[英]Not all inline JavaScript gets executed via AJAX
我正在通过AJAX加载文档的片段,并且我已经设法很好地加载“外部”脚本,但是我无法执行<script>
标记内的所有内联JavaScript。
这是我正在尝试加载的文档片段/ HTML的示例:
<textarea></textarea>
<script src="tinyMCE.js" class="ajax-script"></script>
<script class="ajax-script">
alert("I'm inline");
tinymce.init({
selector: 'textarea',
});
</script>
这是我用来加载这个文档的JavaScript代码(在XHR status 200
):
// * This response is HTML
response = xhr.responseText;
// * Set the innerHTML of the body to the response HTML
document.body.innerHTML = response;
// * Find all scripts with ajax-script class
responseScripts = document.getElementsByClassName('ajax-script');
// * Loop through all those scripts
for (i = responseScripts.length; i--;) {
// * Create a 'clone' script element
cloneScript = document.createElement('script');
// * If the response script has a src, add it to the clone
if(responseScripts[0].src) {
cloneScript.src = responseScripts[0].src;
}
// * If the response script has 'inline code', add it
if(responseScripts[0].innerHTML) {
cloneScript.innerHTML = responseScripts[0].innerHTML;
}
// * Remove the original script
responseScripts[0].parentNode.removeChild(responseScripts[0]);
// * Append the clone script to the document
document.body.appendChild(cloneScript);
}
因此,在这个例子中,只有alert("I'm inline");
内联代码的一部分正在执行,但其余部分没有执行。 没有控制台错误,没有什么,似乎浏览器忽略了tinymce.init()
部分。
我不知道这是否与TinyMCE
本身有关? 但为什么会这样呢? 我也试过评估代码,但没有运气。 文档加载后,我可以复制tinymce.init()
并将其粘贴到控制台中,文本编辑器实际显示(因为执行了tinymce.init())。
您是否有任何理由可以解释为什么只调用alert
功能,而不是其他? 你觉得这种加载脚本的方式有什么问题吗?
谢谢。
尽管David Water的回应在Firefox中起到了作用,但它并没有在Chrome中出现。 因此,通过遵循jfriend的建议,我将动态列表转换为数组,并确保脚本同步加载。 这是我做的:
response = xhr.responseText;
document.body.innerHTML = response;
responseScripts = document.getElementsByClassName('ajax-script');
i = 0;
// * Convert DOM dynamic list into an array
function listToArray(list) {
var array = [];
for (var i = list.length >>> 0; i--;) {
array[i] = list[i];
}
return array;
}
function loadScripts() {
if(responseScripts[i]) {
cloneScript = document.createElement('script');
if(responseScripts[i].src) {
cloneScript.src = responseScripts[i].src;
}
if(responseScripts[i].innerHTML) {
cloneScript.innerHTML = responseScripts[i].innerHTML;
}
responseScripts[i].parentNode.removeChild(responseScripts[i]);
document.body.appendChild(cloneScript);
if(cloneScript.src) {
// * For external scripts, wait 'till they load
cloneScript.onload = function () {
loadScripts(i++);
};
} else {
// * For inline scripts, just call the function again
loadScripts(i++);
}
}
}
if(responseScripts.length > 0) {
responseScripts = listToArray(responseScripts);
// * Start loading the scripts
loadScripts();
}
这是你的答案中的一个清理版本的想法(来自我的评论)。 以下是部分改进列表:
var
使用的所有变量 src=
或.innerHTML
(不是两者),因此将其转换为if / else .innerHTML
切换到.textContent
,因为我们想要的只是文本 码:
function insertHtmlAndExecutescripts(elem, html, cls) {
elem.innerHTML = html;
// make actual array of all ajax-script tags
var scripts = Array.prototype.slice.call(elem.getElementsByClassName(cls), 0);
var i = 0;
function loadScripts() {
if (i < scripts.length) {
var cloneScript = document.createElement('script');
var tag = scripts[i++];
if (tag.src) {
cloneScript.src = tag.src;
// * For external scripts, wait 'till they load
cloneScript.onload = function () {
loadScripts();
}
document.body.appendChild(cloneScript);
} else if (tag.innerHTML) {
cloneScript.textContent = tag.textContent;
document.body.appendChild(cloneScript);
// avoid stack build-up of actual recursion
setTimeout(function() {
loadScripts();
}, 0);
}
// remove the original embedded script tag (this is likely not necessary)
tag.parentNode.removeChild(tag);
}
}
loadScripts();
}
尝试记录从responseScripts[0].innerHTML
返回的内容,如果这是完整的脚本,那么您可以只eval
结果。 如果这只是第一行,那么你已经找到了问题所在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.