我通过ajax加载HTML部分。通过在现有节点上使用将partial附加到DOM。
部分底部包含一些脚本标记,如:
innerHTML
但是,由于脚本标记未执行,我遍历加载的部分以识别所有脚本标记。然后,我在DOM中创建新的脚本节点,并将它们附加到<script src="/Scripts/Griffin.Editor.js" type="text/javascript"></script>
<script type="text/javascript">
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
var textParser = {
parse: function (text) {
return marked(text);
}
}
var prismHighlighter = {
highlight: function (blockElements, inlineElements) {
blockElements.forEach(function(item) {
Prism.highlightElement(item);
});
}
};
var editor = new Griffin.Editor('editor', textParser);
editor.syntaxHighlighter = prismHighlighter;
editor.preview();
</script>
。
类似的东西:
HEAD
根据我的理解,浏览器应该在调用嵌入式脚本之前加载引用的脚本。然而,对我来说情况并非如此,因为JS控制台抱怨没有找到依赖脚本中定义的对象。
如果我使用计时器并在其中评估嵌入式脚本,一切正常。但这似乎是一个丑陋的解决方法,我真的想了解加载行为背后的机制(即为什么在部分附加到DOM时不执行脚本以及为什么在我添加节点时不直接加载引用的脚本var scripts = viewElem.getElementsByTagName('script');
for (let i = 0; i < len; i++) {
var scriptTag = scripts[0];
let node = document.createElement('script');
if (scriptTag.src && scriptTag.src.length > 0) {
node.src = scriptTag.src;
node.type = scriptTag.type;
} else {
node.text = scriptTag.text;
node.type = scriptTag.type;
//had eval here before (instead of attaching the embedded script to the HEAD).
}
document.head.appendChild(node);
scriptTag.parentNode.remove(scriptTag);
}
代码。
答案 0 :(得分:0)
从我遇到的情况来看,您无法在Ajax响应中立即执行JavaScript。原因是你试图在另一个JavaScript函数中执行JavaScript。因此浏览器不知道在这种情况下使用哪个执行上下文。
我建议像你提到的那样使用延迟执行。除此之外,您需要让浏览器首先解释Ajax响应。例如:
$.get('url', function (html) {
// html = "<script>function myTest () { console.log('here'); }</script>"
$('#result').html(html);
// Now that the DOM has had time to parse the response we can do:
myTest();
});
注意,调用响应函数的Ajax回调不是立即执行的响应。希望这会有所帮助。
答案 1 :(得分:0)
我发现really great article深入解释了如何将脚本加载到浏览器中。
实质上,当您动态包含脚本时,您无法确定每个默认的执行顺序。要确保您需要执行以下某项操作的顺序
一个。如果支持,请使用async=false
湾使用readyState(对于ie <10)
C。使用defer
属性。
尝试按顺序使用上述功能以确定。
但是,即使你做了所有这些,如果你将嵌入式脚本(脚本标签中的代码)与引用的脚本混合(使用src
属性),你仍然会被搞砸。
问题是嵌入式脚本将直接运行,即使之前添加了引用脚本标记。要解决这个问题,您需要将嵌入式脚本推送到队列中,并为所有引用的脚本挂钩load
事件。
一旦所有引用的脚本切换load
,即使您可以自由调用嵌入式脚本(通过将脚本标记添加到元素或eval
其text
属性)。