如頁面上有如下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值得時候,自動觸發(fā)一些事件有沒有對應(yīng)的解決辦法呢?
lerte 說的對,數(shù)據(jù)雙向綁定,不過不用框架也行,只要知道原理;樓主的問題實際上是:
改變了一個對象的屬性,怎么去自動觸發(fā)一個程序,或者訪問一個屬性,怎么去自動觸發(fā)一個程序
實際上,可以新建另一個訪問器屬性 _value ,把原來 js 對 value 的操作改為對 _value 屬性的操作,這樣訪問 _value 時,會自動調(diào)用 get 函數(shù)獲取 value 的值,設(shè)置 _value 屬性時,會自動調(diào)用 set 函數(shù)設(shè)置 value 屬性的值,你可以將你的程序綁定在 get/set 函數(shù)中,這樣就可以監(jiān)聽 js 修改 value 數(shù)據(jù)的變化;
如果直接設(shè)置 value 屬性為 訪問器屬性,結(jié)果會造成,用戶在頁面修改了 value,不會調(diào)用 set 函數(shù),所以 想了上面的中介 _value,此處感謝@叫我小藍就行了 的提醒。
題主的案例:
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>
效果
再給個例子,根據(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 改變時觸發(fā),是實時的,然而通過 js 改變 value 時,卻不會觸發(fā)。onpropertychange用js改變是可以觸發(fā)的,單限于ie。可以封裝一下
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="點擊我改變input值" />
<!-- Add a click handler that calls preventDefault -->
<input type="button" onclick="addHandler();" value="js觸發(fā)input和change默認事件" />
<!-- Remove the click handler that calls preventDefault -->
<input type="button" onclick="removeHandler();" value="js取消觸發(fā)input和change默認事件" />
<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年。依托北京大學優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達內(nèi)教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進“中國制造2025”,實現(xiàn)中華民族偉大復興的升級產(chǎn)業(yè)鏈。利用北京大學優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓領(lǐng)域的先行者
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經(jīng)理職務(wù)負責iOS教學及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。