PDA

View Full Version : javascript size limit



james438
12-06-2009, 02:43 AM
I have this simple script that is rather large. It uses an array to store about 200 questions and answers. Using a button a person can cycle through the questions.

If I add more than 140 questions the script just won't run. At first I thought there was an error in my code and then that there was an array limit built in to javascript, but it appears that there is a limit to the size of the javascript itself and the size limit is different depending on the browser.

Any idea on how to work around this?


<div style='font-size:18px;text-align:center;'><button onclick="newi();">next</button></div>
<div style="text-align:center;font-size:18px;" id="outputtext"><br><br></div>

<script type="text/javascript">var question = new Array('Q. 1. <br />
A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.');
var Number = -1;
function newi(outputtext){if(++Number > question.length - 1) Number = 0;
if (outputtext==0)document.write(question[Number])
else if (document.getElementById)document.getElementById("outputtext").innerHTML=question[Number];}
newi();
</script>

EDIT: Yeah, I need to clean up my code as it looks like it only works in Opera at the moment. I think the question is still valid, so I am leaving it up. I am gonna try cleaning it up though.

jscheuer1
12-06-2009, 03:23 AM
The code from your post doesn't even work in Opera. You have broken the code line for the array in a spot that that produces an unterminated string literal:


var question = new Array('Q. 1. <br />
A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

In a construct like that, you could close the string at the end of the line and use a plus sign, then open the string again on the next line:


var question = new Array('Q. 1. <br />' +
'A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

But it is generally easier to read, and works just as well if you break the line after a comma that denotes the end of an entry:


var question = new Array('Q. 1. <br /> A. ',
'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

In any case there is no limit on the size of an array or of a script, at least not in the order of magnitude (200 entries) that you are talking about. Consider the massive scripts for the various code libraries.

So it probably is some sort of syntax error. To find it I would need the code or a link to it. It might be something else, but I would need the code or link to discover that as well.

djr33
12-06-2009, 03:29 AM
There is no "rule" for a size limit, but if you have a huge amount of code it may overwhelm and crash the browser when it takes too much memory (RAM) to run on the user's computer.
But as John said, 200 entries should not do this (though on a particularly slow computer it might make the performance lag a bit).

james438
12-06-2009, 03:35 AM
Here is the link to the script:http://www.animeviews.com/article.php?ID=69&category=misc

The script is large, but 99% of it is the array. It has not been cleaned up yet, but is rather simple. I didn't want to post it due to the length, but thanks for taking a look.

jscheuer1
12-06-2009, 08:03 AM
You are correct about the code being sloppy. The Walter Zorn script (wz_tooltip.js) is inserted in the wrong place. There is no body tag. This script and style section:


<script type="text/javascript" src="virtualpaginate.js">

/***********************************************
* Virtual Pagination script- Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/

</script>

<style type="text/css">

/*Sample CSS used for the Virtual Pagination Demos. Modify/ remove as desired*/

.paginationstyle{ /*Style for . . .

are inserted inside of a preceding style tag, so that the script at least is not even parsed.

But none of that, and there is probably more of that sort of thing, directly impacts your questions script. Except for the question script's own sloppiness. Wow, that's one long uninterrupted line. If you want to code like that, you should follow a stricter syntax. The javascript parser will make logical assumptions about code that isn't properly written. But this varies by browser. There is only one critical lapse in syntax that browsers (other than Opera) aren't correcting for, here:


. . . if (outputtext==0)document.write(question[Number])else if (document.getElementById)document.getE . . .

Since there is no line break or semi-colon and the no {} braces around:


document.write(question[Number])

the script parser doesn't know that the else if statement isn't part of what should be done if the outputtext==0 condition is true. Of course it cannot be, it's an else if branch, but most script parsers aren't able to make that distinction. Apparently Opera's is. You can fix it by doing any one or more of those three things. The one that would most fit the coding style would be inserting a semi-colon:


. . . if (outputtext==0)document.write(question[Number]);else if (document.getElementById)document.getE . . .

james438
12-06-2009, 09:23 AM
Sorry about all of the errors. I'll be sure to clean that up. I already have the javascript fixed up and I'll try to reformat it better so that it is at least more readable. I inserted the semicolon and braces. I'll try to insert a body tag and rearrange some of my code soon.

Thanks for looking at that mess and pointing out some elementary errors in my code.

james438
12-06-2009, 09:37 PM
I'm still fixing things up. I just took care of the linebreaks that was mentioned in #2. What is an "unterminated string literal"? Since newlines and most whitespace is hardly ever parsed I figured it was mostly just used for coders to make their code look neat. I think that is what you were referring to with a linebreak right before a newline.

I discovered that my MySQL database was using text for the data type, which is fine, because I had not as yet reached the limit for data storage for data type text till this script. I updated it to mediumtext and that took care of another problem area. I believe the size for text is 65535 and for mediumtext it is 16777215, so that should help out with my data storage issue that I just discovered.

EDIT: Actually, when I tried using newlines right after a linebreak within a string javascript became unhappy with me, so I won't be doing it that way.

jscheuer1
12-06-2009, 10:51 PM
I can't speak for whatever you've actually done until I see it. I can tell why the first of these is unterminated:


var question = new Array('Q. 1. <br />
A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

Look at the line break. The javascript parser can assume a semi-colon there, so you would in effect have:


var question = new Array('Q. 1. <br />;
A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

That means that the first line must stand on its own. Looking at just it:


var question = new Array('Q. 1. <br />;

we see an opening delimiter for the string, but no closing one. The type of string is a literal (as opposed to a string Object created with the new String() method). It's not terminated. It's an unterminated string literal.

Now, with this one:


var question = new Array('Q. 1. <br />' +
'A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

the string on the first line is terminated. Next comes the plus operator, which tells the parser we are going to add something to the string. This also allows the parser to know that this line isn't really finished yet. What we are going to add to it can be on this line or on the next line. On the next line we have the completion of the string (its second part - another string literal in this case) and then a comma denoting that another array entry is to follow, another string literal, etc.

The preferred method in a case like this though is to split the line on the comma.


var question = new Array('Q. 1. <br /> A. ',
'Q. 2. <br /> A.', 'Q. 3. <br /> A.');

Here our string is terminated on the first line. Then comes a comma that tells the parser that we will be continuing the array. Once again, the line isn't finished. Like the plus operator for a terminated string, the comma (when used like this in an unterminated array) tells the parser that the line will continue on this line or on the next line with the next array entry. On the next line we have another array entry (a string literal), and so on.

james438
12-07-2009, 12:20 AM
ok, so the semicolon is the terminus, just like in PHP and the closing quote is the closing delimiter. Other delimiters include the double quote, the curly bracket, and parentheses. The last two I am less sure on. There are a few others from what I have read while searching online.

The string literal is the string written out. The string object is where the string literal is assigned to a variable. Let me know if I am close.

I am currently using
var question = new Array('Q. 1. <br />' + 'A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.'); but I think that I will change to the preferred method as I like that method better as well.

Currently the script works and in all the major browsers, but when I tried adapting your code for the image script we were working on earlier, which had prev and back buttons I was less than successful.

Your original code looked something like:



<button onclick="return newi(-1);">prev</button>
<button onclick="return newi();">original image</button>
<button onclick="return newi(1);">next</button>
<img id="img" src="" style="width:250px;" alt="">
<script type="text/javascript">
function newi(n){
newi.Num += n || -newi.Num;
newi.Num = newi.Num < 0? newi.count - 1 : newi.Num % newi.count;
newi.img.src = '/images/screenshots/' + newi.ar[newi.Num];
newi.output.value = newi.ar[newi.Num];
return false;
}
newi.Num = 0;
newi.ar = new Array(<?php print $Statss;?>);
newi.count = newi.ar.length;
newi.img = document.getElementById('img');
newi.output = document.forms.editform.elements.outputtext;
newi();
</script>

My adaptation of your code looked something like:


<button onclick="return newi(-1);">prev</button>
<button onclick="return newi();">original image</button>
<button onclick="return newi(1);">next</button>
<div id="outputtext" style="width:250px;"></div>
<script type="text/javascript">
function newi(n){
newi.Num += n || -newi.Num;
newi.Num = newi.Num < 0? newi.count - 1 : newi.Num % newi.count;
newi.output.value = newi.ar[newi.Num];
return false;
}
newi.Num = 0;
newi.ar = new Array('Q. 1. <br /> A. ','Q. 2. <br /> A.', 'Q. 3. <br /> A.');
newi.count = newi.ar.length;
newi.outputtext = document.getElementById('outputtext');
newi();
</script>It feels more like I am grasping in the dark. I think the highlighted text above is where I am having the most trouble.

jscheuer1
12-07-2009, 02:07 AM
I will get back to you on the last part of your question (about your adaptation of the code I wrote for images to your questions thinger), or remind me if I don't. The main thing with it though is that div's have no value property. You may access their innerHTML property in the same way as you would a text area's or input's value property. But that's not the best way.

Anyways, for now let me dispose of the other questions, and one issue about your array that you didn't even ask about first. Your array is an array Object created using the new Array() constructor. In almost all cases you are better off with a literal array. Here's how your array from your last post would look as a literal:


var question = ['Q. 1. <br />' + 'A. ', 'Q. 2. <br /> A.', 'Q. 3. <br /> A.'];

Now about terminus. Like PHP, there are lines that require a terminus semi-colon and ones that cannot have one. However, in javascript, unlike in PHP (unless certain PHP settings are enabled) not every line that requires a terminus needs a semi-colon. The javascript parser will often fill these in for you. But it is a good idea to provide one anyway for those lines that require them. It makes the code easier to read, faster to parse, and more conducive to compression. As for the delimiters you mention, that's not the entire list. And it varies as to what delimiters are permitted, depending upon what sort of data they are delimiting.

As to the string literal versus string object. This is a string literal:


'Hi Bob'

Assign it to a variable:


var str = 'Hi Bob';

It's still a string literal, even if you later go:


alert(str);

Even at that point it is still a string literal. It just happens to be contained in a variable.

The only way to get a string Object is to use the new String() constructor:


var str = new String('Hi Bob');

All Objects inherit the global Object constructor's methods. So you are generally better off using the literal for strings and arrays unless you need these methods in situations where javascript won't automatically convert the type for you, which are few. Attaching them to an array or string that doesn't require them just makes it longer to process your code and can lead to unexpected results when you try to access or change your array or string.

james438
12-07-2009, 04:35 AM
Thanks for that explanation. I probably would not have changed the array Object to a local Object with the correct syntax without the example you posted. Considering the size of the array I don't want to needlessly add to processing time or increase client computations, so I updated the script.

jscheuer1
12-07-2009, 02:33 PM
OK, here's the newi function transformed to a newq function:


<div>
<div>Questions:</div>
<button onclick="return newq(-1);">prev</button>
<button onclick="return newq();">first</button>
<button onclick="return newq(1);">next</button>
<div id="outputtext" style="width:250px;margin-top:1em;">&nbsp;<br>&nbsp;</div>
</div>

<script type="text/javascript">
function newq(n){
newq.Num += n || -newq.Num;
newq.Num = newq.Num < 0? newq.count - 1 : newq.Num % newq.count;
var r = newq.ar[newq.Num].split('<br />');
newq.output.firstChild.nodeValue = r[0];
newq.output.lastChild.nodeValue = r[1];
return false;
}

newq.Num = 0;
newq.ar = ['Q. 1. <br /> A. ','Q. 2. <br /> A.', 'Q. 3. <br /> A.'];
newq.count = newq.ar.length;
newq.output = document.getElementById('outputtext');
newq();
</script>

james438
12-07-2009, 05:38 PM
Thanks for the help and the script. I am currently reading up on parent and child nodes and figuring out how the script knows to place the content on either side of the <br> in the <div>.