Javascript 对输入值进行编程更改时触发操作
我的目标是观察输入值,并在其值以编程方式更改时触发处理程序。我只在现代浏览器中需要它 我使用Javascript 对输入值进行编程更改时触发操作,javascript,html-input,defineproperty,Javascript,Html Input,Defineproperty,我的目标是观察输入值,并在其值以编程方式更改时触发处理程序。我只在现代浏览器中需要它 我使用defineProperty尝试了许多组合,这是我的最新迭代: var myInput=document.getElementById("myInput"); Object.defineProperty(myInput,"value",{ get:function(){ return this.getAttribute("value"); }, set:functi
defineProperty
尝试了许多组合,这是我的最新迭代:
var myInput=document.getElementById("myInput");
Object.defineProperty(myInput,"value",{
get:function(){
return this.getAttribute("value");
},
set:function(val){
console.log("set");
// handle value change here
this.setAttribute("value",val);
}
});
myInput.value="new value"; // should trigger console.log and handler
这似乎达到了我的预期,但它感觉像是一个黑客,因为我正在覆盖现有的value属性并使用value
(属性和属性)的双重状态。它还中断了似乎不喜欢修改的属性的change
事件
我的其他尝试:
- setTimeout/setInterval循环,但这也不是干净的
- 各种
和watch
polyfill,但它们因输入值属性而中断observe
@mohit jain建议的诀窍是为用户交互添加第二个输入。既然您已经在使用polyfills进行监视/观察等,让我借此机会向您提出建议 它以ng模型的形式提供了这一功能。您可以在模型的值上设置观察者,当它发生变化时,您可以调用其他函数 以下是一个非常简单但有效的解决方案: 基本上,进行文本输入并将其绑定到模型:
<input type="text" data-ng-model="variable">
我只在现代浏览器中需要它
你想要多现代?Ecma脚本7(6将在12月定稿)可能包含以下内容。这将允许您创建本机可观察对象。是的,你可以运行它!怎么做
要尝试此功能,您需要启用enable
Chrome Canary中的实验JavaScript标志并重新启动浏览器。
该标志可在'about:flags'
更多信息:
是的,这是高度实验性的,在当前的浏览器中还没有准备好。而且,它还没有完全准备好,而且如果是ES7的话也不是100%,ES7的最终日期甚至还没有确定。不过,我还是想让您知道,以备将来使用。有一种方法可以做到这一点。
没有DOM事件,但是有一个javascript事件会在对象属性更改时触发
document.form1.textfield.watch("value", function(object, oldval, newval){})
^ Object watched ^ ^ ^
|_ property watched | |
|________|____ old and new value
在回调中,您可以执行任何操作
在本例中,我们可以看到这种效果(请检查): 当
obj
更改时,它会激活监视
侦听器。
此链接中有更多信息:如果解决方案的唯一问题是值集上的更改事件中断。thn您可以在现场手动触发该事件。(但如果用户通过浏览器更改输入,则不会设置此监视器--请参见下面的编辑)
//API将要更改的隐藏输入
var myInput=document.getElementById(“myInput”);
//用户的可视输入
var myInputVisible=document.getElementById(“myInputVisible”);
//隐藏输入的属性变异
Object.defineProperty(myInput,“值”{
get:function(){
返回此.getAttribute(“值”);
},
设置:功能(val){
console.log(“set”);
//更新myInput集合上myInputVisible的值
myInputVisible.value=val;
//在这里处理值更改
此.setAttribute(“值”,val);
//解雇事件
如果(文档中的“createEvent”){//现代浏览器
var evt=document.createEvent(“HTMLEvents”);
evt.initEvent(“变更”、真、假);
myInput.dispatchEvent(evt);
}
否则{//IE 8及以下
var evt=document.createEventObject();
myInput.fireEvent(“onchange”,evt);
}
}
});
//侦听可见的输入更改并更新隐藏的
myInputVisible.onchange=函数(e){
myInput.value=myInputVisible.value;
};
//这是您希望使用的任何自定义事件处理程序
//它将捕获两个编程更改(直接在myInput上完成)
//和用户的更改(在myInputVisible上完成)
myInput.onchange=函数(e){
log(myInput.value);
};
//演示编程更改的测试方法
函数testSet(){
myInput.value=Math.floor((Math.random()*100000)+1);
}
编辑: 手动事件触发和mutator方法的问题在于,当用户从浏览器更改字段值时,value属性不会更改。解决方法是使用两个字段。一个隐藏的,我们可以有编程交互。另一个是可见的,用户可以与之交互。考虑到这一点,这种方法非常简单
onpropertychange
util.listenToCustomEvents = function (event_name, callback) {
if (document.addEventListener) {
document.addEventListener(event_name, callback, false);
} else {
document.documentElement.attachEvent('onpropertychange', function (e) {
if(e.propertyName == event_name) {
callback();
}
}
};
我不确定IE8解决方案是否可以跨浏览器工作,但您可以在输入的属性值上设置一个假的eventlistener
,并在值
var obj = { prop: 123 };
obj.watch('prop', function(propertyName, oldValue, newValue){
console.log('Old value is '+oldValue); // 123
console.log('New value is '+newValue); // 456
});
obj.prop = 456;
<html>
<body>
<input type='hidden' id='myInput' />
<input type='text' id='myInputVisible' />
<input type='button' value='Test' onclick='return testSet();'/>
<script>
//hidden input which your API will be changing
var myInput=document.getElementById("myInput");
//visible input for the users
var myInputVisible=document.getElementById("myInputVisible");
//property mutation for hidden input
Object.defineProperty(myInput,"value",{
get:function(){
return this.getAttribute("value");
},
set:function(val){
console.log("set");
//update value of myInputVisible on myInput set
myInputVisible.value = val;
// handle value change here
this.setAttribute("value",val);
//fire the event
if ("createEvent" in document) { // Modern browsers
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, false);
myInput.dispatchEvent(evt);
}
else { // IE 8 and below
var evt = document.createEventObject();
myInput.fireEvent("onchange", evt);
}
}
});
//listen for visible input changes and update hidden
myInputVisible.onchange = function(e){
myInput.value = myInputVisible.value;
};
//this is whatever custom event handler you wish to use
//it will catch both the programmatic changes (done on myInput directly)
//and user's changes (done on myInputVisible)
myInput.onchange = function(e){
console.log(myInput.value);
};
//test method to demonstrate programmatic changes
function testSet(){
myInput.value=Math.floor((Math.random()*100000)+1);
}
</script>
</body>
</html>
util.listenToCustomEvents = function (event_name, callback) {
if (document.addEventListener) {
document.addEventListener(event_name, callback, false);
} else {
document.documentElement.attachEvent('onpropertychange', function (e) {
if(e.propertyName == event_name) {
callback();
}
}
};