如頁面上有如下input:
<input type="text" id="demo"/>
給input加上事件:
var input = document.getElementById('demo');
input.addEventListener('oninput', function(){
console.log('oninput event ');
}, false);
input.addEventListener('onchange', function(){
console.log('onchange event');
}, false);
現(xiàn)在我用JavaScript動態(tài)的設(shè)置input的值:
document.getElementById('demo').value = 'value change';
會發(fā)現(xiàn)oninput和onchange事件都沒有自動觸發(fā),但輸入框的值卻已經(jīng)變化了。如果想要觸發(fā)事件,則必須手動觸發(fā)才行。
要想設(shè)置value值得時(shí)候,自動觸發(fā)一些事件有沒有對應(yīng)的解決辦法呢?
lerte 說的對,數(shù)據(jù)雙向綁定,不過不用框架也行,只要知道原理;樓主的問題實(shí)際上是:
改變了一個(gè)對象的屬性,怎么去自動觸發(fā)一個(gè)程序,或者訪問一個(gè)屬性,怎么去自動觸發(fā)一個(gè)程序
實(shí)際上,可以新建另一個(gè)訪問器屬性 _value ,把原來 js 對 value 的操作改為對 _value 屬性的操作,這樣訪問 _value 時(shí),會自動調(diào)用 get 函數(shù)獲取 value 的值,設(shè)置 _value 屬性時(shí),會自動調(diào)用 set 函數(shù)設(shè)置 value 屬性的值,你可以將你的程序綁定在 get/set 函數(shù)中,這樣就可以監(jiān)聽 js 修改 value 數(shù)據(jù)的變化;
如果直接設(shè)置 value 屬性為 訪問器屬性,結(jié)果會造成,用戶在頁面修改了 value,不會調(diào)用 set 函數(shù),所以 想了上面的中介 _value,此處感謝@叫我小藍(lán)就行了 的提醒。
題主的案例:
js:
window.onload = function() {
let input = document.getElementById('demo');
function oninputCallback() {
console.log('oninput event ');
}
function onchangeCallback() {
console.log('onchange event');
}
input.addEventListener('oninput', oninputCallback, false);
input.addEventListener('onchange', onchangeCallback, false);
Object.defineProperty(input, '_value', {
configurable: true,
set: function(value) {
this.value = value;
oninputCallback();
onchangeCallback();
},
get: function() {
return this.value;
}
});
};
html:
<body>
<input type="text" id="demo"/>
</body>
效果
再給個(gè)例子,根據(jù)數(shù)據(jù)類型的變化,自動修改類名,demo
js:
window.onload = function() {
let bonusDiv = document.getElementById('bonusDiv');
Object.defineProperty(bonusDiv, 'data-type', {
configurable: true,
set: function(value) {
switch (value) {
case 'x1':
this.className = 'red';
break;
case 'x2':
this.className = 'blue';
break;
case 'x3':
this.className = 'purple';
break;
}
}
});
};
html:
<div id="bonusDiv" ></div>
效果:
oninput 事件在value 改變時(shí)觸發(fā),是實(shí)時(shí)的,然而通過 js 改變 value 時(shí),卻不會觸發(fā)。onpropertychange用js改變是可以觸發(fā)的,單限于ie??梢苑庋b一下
var input = document.getElementById('demo');
valuechange(input,function(){
input.value = 'value change';
return true;
},function(){
console.log('this input change');
});
function valuechange(obj,myevent,fn){
var ie = !!window.ActiveXObject;
if(ie){
if(myevent()){
obj.onpropertychange = fn;
}
}else{
if(myevent()){
fn();
}
}
}
我覺得數(shù)據(jù)雙向綁定蠻好的,不過還有別的解決辦法,可以用js的事件構(gòu)造器,讓js觸發(fā)你想要的事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" id="demo" />
<!-- Simulate click -->
<input type="button" onclick="changeValue();" value="點(diǎn)擊我改變input值" />
<!-- Add a click handler that calls preventDefault -->
<input type="button" onclick="addHandler();" value="js觸發(fā)input和change默認(rèn)事件" />
<!-- Remove the click handler that calls preventDefault -->
<input type="button" onclick="removeHandler();" value="js取消觸發(fā)input和change默認(rèn)事件" />
<script>
var input = document.getElementById('demo');
input.addEventListener('input', function() {
console.log('oninput event ');
}, true);
input.addEventListener('change', function() {
console.log('onchange event');
}, false);
// 參考網(wǎng)站
// https://stackoverflow.com/questions/2490825/how-to-trigger-event-in-javascript
// https://developer.mozilla.org/zh-CN/docs/Web/Guide/Events/Creating_and_triggering_events
function changeValue() { //改變input的值函數(shù)
input.value = Math.random() * 10;
simulateEvent("demo", "change");
simulateEvent("demo", "input");
}
function simulateEvent(id, event) { //js觸發(fā)事件--事件構(gòu)造器
var evt = document.createEvent("Event");
evt.initEvent(event, true, true);
var cb = document.getElementById(id);
var canceled = !cb.dispatchEvent(evt);
if (canceled) {
// A handler called preventDefault
// console.log("canceled");
} else {
// None of the handlers called preventDefault
// console.log("not canceled");
}
}
function preventDef(event) {
event.preventDefault();
}
function addHandler() {
document.getElementById("demo").addEventListener("change", preventDef, false);
document.getElementById("demo").addEventListener("input", preventDef, false);
}
function removeHandler() {
document.getElementById("demo").removeEventListener("change", preventDef, false);
document.getElementById("demo").removeEventListener("input", preventDef, false);
}
</script>
</body>
</html>
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。