开发者

forcing a dom rerender in ie8

开发者 https://www.devze.com 2023-01-16 07:10 出处:网络
I\'ve tried all of the classic ie tricks to get my webpage to rerender the changes that have been made in the dom but nothing has worked. I\'ve already tried

I've tried all of the classic ie tricks to get my webpage to rerender the changes that have been made in the dom but nothing has worked. I've already tried

element.className = element.className;

as well as accessing some part of the dom I changed but that doesn't work either.

Here's my code. Onload the body calls queryDB and in the html there's a paragraph with the id "plants". So far this code only works correctly on firefox 3 and chrome.

var timeout = 5000; //get new plants every 5 seconds

function queryDB() {
    responseDoc = getXMLFrom("ajax/getallplants.php");
    paragraph = document.getElementById("plants");
    table = document.createElement("table");
    table.setAttribute("class", "viewTable");

    //clean up the last query
    cleanUpLastResult(paragraph);

    //loop through the responseDoc and dynamically add plants
    if(plantsFound(responseDoc)) {
        for(i = 0; i < responseDoc.documentElement.childNodes.length; i++) {
            currentChild = responseDoc.documentElement.childNodes[i];

            row = document.createElement("tr");
            //old way of printing where the whole sci name and common name was just text
            /*paragraph.appendChild(document.createTextNode(responseDoc.documentElement.childNodes[i].firstChild.nodeValue));
            paragraph.appendChild(document.createElement("br"));*/

            //newer way of printing where the common name is bolded
            /*paragraph.appendChild(document.createTextNode(currentChild.firstChild.nodeValue + " "));
            commonName = document.createElement("b");
            commonName.appendChild(document.createTextNode(currentChild.getAttribute("commonname")));
            paragraph.appendChild(commonName);
            paragraph.appendChild(document.createElement("br"));*/

            //newest way of printing that prints to a table
            col1 = document.createElement("td");
            col1.setAttribute("class", "viewTable");
            col1.appendChild(document.createTextNode(currentChild.firstChild.nodeValue));

            col2 = document.createElement("td");
            col2.setAttribute("class", "viewTable");
            col2Bold = document.createElement("b");
            col2Bold.appendChild(document.createTextNode(currentChild.getAttribute("commonname")));
            col2.appendChild(col2Bold);

            row.appendChild(col1);
            row.appendChild(col2);

            table.appendChild(row);
        }

        paragraph.appendChild(table);

        paragraph.className = paragraph.className;
        paragraph.firstChild.className = paragraph.firstChild.className;
    }
    else {
        paragraph.appendChild(document.createTextNode("no plants currently entered"));
    }

    //re-add the callback
    setTimeout(queryDB, timeout);
}

function plantsFound(responseDoc) {
    if(responseDoc.documentElement == null) {
        return false;
    }
    else {
        if(responseDoc.documentElement.firstChild.nodeType == 3) {
            //text node so no children

            return false;
        }
        else {
            return true;
        }
    }
}

function cleanUpLastResult(paragraph) {
    //old way of cleaning up where everything was only a childnode of the paragraph
    /*while(paragraph.childNodes.length >= 1) {
        paragraph.removeChild(paragraph.firstChild);
    }*/

    /* The three possible cases:
     * 1 first execution time so paragraph has no child
     * 2 nth execution time but nothing was found in db so only a textnode
     * 3 nth execution and there's a whole table to clean up
     */
    if(paragraph.firstChild == null) {
        //nothing there so nothing to delete
    }
    else if(paragraph.firstChild.nodeValue != null) {
        //no table printed, just remove that text node

        paragraph.removeChild(paragraph.firstChild);
    }
    else {
        //delete the whole table

        table = paragraph.firstChild;

        //remove each row
        while(table.childNodes.length >= 1) {
            //remove the two columns in it and their stuff

            row = table.firstChild;

            col1 = row.firstChild;
            col2 = row.lastChild;

            //remove column1 and it's text node
            col1.removeChild(col1.firstChild);
            row.removeChild(row.firstChild);

            //remove column2, it's bold node and its text node
            col2.firstChild.removeChild(col2.firstChild.firstChild);
            col2.removeChild(col2.firstChild);
            row.removeChild(row.firstChild);

            table.removeChild(row);
        }

        //finally delete the table
        paragraph.removeChild(paragraph.firstChild);
    }
}

function getXMLFrom(url) {
    if(window.XMLHttpRequest) {
        //regular browser
        xmlhttp = new XMLHttpRequest();
    }
    else {
        //ie6
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.open("GET", url, false);
    xmlhttp.send();
    responseDoc = xmlhttp.responseDoc;

    if(responseDoc == null) {
        if(window.XMLHttpRequest && (typeof DOMParser != "undefined")) {
            //firefox

            var parser = new DOMParser();
        开发者_StackOverflow中文版    responseDoc = parser.parseFromString(xmlhttp.responseText, "text/xml");
        }
        else {
            //ie6 or ie7

            var doc = new ActiveXObject("Microsoft.XMLDOM");
            doc.async = true;
            doc.loadXML(xmlhttp.responseText);
            responseDoc = doc;
        }

        if(responseDoc == null) {
            alert("error in parser xml from: " + url);
        }

        return responseDoc;
    }
}

I've also tested the responseDoc and I know I am getting a correct response from getallplants.php which generates an xml representations of various plants. Any ideas on how to fix this? Also, for various reasons I can't use JQuery for this.

edit I have a quasi-good solution that I found on another SO thread. If I add document.write(document.all[0].innerHTML); to queryDB after I set the table I made to a child of the paragraph. The only problem is that if I do this the page won't refresh every 5 minutes. So if the database it changed this page has to be refreshed which kind of defeats the purpose of having javascript asynchroniously get info from the database.


I had a similar issue, a few weeks ago, and adding a class to the body element made the trick. The added class can be removed just after.

0

精彩评论

暂无评论...
验证码 换一张
取 消