鍍金池/ 問答/HTML5  HTML/ JavaScript動態(tài)的改變input的value屬性時(shí),如何自動觸發(fā)onin

JavaScript動態(tài)的改變input的value屬性時(shí),如何自動觸發(fā)oninput、onchange事件?

如頁面上有如下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)的解決辦法呢?

回答
編輯回答
念初

$("#demo").trigger("oninput").trigger("onchange");

2017年10月12日 12:32
編輯回答
兔寶寶

js動態(tài)改變時(shí),手動觸發(fā)input事件

2018年6月6日 04:37
編輯回答
憶往昔

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>

效果

clipboard.png

再給個(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>

效果:

clipboard.png

2018年8月20日 18:12
編輯回答
薔薇花

onchange 只會在你離開(blur) input 的時(shí)候觸發(fā)。你可以將回調(diào)函數(shù)抽取出來,在 JS 改變 input 時(shí)同時(shí)調(diào)用回調(diào)?;蛘哂?oninput ,搭配 onpropertychange 可兼容 IE8 。

2017年6月2日 16:37
編輯回答
抱緊我

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();
        }       
    }
}
2018年7月25日 02:52
編輯回答
巫婆

你可以做一個(gè)定時(shí)器,設(shè)置一些標(biāo)識變量,在定時(shí)器里面根據(jù)這些變量達(dá)到你的效果

2017年12月22日 23:11
編輯回答
雅痞

你既然都是用js去操作input了,這些事件觸發(fā)的處理(調(diào)用),你寫到j(luò)s后續(xù)操作中就完了,為什么還要想著觸發(fā)事件?

2017年1月5日 17:46
編輯回答
礙你眼

其實(shí),仔細(xì)一想,要是JavaScript可以通過設(shè)置值來觸發(fā)input事件,本身好像就不太合理。
因?yàn)楫?dāng)我打開一個(gè)頁面的時(shí)候,頁面中某一段js可以通過某種方法來觸發(fā)需要用戶手動觸發(fā)的事件,也就是相當(dāng)于在用戶不知情的情況下,替用戶做了某些操作(填寫表單、填寫密碼),感覺不太安全。

2017年12月5日 17:25
編輯回答
詆毀你

可以將監(jiān)聽函數(shù)內(nèi)部的操作作為一個(gè)函數(shù),當(dāng)改變input的值時(shí),調(diào)用這個(gè)函數(shù)。

2017年1月15日 22:27
編輯回答
青裙

我覺得數(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>
2018年8月14日 05:51