Skip to content
Advertisement

Javascript Hanging UI on IE6/7

Could anyone suggest performance improvements for the function I’ve written (below, javascript with bits of jquery)? Or point out any glaring, basic flaws? Essentially I have a javascript Google map and a set of list based results too, and the function is fired by a checkbox click, which looks at the selection of checkboxes (each identifying a ‘filter’) and whittles the array data down accordingly, altering the DOM and updating the Google map markers according to that. There’s a ‘fake’ loader image in there too at the mo that’s just on a delay so that it animates before the UI hangs!

function updateFilters(currentCheck) {
    if (currentCheck == undefined || (currentCheck != undefined && currentCheck.disabled == false)) {
        var delay = 0;
        if(document.getElementById('loader').style.display == 'none') {
            $('#loader').css('display', 'block');
            delay = 750;
        }
        $('#loader').delay(delay).hide(0, function(){        
            if (markers.length > 0) {
                clearMarkers();
            }

            var filters = document.aspnetForm.filters;
            var markerDataArray = [];
            var filterCount = 0;
            var currentfilters = '';
            var infoWindow = new google.maps.InfoWindow({});

            for (i = 0; i < filters.length; i++) {
                var currentFilter = filters[i];
                if (currentFilter.checked == true) {
                    var filtername;
                    if (currentFilter.parentNode.getElementsByTagName('a')[0].textContent != undefined) {
                        filtername = currentFilter.parentNode.getElementsByTagName('a')[0].textContent;
                    } else {
                        filtername = currentFilter.parentNode.getElementsByTagName('a')[0].innerText;
                    }
                    currentfilters += '<li>' + $.trim(filtername) +
                        $.trim(document.getElementById('remhide').innerHTML).replace('#"','#" onclick="toggleCheck('' + currentFilter.id + '');return false;"');
                
                    var nextFilterArray = [];
                    filterCount++;
                    for (k = 0; k < filterinfo.length; k++) {
                        var filtertype = filterinfo[k][0];
                        if (filterinfo[k][0] == currentFilter.id) {
                            var sitearray = filterinfo[k][1];
                            for (m = 0; m < sitearray.length; m++) {
                                var thissite = sitearray[m].split(',');
                                if (filterCount > 1) {
                                    nextFilterArray.push(thissite[2] + '|' + thissite[1]
                                + '|' + thissite[0]);
                                } else {
                                    markerDataArray.push(thissite[2] + '|' + thissite[1]
                                + '|' + thissite[0]);
                                }
                            }
                        }
                    }
                    if (filterCount > 1) {
                        var itemsToRemove = [];
                        for (j = 0; j < markerDataArray.length; j++) {
                            var exists = false;
                            for (k = 0; k < nextFilterArray.length; k++) {
                                if (markerDataArray[j] == nextFilterArray[k]) {
                                    exists = true;
                                }
                            }
                            if (exists == false) {
                                itemsToRemove.push(j);
                            }
                        }
                        var itemsRemoved = 0;
                        for (j = 0; j < itemsToRemove.length; j++) {
                            markerDataArray.splice(itemsToRemove[j]-itemsRemoved,1);
                            itemsRemoved++;
                        }
                    }
                }
            }
            
            
            if (currentfilters != '') {
                document.getElementById('appliedfilters').innerHTML = currentfilters;
                document.getElementById('currentfilters').style.display = 'block';
            } else {
                document.getElementById('currentfilters').style.display = 'none';  
            }
            
            if (filterCount < 1) {
               for (j = 0; j < filterinfo.length; j++) {
                    var filtertype = filterinfo[j][0];
                    if (filterinfo[j][0] == 'allvalidsites') {
                        var sitearray = filterinfo[j][1];
                        for (m = 0; m < sitearray.length; m++) {
                            var thissite = sitearray[m].split(',');
                            markerDataArray.push(thissite[2] + '|' + thissite[1]
                                + '|' + thissite[0]);
                        }
                    }
                }
            }

            var infoWindow = new google.maps.InfoWindow({});
            
            var resultHTML = '<div id="page1" class="page"><ul>';
            
            var count = 0;
            var page = 1;
            var paging = '<li class="selected"><a href="#" title="' + page + '" onclick="togglePaging('' + page + '');return false;">1</a></li>';
            
            for (i = 0; i < markerDataArray.length; i++) {
                var markerInfArray =  markerDataArray[i].split('|');
                var url = '';
                var name = '';
                var placename = '';
                var region = '';
                var summaryimage = 'images/controls/placeholder.gif';
                var summary = '';
                var flag = 'images/controls/placeholderf.gif';
                
                for (j = 0; j < tsiteinfo.length; j++) {
                    var thissite = tsiteinfo[j].split('|');
                    if (thissite[0] == markerInfArray[2]) {
                        name = thissite[1];
                        placename = thissite[2];
                        region = thissite[3];
                        if (thissite[4] != '') {
                            summaryimage = thissite[4];
                        }
                        summary = thissite[5];
                        if (thissite[6] != '') {
                            flag = thissite[6];
                        }
                    }
                }
                
                for (k = 0; k < sitemapperinfo.length; k++) {
                    var thissite = sitemapperinfo[k].split('|');
                    if (thissite[0] == markerInfArray[2]) {
                        url = thissite[1];
                    }
                }
                
                var markerLatLng = new google.maps.LatLng(markerInfArray[1].toString(), markerInfArray[0].toString());

                var infoWindowContent = '<div class="infowindow">' + markerInfArray[2] + ': ';
                
                var siteurl = approot + '/sites/' + url;

                infoWindowContent += '<a href="' + siteurl + '" title="' + name + '"><strong>' + name + '</strong></a>';
                infoWindowContent += '<br /><br/><em>' + placename + ', ' +  region + '</em></div>';

                marker = new google.maps.Marker({
                    position: markerLatLng,
                    title: $("<div/>").html(name).text(),
                    shadow: shadow, 
                    icon: image
                });
                addInfo(infoWindow, marker, infoWindowContent);
                    
                markers.push(marker);
                
                count++;
                if ((count > 20) && ((count % 20) == 1)) { // 20 per page
                    page++;
                    resultHTML += '</ul></div><div id="page' + page + '" class="page"><ul>';
                    paging += '<li><a href="#" title="' + page + '" onclick="togglePaging('' + page + '');return false;">' + page + '</a></li>';
                }
                
                resultHTML += '<li><div class="namehead"><h2>' + name + ' <span>' + placename + ', ' + region + '</span></h2></div>' +
                    '<div class="codehead"><h2><img alt="' + region + '" src="' + approot +
                    '/' + flag + '" /> ' + markerInfArray[2] + '</h2></div>' +
                    '<div class="resultcontent"><img alt="' + name + '" src="' + approot +
                    '/' + summaryimage +'" />' + '<p>' + summary + '</p>' + document.getElementById('buttonhide').innerHTML.replace('#',siteurl) + '</div></li>';
            }          
            
            $('#filteredmap .paging').each(function(){
                $(this).html(paging);
            });
                              
            document.getElementById('resultslist').innerHTML = resultHTML + '</ul></div>';
            document.getElementById('count').innerHTML = count + ' ';
            document.getElementById('page1').style.display = 'block';
            
            for (t = 0; t < markers.length; t++) {
                markers[t].setMap(filteredMap); 
            } 
        });
    }
}

function clearMarkers() {
    for (i = 0; i < markers.length; i++) {
        markers[i].setMap(null); 
        markers[i] = null; 
    } 
    markers.length = 0;
}

However, I’m suffering from performance issues (UI hanging) specifically in IE6 and 7 when the number of results is high, but not in any other modern browsers, i.e. FF, Chrome, Safari etc. It is much worse when the Google map markers are being created and added (if I remove this portion it is still slugglish, but not to the same degree). Can you suggest where I’m going wrong with this?

Thanks in advance 🙂 Please be gentle if you can, I don’t do much javascript work and I’m pretty new to it and jquery!

Advertisement

Answer

This looks like a lot of work to do at the client no matter what.

Why don’t you do this at the server instead, constructing all the HTML there, and just refresh the relevant sections with the results of an ajax query?

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement