为什么我的 JavaScript 代码在我动态添加的 script 标签中不起作用,但当它作为全局变量时却可以工作?

问题描述

为什么我的 JavaScript 代码在我动态添加的 script 标签中不起作用,但作为全局变量时却可以工作?

现在,请让我告诉您我的问题是什么。我的代码功能是为具有许多项的网页上的每个项添加一个按钮(在我的示例中,我将项数更改为 2)。单击我添加的按钮后,我可以查看一些我想查看的项目的信息,例如时间等,但我无法理解的是我的“getINFO”功能。每当它作为全局变量使用或需要作为外部js函数时,它都能正常工作;但是如果我想把它放在我动态添加的脚本标签中,控制台会报错。 经过一行一行的调试,我终于找到了我的程序出错的原因。原因是 XMLHttpRequest obj 的 open() 和 send() 函数。只要我删除这两个函数,我的代码就不会报告任何错误,但是,这也不是我想要的。那么,我该怎么做才能让我的代码在脚本标签中正常工作呢?如果我的要求不被允许,也请告诉我。谢谢!

这是我的代码

   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(根据 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);
    }
}

解决方法

如果你想从脚本注册一个函数,你应该设置脚本的 textContent。

var script = document.createElement('script');
script.textContent = "function fun() { console.log('hello',this.id); }";
document.body.appendChild(script);

for (let i = 0; i < 3; i++) {
  var btn = document.createElement("button");
  btn.textContent = "Hello " + i;
  btn.id = "b" + i;
  btn.addEventListener("click",fun);
  document.body.appendChild(btn);

}

,

我是提问者。最后惊讶地发现,当我把“xmlhttp.Open('Get',URL);xmlhttp.send();”这两行放在“xmlhttp.onload”语句前面时,就成功实现了我的目的.而已。但我不知道为什么我必须这样做才能成功解决我的问题。 我的解决方法如下:

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);

我的解决方案 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);
    }
}