我怎么能等到新创建的元素 "ready"(所有脚本都已下载)
How can I wait until a newly created Element is "ready" (all scripts downloaded)
我正在编写一段代码,将 Sammy JS(路由器)和 Knockout JS 粘合在一起。
所以,这是我的问题,
<script id="MyTemplate" type="text/html">
// [HTML Containing a script link (Encoded HTML)]
</script>`
我使用 jQuery 创建此模板的实例:
var TInstance = $($("#MyTemplate").text())
然后,我想将新的 html TInstance
注入我的 <body>
或其他现有标签
$("body").html(TInstance)
很好,现在我想做 ko.applyBindings
将新的 TInstance
绑定到 ViewModel
并且它有效。
我遇到的问题是:当我在 TInstance
中有一个 <script src="..." />
时,
我想等到该脚本被下载和解析,然后执行 ko.applyBindings
.
所以我尝试了 $(TInstance).ready(() => {ko.applyBindings(...)})
,它在第一次加载页面时工作,但如果我重做整个过程,换入新的 TInstance
新 [=14= 上的就绪处理程序] 不会开火。
我该怎么办?
已通过使用 0 毫秒 setTimeout
调用解决了问题
setTimeout(() => { /*all new resources have been loaded and the html rendered*/ });
帮助:https://eager.io/blog/how-to-decide-when-your-code-should-run/
好的,这个答案不会是 "copy & paste and play",它需要你进行一些调整,但我认为你会理解这个概念并且你会管理。
没有添加依赖管理模块,也没有重构你的代码(通常纯脚本标签不会与 html 一起动态注入,原因与你现在遇到麻烦的原因相同。这是一个好主意在第一页加载时使用 html 加载脚本标签,但以后添加的任何内容,特别是如果需要某些流程,都需要编程处理,因此需要模块管理框架来处理更大的项目)
一种方法是停止您的代码执行流程并轮询环境以查看您的脚本是否已加载。即:
var demoInterval = setInterval(function(){
if(myCondition){
clearInterval(demoInterval );
functionThatStartsTheRestOfTheLogicFlow(); // this could apply bindings etc etc
}
},50);
现在举例来说,如果您使用脚本标签加载 jQuery,您的条件可能是
typeof($) !== 'undefined'
它会每 50 毫秒轮询一次,直到 $ 被定义,然后它会调用一个函数来清除轮询并继续您的逻辑流程。
在你的情况下,条件可能是 function/model 的定义,一个你的自定义 js 文件可以设置的类似标志的变量,轮询预计会在某个时候读取等等。
更好的方法是从 html 中删除脚本标签并通过 javascript 动态加载脚本,以便您可以利用所需的特定脚本的 onload 事件,您可以阅读示例 here。对于开发人员来说,以编程方式控制这些情况要容易得多。
希望对您有所帮助
我正在编写一段代码,将 Sammy JS(路由器)和 Knockout JS 粘合在一起。
所以,这是我的问题,
<script id="MyTemplate" type="text/html">
// [HTML Containing a script link (Encoded HTML)]
</script>`
我使用 jQuery 创建此模板的实例:
var TInstance = $($("#MyTemplate").text())
然后,我想将新的 html TInstance
注入我的 <body>
或其他现有标签
$("body").html(TInstance)
很好,现在我想做 ko.applyBindings
将新的 TInstance
绑定到 ViewModel
并且它有效。
我遇到的问题是:当我在 TInstance
中有一个 <script src="..." />
时,
我想等到该脚本被下载和解析,然后执行 ko.applyBindings
.
所以我尝试了 $(TInstance).ready(() => {ko.applyBindings(...)})
,它在第一次加载页面时工作,但如果我重做整个过程,换入新的 TInstance
新 [=14= 上的就绪处理程序] 不会开火。
我该怎么办?
已通过使用 0 毫秒 setTimeout
调用解决了问题
setTimeout(() => { /*all new resources have been loaded and the html rendered*/ });
帮助:https://eager.io/blog/how-to-decide-when-your-code-should-run/
好的,这个答案不会是 "copy & paste and play",它需要你进行一些调整,但我认为你会理解这个概念并且你会管理。
没有添加依赖管理模块,也没有重构你的代码(通常纯脚本标签不会与 html 一起动态注入,原因与你现在遇到麻烦的原因相同。这是一个好主意在第一页加载时使用 html 加载脚本标签,但以后添加的任何内容,特别是如果需要某些流程,都需要编程处理,因此需要模块管理框架来处理更大的项目)
一种方法是停止您的代码执行流程并轮询环境以查看您的脚本是否已加载。即:
var demoInterval = setInterval(function(){
if(myCondition){
clearInterval(demoInterval );
functionThatStartsTheRestOfTheLogicFlow(); // this could apply bindings etc etc
}
},50);
现在举例来说,如果您使用脚本标签加载 jQuery,您的条件可能是 typeof($) !== 'undefined' 它会每 50 毫秒轮询一次,直到 $ 被定义,然后它会调用一个函数来清除轮询并继续您的逻辑流程。
在你的情况下,条件可能是 function/model 的定义,一个你的自定义 js 文件可以设置的类似标志的变量,轮询预计会在某个时候读取等等。
更好的方法是从 html 中删除脚本标签并通过 javascript 动态加载脚本,以便您可以利用所需的特定脚本的 onload 事件,您可以阅读示例 here。对于开发人员来说,以编程方式控制这些情况要容易得多。
希望对您有所帮助