Search code examples
javascriptfirefoxbrowserxmlhttprequest

Why doen't my JavaScript code work in the script tag added by me dynamically but it can work when it is as a global variable?


Why doen't my JavaScript code work in the script tag added by me dynamically but it can work when it is as a global variable?

Now,pls let me tell you what my problem is.The function of my code is to add a button for each item on a web page with many items (in my example, I changed the number of items to 2). After clicking the button I added, I can view some information about the items I want to see, such as time, etc. But what I can't understand is my "getINFO" function. Whenever it is used as a global variable or it is required as an outer js function, it works properly; But if I want to put it in my dynamically added script tag, the console will report an error. After line by line debugging, I finally found out the cause of my program's error. The reason is that the function open() and send() of XMLHttpRequest obj. As long as I remove the 2 functions, my code will not report any errors,however,it is not what I want,either. So, what should I do to make my code work normally in the script tag? If my demand is not allowed, please let me know,too. Thank you!

Here is my code:

   getINFO = function(e) {
        var dad = e.parentNode;
        var index = e.dataset.idx;
        var URL = dad.childNodes[1].childNodes[0].href + '/log';
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onload = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                var temp = document.createElement('div');
                temp.innerHTML = xmlhttp.responseText;
                var user = temp.querySelector('#zh-question-log-list-wrap');
                var user0 = user.children[user.children.length - 1].children[0].outerHTML;
                var time = user.querySelector('time').innerHTML;
                var id = 'div' + index;
                var dive = document.createElement('div');
                dive.setAttribute('id', id);
                dive.innerHTML = time;
                dive.innerHTML += user0;
                e.outerHTML = dive.outerHTML
            }
        }
        xmlhttp.open('GET', URL, true);//Where things go wrong
        xmlhttp.send()//Where things go wrong
    }    
        window.onload=function(){    
            var script = document.createElement("script");
            script.appendChild(document.createTextNode("placeholder"));//The placeholder is where I plan to add my getINFO function.
            script.setAttribute("type","text/javascript");
            document.head.appendChild(script);
    
            var AJAXs = document.getElementsByClassName('HotItem'),btn;
            var len=2//AJAXs.length;//The number of items I changed is 2 in my example
            
            //add btn
            for (let i = len-1; i >=0; i--) {
                btn = document.createElement('input');
                btn.setAttribute("data-idx",i);
                btn.setAttribute("type","button");
                btn.setAttribute("value",(i+1) +"_getInfo");
                btn.setAttribute("onclick","getINFO(this)");
                AJAXs[i].appendChild(btn);    
            }

v2(according to the method offered by epascarello)

function getINFO() {
    var that =this;
    var dad = that.parentNode;
    var index = that.dataset.idx;
    var URL = dad.children[1].children[0].href + '/log';
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onload = function() {
        if (xmlhttp.readyState == 4&& xmlhttp.status == 200) {
            var temp = document.createElement('div');
            temp.innerHTML = xmlhttp.responseText;
            var user = temp.querySelector('#zh-question-log-list-wrap');
            var user0 = user.children[user.children.length - 1].children[0].outerHTML;
            var time = user.querySelector('time').innerHTML;
            var id = 'div' + index;
            var dive = document.createElement('div');
            dive.setAttribute('id', id);
            dive.innerHTML = time;
            dive.innerHTML += user0;
            that.outerHTML = dive.outerHTML
        }
    }
    xmlhttp.open('GET', URL);
    xmlhttp.send()
}

window.onload=function(){

    //var script = document.createElement("script");
    //script.textContent="function getINFO(){var that=this;var dad=that.parentNode;var index=that.dataset.idx;var URL=dad.children[1].children[0].href+'/log';var xmlhttp=new XMLHttpRequest();xmlhttp.onload=function(){if(xmlhttp.readyState==4 && xmlhttp.status==200){var temp=document.createElement('div');temp.innerHTML=xmlhttp.responseText;var user=temp.querySelector('#zh-question-log-list-wrap');var user0=user.children[user.children.length-1].children[0].outerHTML;var time=user.querySelector('time').innerHTML;var id='div'+index;var dive=document.createElement('div');dive.setAttribute('id',id);dive.innerHTML=time;dive.innerHTML+=user0;that.outerHTML=dive.outerHTML}}xmlhttp.open('GET',URL);xmlhttp.send()}";
    //script.type = "text/javascript";
    //document.head.appendChild(script);

    var AJAXs = document.getElementsByClassName('HotItem'),btn;
    var len=AJAXs.length;
    //add btns
    for (let i = len-1; i >=0; i--) {
        btn = document.createElement('input');
        btn.setAttribute("data-idx",i);
        btn.setAttribute("type","button");
        btn.setAttribute("value",(i+1) +"_getINFO");
        btn.addEventListener("click", getINFO);
        //btn.setAttribute("onclick","getINFO(this)");
        AJAXs[i].appendChild(btn);
    }
}

Solution

  • I'm the questioner. Finally, I was surprised to find that when I put "xmlhttp. Open ('Get ', URL);xmlhttp.send();"these two lines in front of the "xmlhttp. Onload" statement, I succeeded in achieving my goal. That's it. But I don't know why I have to do this to solve my problem successfully. My solution is as follows:

    var script = document.createElement("script");
    script.textContent="function getINFO(){var that=this;var dad=that.parentNode;var index=that.dataset.idx;var URL=dad.children[1].children[0].href+'/log';var xmlhttp=new XMLHttpRequest();xmlhttp.open('GET',URL);xmlhttp.send();xmlhttp.onload=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){var temp=document.createElement('div');temp.innerHTML=xmlhttp.responseText;var user=temp.querySelector('#zh-question-log-list-wrap');var user0=user.children[user.children.length-1].children[0].outerHTML;var time=user.querySelector('time').innerHTML;var id='div'+index;var dive=document.createElement('div');dive.setAttribute('id',id);dive.innerHTML=time;dive.innerHTML+=user0;that.outerHTML=dive.outerHTML}}}";
    script.type = "text/javascript";
    document.head.appendChild(script);
    

    My solution v2:

    window.onload=function(){
    
        var script = document.createElement("script");
        script.textContent="getINFO=function(e){var dad=e.parentNode;var index=e.dataset.idx;var URL=dad.childNodes[1].childNodes[0].href+'/log';var xmlhttp=new XMLHttpRequest();xmlhttp.open('GET',URL,true);xmlhttp.send();xmlhttp.onload=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){var temp=document.createElement('div');temp.innerHTML=xmlhttp.responseText;var user=temp.querySelector('#zh-question-log-list-wrap');var user0=user.children[user.children.length-1].children[0].outerHTML;var time=user.querySelector('time').innerHTML;var id='div'+index;var dive=document.createElement('div');dive.setAttribute('id',id);dive.innerHTML=time;dive.innerHTML+=user0;e.outerHTML=dive.outerHTML}}}";
        document.head.appendChild(script);
    
        var AJAXs = document.getElementsByClassName('HotItem'),btn;
        var len=AJAXs.length;
        //add btns
        for (let i = len-1; i >=0; i--) {
            btn = document.createElement('input');
            btn.setAttribute("data-idx",i);
            btn.setAttribute("type","button");
            btn.setAttribute("value",(i+1) +"_獲取資訊");
            //btn.addEventListener("click", getINFO);
            btn.setAttribute("onclick","getINFO(this)");
            AJAXs[i].appendChild(btn);
        }
    }