我正在通过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
函数,而不是其他函数?你觉得这种加载脚本的方式有什么问题吗?
感谢。
答案 0 :(得分:2)
尽管 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();
}
答案 1 :(得分:1)
这是你的答案中的一个清理版本的想法(来自我的评论)。以下是改进的部分清单:
var
src=
或.innerHTML
(不是两者),因此将其设为if / else .textContent
切换到.innerHTML
因为我们想要的只是文字代码:
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();
}
答案 2 :(得分:0)
尝试记录从responseScripts[0].innerHTML
获取的内容,如果这是完整脚本,那么您只能eval
结果。如果这只是第一行,那么你已经找到了问题所在。