问题描述
为什么我的 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);
}
}