脚本未直接加载

时间:2015-07-19 19:30:35

标签: javascript ajax dom

我通过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); } 代码。

2 个答案:

答案 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,即使您可以自由调用嵌入式脚本(通过将脚本标记添加到元素或evaltext属性)。

来源:http://blog.gauffin.org/2015/07/embedded-script-tags-in-content-loaded-through-ajax-and-execute-the-script-tags-dynamically/