1. 程式人生 > >輸入框事件監聽(五):如何感知JS設值的變化

輸入框事件監聽(五):如何感知JS設值的變化

通過change事件,輸入框可以感知使用者手動輸入,但是如果用程式對輸入框進行賦值,則會出現無法感知的情況。

實踐的HTML如下:

<input type="text" id="username" name="username"/>

實踐的JS如下:

var username = document.querySelector("#username"),
    counter = 0;
//  建立定時器對其進行設值
setInterval(function() {
    //  強烈推薦使用這種方式賦值
    username.setAttribute("value", counter++);
    //  對輸入框賦值
// username.value = counter ++; }, 1000); // 監聽輸入框的change事件 username.addEventListener("change", function() { console.debug("change", this.value); });

執行上面的程式碼,觀察瀏覽器的控制檯視窗,發現沒有任何輸出,也就是說對於程式設值的這種方式,輸入框完全無法感知到變化。那使用focus與blur事件呢?

//  在設值時觸發focus、blur事件
setInterval(function() {
    username.focus();
    //  強烈推薦使用這種方式賦值
username.setAttribute("value", counter++); // 對輸入框賦值 // username.value = counter ++; username.blur(); }, 1000); // 監聽輸入框的blur、focus事件 username.addEventListener("blur", function() { console.debug("change", this.value); });

執行的結果是,只能感知到很少的一部分狀態變化(隨機地有幾次被感知到),所以這種辦法不能被採用,因為必然會出現難以預料的bug。並且這種辦法會在設值時侵入太多的程式碼,難以滿足實際的情況,如第三方外掛封裝了某個輸入框,我們想感知到此輸入框內容的變化,如果採用上面的程式碼,則需要大量地修改第三方外掛的程式碼。

經過仔細地研究,發現HTML5提供了一個新的觀察介面Observer,可以用來觀察DOM的子節點與屬性的變化,例項如下:

//  定義觀察器Observer
var  observer = new MutationObserver(function() {
    console.debug(username.value);
});
//  定義需要監控dom的哪些內容
observer.observe(username, {
    attributes : true,
    attributeOldValue : false,
    attributeFilter : ['value']
    characterData  : true,
    characterDataOldValue : true
});

現在觀察瀏覽器的輸出視窗,發現能觀察到每一次值的改變。但需要特別注意的是,賦值的方式一定要採用setAttribute方式,賦值的方式一定要採用setAttribute方式,賦值的方式一定要採用setAttribute方式。(重要的事情說三遍)