jQuery准备在自定义行为脚本初始化之前启动

jQuery ready firing before custom behavior script initializes

本文关键字:初始化 脚本 启动 自定义 jQuery      更新时间:2023-09-26

背景

我继承了一个古老的web应用程序,该应用程序具有使用老式HTC(HTML组件)脚本定义的自定义行为的输入控件,例如:

<input name="txtFiscalYearEndDay" type="text" value="30" 
    maxlength="2" size="5" id="txtFiscalYearEndDay" class="Text1"       
    style="behavior:url(/path/js/InFocus.htc);" />

以下是这个HTC文件的相关部分来说明这个问题:

<PUBLIC:COMPONENT tagName="InFocus">
<PUBLIC:METHOD NAME="setValid" />
<PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="initialize" />
<SCRIPT LANGUAGE="javascript">
    function initialize() {
        // attaches events and adds CSS classes, nothing fancy
    }        
    function setValid(bInternal) {
        // checks some flags and changes a label
    } 
</SCRIPT>
</PUBLIC:COMPONENT>

到目前为止,没有什么异常。此外,我还有一些运行在DOM上的JS:

$(function() {
    txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});

以及验证功能:

function txtFiscalYearEndDay_Validate(el) {
    ...
}

注意:我不使用$('#txtFiscalYearEndDay'),因为我真的不能尝试在元素上调用setValid(true);,也不想必须调用$('#txtFiscalYearEndDay')[0].setValid(true);

问题

在验证函数的某一点上,我试图调用元素上的一个方法,该方法由HTC脚本添加:

el.setValid(true);

然而,IE调试器很伤心,并抱怨setValid()不是一个函数。在调试器中检查它可以确认这一点:

typeof el.setValid // "unknown"

当然,一旦页面完成渲染(或者文档实际准备所需的任何时间段已经过去),验证函数就会按预期工作(因为我对更改和模糊事件也调用相同的验证函数)。也就是说,当在jQuery的on DOM ready函数之外调用该函数时,它工作得很好。

你们中有人对这里可能发生的事情有什么想法吗?jQuery的"ondomready"是否在HTC脚本的"ondom ready"之前注册?我能改变一下顺序吗

我目前在所有版本的IE中都看到了这种行为。

编辑:解决方案

我发现了一个变通办法。如果您将函数调用从jQuery就绪函数中取出,并将其扔到页面的末尾,它就会工作(即:)

...
    <script type="text/javascript">
        txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
    </script>
</body>
</html>

我不知道HTC是否计入页面就绪,但我怀疑他们没有。

你可能会尝试在HTC阶段结束后检查一些只有tru的东西。

然后,您自己的脚本应该开始这样的操作:

function MyFunction() {
 if(!HTCIsreadyTest()) {
    setTimeout(MyFunction, 100);
return;
}
//the rest of your code
}

这基本上可以让你在100毫秒内检查并重新启动功能,如果条件不满足,直到测试成功。

如果HTC sciprts在2秒后仍未加载,您还可以广告一个计数器参数,每次尝试触发超时代码时将其增加一

我能找到的最简单的解决方法是将验证函数调用从jQuery ready()回调中移出,并将其移动到页面的末尾:

...
    <script type="text/javascript">
        txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
    </script>
</body>
</html>

然而,我找到了一个更优雅的解决方案。因为我似乎需要等待加载所有页面资源,所以我只需要将函数调用从jQuery ready()回调中移出,并将其放入窗口load()回调:

$(window).load(function() { // instead of $(function() {
    txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});

我使用后者,这样我就可以把所有的JS代码放在一起。