Javascript y cadena MUY LARGA

i am having problems with the below code:

function showTableData()
{
    var tableArray;
    var x = 0;
    var theHTML;

    for (i = 0; i < 7032; i++)
    {
        if (x = 0)
        {
            theHTML = '<tr>' + 
                '<th scope="row" class="spec">' + partNum[i] + '</th>' + 
                '<td>' + Msrp[i] + '</td>' + 
                '<td>' + blah[i] + '</td>' + 
                '<td>' + blahs[i] + '</td>' + 
            '</tr>' + theHTML;
            x++;
        }else{
            theHTML = '<tr>' + 
                '<th scope="row" class="specalt">' + partNum[i] + '</th>' + 
                '<td class="alt">' + Msrp[i] + '</td>' + 
                '<td class="alt">' + blah[i] + '</td>' + 
                '<td class="alt">' + blahs[i] + '</td>' + 
            '</tr>' + theHTML;
            x--;
        }
    }
    theHTML = '<table id="mytable" cellspacing="0">' + 
    '<tr>' + 
        '<th scope="col" abbr="Configurations" class="nobg">Part Number</th>' + 
        '<th scope="col" abbr="Dual 1.8">Msrp Price</th>' + 
        '<th scope="col" abbr="Dual 2">blahs Price</th>' + 
    '<th scope="col" abbr="Dual 2.5">Low Price</th>' + 
    '</tr>' + theHTML + '</table>';

    $('#example').append(theHTML);
}
 </script>

 <div id="example">
 </div>

The problem being that the $('#example').append(theHTML); never executes (or shows on the page). I think its because the string is soooooo long! It has over 7,000 items in the array so im not sure if thats the reason or if its something else?

¡Cualquier ayuda sería genial! ¡Gracias!

David

preguntado el 09 de enero de 11 a las 03:01

if (x=0) (line 9) should be if (x==0) don't know if that is just a typo though -

Are you sure that the function has been called properly? -

Some advice. Build up an array using push instead of string concatenation. Then use array.join('') before you append the html. Better performance. -

Thanks, Hemlock. Fixed that error. -

5 Respuestas

Aparte de la if (x = 0) that should really be if (i % 2 === 0), you really should improve performance here by using Array.join() method instead of concatenating strings. This will have a similar effect to a StringBuilder in C# or Java.

Por ejemplo:

function showTableData()
{
    var tableArray;
    var theHTML = [];
    theHTML.push('<table id="mytable" cellspacing="0">',
    '<tr>', 
        '<th scope="col" abbr="Configurations" class="nobg">Part Number</th>', 
        '<th scope="col" abbr="Dual 1.8">Msrp Price</th>',
        '<th scope="col" abbr="Dual 2">blahs Price</th>', 
    '<th scope="col" abbr="Dual 2.5">Low Price</th>', 
    '</tr>');

    for (var i = 0; i < 7032; i++)
    {
        if (i % 2 == 0)
        {
             theHTML.push('<tr>', 
                 '<th scope="row" class="spec">', partNum[i], '</th>',
                 '<td>', Msrp[i], '</td>', 
                 '<td>', blah[i], '</td>', 
                 '<td>', blahs[i], '</td>', 
             '</tr>');
        } else {
             theHTML.push('<tr>',
                 '<th scope="row" class="specalt">', partNum[i], '</th>', 
                 '<td class="alt">', Msrp[i], '</td>', 
                 '<td class="alt">', blah[i], '</td>', 
                 '<td class="alt">', blahs[i], '</td>',
             '</tr>');
        }
    }
    theHTML.push('</table>');

    $('#example').append(theHTML.join(''));
}
 </script>

 <div id="example">
 </div>

The reason why appending string 'my' + ' appended' + ' string' is slower than joining strings ['my', ' joined', ' string'].join('') es porque JavaScript strings are immutable so in the former example there is a third string created every time 2 strings are concatenated, which is a very expensive operation compared to adding new entries into an array.

Ver también un Javascript StringBuilder project built using the same priciples of Array.push() and Array.join().

The performance improvement on this project for 10,000 concatenations in IE was down from over 1 minute to 0.23 seconds.

ACTUALIZACIÓN: Additional calls to Array.join() added to replace string concatenation within the for-loop, this is to improve client rendering speeds further. + Added better link to StringBuilder.

FURTHER UPDATE: Added suggestions by Hemlock:

  1. Removed use of globally scoped variable by defining var i = 0 in for-loop
  2. Pushed several strings at a time using multiple parameters of Array.push().

Respondido 26 Oct 17, 02:10

Much can still be done with this code. The worst problem is that i is never declared s/b for var i=0;. There is no need for the extra arrays, only one join is needed since push can accept multiple arguments. I don't understand why all that code is repeated to add the rows, it looks like that is just there to add alt styling. Can be done with one class on the tr and some decent css. Here is an example: jsbin.com/itego4/3/edit - Cicuta

@Hemlock, I made changes to push statement and locally scoped var but left if-then-else and css untouched, while I agree with you on that one I think its going beyond the scope of the question and changing css may have other side-effects. - Steven de Salas

very nice @steven - i had no idea i could attach long html strings like that ;) - SEO Sagive

@StevendeSalas My tests on jsperf.com/string-concat-without-sringbuilder/3 show that a StringBuilder does more harm than good (method overhead), and that string concatenation is faster than the Array.join trick... care to comment on that? - Juan Mendes

Hi Juan, while I cant vouch for the stats of your test I do know that since Google launched its Chrome browser with various JS engine compile-time performance optimizations in its like this one all the other browsers have followed suit. Perhaps this answer is only relevant to old versions of IE now. - Steven de Salas

one error i saw was that if (x = 0) debiera ser if (x == 0), other than that it seems to work for me: http://jsfiddle.net/9vvJ6/

Respondido el 09 de enero de 11 a las 06:01

Esta línea:

if (x = 0)

no debería ser

if (x == 0)

Might be the error here causing the rest of the script not being able to be executed.

Respondido el 09 de enero de 11 a las 06:01

if (x = 0) is correct, being syntax. It won't be cause an error. if assining 0 to x is successful, true... - miqbal

If you're already using jQuery here, you might want to consider jQuery templates here, it would most likely clean up your code quite a bit and make your life easier. There can be performance tradeoffs (but I think string interpolation is faster than string concatenation in JavaScript, so this could even be faster?), but what you may or may not lose in performance, it's a much more elegant solution. You could keep your entire template in one place (maybe an external file, or parts of it hidden in the DOM of your document, I haven't used it enough to tell you what the best practice is), and then use jQuery templates to do the string replacement. There are multiple jQuery-based template frameworks, but the one I linked to is becoming an official part of jQuery.

Respondido el 09 de enero de 11 a las 07:01

The problem is with .append jquery function. You can not use .html or .append function for long string. Instead you need to use .innerHTML

Prueba esta

document.getElementById('example').innerHTML=theHTML.join('');

respondido 14 mar '13, 14:03

This is not strictly true. As stated in the jquery documentation: "This [html] method uses the browser's innerHTML property" (api.jquery.com/html/#html2). - beterthanlife

Its worth noting that html() can be almost twice as slow as using innerHTML directly (stackoverflow.com/questions/1063303/…). - beterthanlife

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.