背景
我继承了一个古老的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代码放在一起。