問題描述
有多種方式,< input type = “text”> 可以改變,包括:
-
按鍵
-
複製貼上
-
用 JavaScript 修改
-
auto-completed 透過瀏覽器或工具欄
我希望我的 JavaScript 函式隨時更改 (當前的輸入值) 被呼叫。而且我希望它立即被打來,而不僅僅是當輸入失去焦點時。
我正在尋找在所有瀏覽器 (最好使用 jQuery) 這樣做最乾淨,最強大的方法。
示例用例:在 Twitter Signup 頁面上,使用者名稱欄位的值顯示在其下面的 URL「http://twitter/ username」 中。
最佳解決方案
這個 jQuery 程式碼可以立即對任何元素進行更改,並且可以在所有瀏覽器中執行:
$('.myElements').each(function() {
var elem = $(this);
// Save current value of element
elem.data('oldVal', elem.val());
// Look for changes in the value
elem.bind("propertychange change click keyup input paste", function(event){
// If value has changed...
if (elem.data('oldVal') != elem.val()) {
// Updated stored value
elem.data('oldVal', elem.val());
// Do action
....
}
});
});
次佳解決方案
不幸的是,我認為 setInterval 獲獎:
<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>
這是最簡單的解決方案,只有一行程式碼。它也是最強大的,因為您不必擔心 input 可以獲得的所有不同的事件/方式。
在這種情況下,使用’setInterval’ 的缺點似乎不適用:
-
100ms 延遲?對於許多應用,100ms 足夠快。
-
在瀏覽器上增加了負載?一般來說,在您的頁面上新增大量 heavy-weight setIntervals 是不好的。但在這種特殊情況下,增加的頁面載入是不可檢測的。
-
它不會擴充套件到許多輸入?大多數頁面沒有多少輸入,您可以在同一個 setInterval 中嗅探所有的輸入。
第三種解決方案
jquery 的即時花式解決方案> = 1.9
$("#input-id").on("change keyup paste", function(){
dosomething();
})
如果還要檢測”click” 事件,只需:
$("#input-id").on("change keyup paste click", function(){
dosomething();
})
如果你的 jquery <= 1.4,只需使用"live" 而不是"on" 。
第四種方案
繫結到 oninput 事件似乎在大多數健全的瀏覽器中正常工作。 IE9 也支援它,但實現是錯誤的 (刪除字元時事件不會觸發) 。
使用 jQuery 版本 1.7+,on 方法可以像這樣繫結到事件:
$(".inputElement").on("input", null, null, callbackFunction);
第五種方案
不幸的是,沒有符合您的標準的事件或事件集。鍵盤和複製/貼上都可以使用 keyup 事件來處理。透過 JS 進行的更改變得非常棘手。如果您可以控制設定文字框的程式碼,最好的方法是修改它直接呼叫函式或觸發文字框上的使用者事件:
// Compare the textbox's current and last value. Report a change to the console.
function watchTextbox() {
var txtInput = $('#txtInput');
var lastValue = txtInput.data('lastValue');
var currentValue = txtInput.val();
if (lastValue != currentValue) {
console.log('Value changed from ' + lastValue + ' to ' + currentValue);
txtInput.data('lastValue', currentValue);
}
}
// Record the initial value of the textbox.
$('#txtInput').data('lastValue', $('#txtInput').val());
// Bind to the keypress and user-defined set event.
$('#txtInput').bind('keypress set', null, watchTextbox);
// Example of JS code triggering the user event
$('#btnSetText').click(function (ev) {
$('#txtInput').val('abc def').trigger('set');
});
如果您無法控制該程式碼,可以使用 setInterval()將’watch’ 更改為文字框:
// Check the textbox every 100 milliseconds. This seems to be pretty responsive.
setInterval(watchTextbox, 100);
這種主動監控不會捕獲更新’immediately’,但似乎足夠快,沒有明顯的滯後。正如 DrLouie 在評論中指出的那樣,如果您需要觀看大量投入,此解決方案可能不會很好地擴充套件。您可以隨時調整第二個引數到 setInterval()以檢查更多或更少的頻率。
第六種方案
如果您不喜歡任何其他答案,這是一個稍微不同的解決方案:
var field_selectors = ["#a", "#b"];
setInterval(function() {
$.each(field_selectors, function() {
var input = $(this);
var old = input.attr("data-old-value");
var current = input.val();
if (old !== current) {
if (typeof old != 'undefined') {
... your code ...
}
input.attr("data-old-value", current);
}
}
}, 500);
考慮到您無法依靠點選和金鑰來捕獲上下文選單貼上。
第七種方案
我建立了一個示例。可能會為你工作
var typingTimer;
var doneTypingInterval = 10;
var finaldoneTypingInterval = 500;
var oldData = $("p.content").html();
$('#tyingBox').keydown(function () {
clearTimeout(typingTimer);
if ($('#tyingBox').val) {
typingTimer = setTimeout(function () {
$("p.content").html('Typing...');
}, doneTypingInterval);
}
});
$('#tyingBox').keyup(function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(function () {
$("p.content").html(oldData);
}, finaldoneTypingInterval);
});
<script src="https://googleajax.admincdn.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<textarea id="tyingBox" tabindex="1" placeholder="Enter Message"></textarea>
<p class="content">Text will be replace here and after Stop typing it will get back</p>
第八種方案
2017 答案:input event 完全符合 IE8 的要求。
$(el).on('input', callback)
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。