简体   繁体   中英

Using Javascript to automatically generate multiple html elements of the same type based on a 2 dimentional array of attributes causes browser to hang

I've created 2 functions for creating DOM elements. The first builds a single element node, inserts attributes based on an array of attribute/value pairs, inserts a text node and puts the element into a parent. This function works fine except when the second function calls it.

The second calls the first function to generate multiple elements of the same type and parent but with different text and attributes (for generating things such as li, option, or p elements). This function's parameters are the type of element to create repeatedly, the parent element to be added to, an array of arrays each containing attribute value pairs, and an array of strings for use in the text node (array of arrays and array of strings must be the same length). The number of elements created is based on the number of attribute arrays.

The problem is that when the 2nd function calls the 1st it seems to hang the browser.

Help and or advice would be much appreciated.

The code I've been running:

function buildElement(type, txt, attr, parent){

    element = document.createElement(type);

    if(typeof attr != 'undefined' && attr){
        for(i=0; i<attr.length; i=i+2){
            element.setAttribute(attr[i], attr[i+1]);
        }
    }
    if(typeof txt != 'undefined' && txt){
        element.appendChild(document.createTextNode(txt));
    }
    if(typeof parent != 'undefined' && parent){
        parent.appendChild(element);
    }
    return element;
}

function multiElements(type, parent, attrs, txts){
    for(i=0; i<attrs.length; i++){
        buildElement(type,txts[i],attrs[i],parent);
    }
}

var x=1;
var local = buildElement('select','','name','local'+x,'onchange',
                                         'selectPhUpdate(this.value)'],newCard);
multiElements('option',
                local,
                [
                    ['value','auck'],
                    ['value','chch'],
                    ['value','dun'],
                    ['value','ham'],
                    ['value','mor'],
                    ['value','nap'],
                    ['value','nply'],
                    ['value','wel']
                ],
                ['Auckland','Christchurch','Dunedin','Hamilton','Morrinsville',
                    'Napier','New Plymouth','Wellington']
);

First of all, there is a [ missing in your code,

var local = buildElement('select','','name','local'+x,'onchange',
                                         'selectPhUpdate(this.value)'],newCard);

should be

var local = buildElement('select','',['name','local'+x,'onchange',
                                         'selectPhUpdate(this.value)'],newCard);

As for the problem itself: You are using global variables for everything, even for your loop counter – and you used i for the loop counter both times.

You have two entries each on the second level of your attrs array that you pass from multiElements to buildElement , so i always has a value of 2 when the loop over the current 2nd level array in buildElement is finished – and that means, the loop in multiElements never stops, because 2 is always lesser than attrs.length (which is 8 ) … and so the third option for “Dunedin” gets created over and over and over … and over … again.

As soon as you use for(var i=0; … for both of your loops, thereby making each i a local variable within the scope of the respective function, it works as expected.

( element in buildElement should be made local, too.)

See it working with those small fixes in this fiddle: http://jsfiddle.net/c7Pq3/1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM