Javascript事件:通知控件值的更改
我有以下问题:
我有一个HTML文本框(<input type =" text">
),其内容由无法触摸的脚本修改(这是我的页面,但我使用的是外部组件)。
我希望每当该文本框的值更改时在脚本中得到通知,因此我可以对此做出反应。
我已经试过了:
txtStartDate.observe('change', function() { alert('change' + txtStartDate.value) });
(可以预测)不起作用。仅当我自己使用键盘更改文本框值,然后将焦点移到其他位置时,它才会执行,但是如果脚本更改了值,则不会执行。
我还有听不见的另一件事吗?
我正在使用Prototype库,并且在相关的情况下,修改文本框值的外部组件是Basic Date Picker(www.basicdatepicker.com)
解决方案
正如我们所暗示的,更改(和其他事件)仅在用户执行某些操作时才会触发。修改内容的脚本不会触发任何事件。唯一的解决方案是在控件中找到可以与侦听器连接的钩子。
这是我的处理方式:
basicDatePicker.selectDate = basicDatePicker.selectDate.wrap(function(orig,year,month,day,hide) { myListener(year,month,day); return orig(year,month,day,hide); });
这是基于Firebug的粗略外观(我对组件不熟悉)。如果还有其他选择日期的方法,则还需要包装这些方法。
根据外部javascript的编写方式,我们始终可以在脚本中重新编写外部脚本的相关部分,并覆盖外部定义,以便触发change事件。
在此之前,我必须使用我无法控制的脚本来执行此操作。
我们只需要找到外部函数,将其完整复制为具有相同名称的新函数,然后重新编写脚本即可执行我们想要的操作。
当然,如果脚本是使用闭包正确编写的,则我们将无法轻易对其进行更改...
IE具有onpropertychange事件,可用于此目的。
对于真正的Web浏览器(;)),有一个DOMAttrModified突变事件,但是在Firefox中进行了数分钟的实验,当以编程方式更改值时,我无法使其在文本输入上启动通过常规键盘输入),但是如果我以编程方式更改输入的名称,它将触发。越来越好奇了...
如果我们无法可靠地运行该功能,则始终可以定期轮询输入值:
var value = someInput.value; setInterval(function() { if (someInput.value != value) { alert("Changed from " + value + " to " + someInput.value); value = someInput.value; } }, 250);
除了解决问题(如noah的解释)外,我们还可以创建一个计时器,每隔几百毫秒检查一次该值。
我必须按照Dan建议的方式修改YUI datable分页器控件。这是蛮力的,但是可以解决我的问题。也就是说,找到写入该字段的方法,复制其代码并添加触发change事件的语句,然后在代码中仅处理该change事件。我们只需要用新版本覆盖原始功能即可。在我看来,轮询虽然运行良好,但它似乎是一种消耗更多资源的解决方案。
当控件的值更改时,即使通过脚本更改,addEventListener(" DOMControlValueChanged"也会触发。
addEventListener(" input"是DOMControlValueChanged的直接用户启动的过滤版本。
不幸的是,DOMControlValueChanged目前仅受Opera的支持,并且webkit中的输入事件支持已被破坏。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。输入事件在Firefox和Opera中也有各种错误。
很快,这些东西可能很快就会在HTML5中清除掉了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
更新:
自2012年9月8日起,Opera不再提供DOMControlValueChanged支持(因为已将其从HTML5中删除),并且现在在浏览器中"输入"事件支持要好得多(包括更少的错误)。