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

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?

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

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

这是我的代码:

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