簡體   English   中英

IE 10, 11. 如何防止使用占位符的文本輸入觸發焦點上的輸入事件?

[英]IE 10, 11. How to prevent the triggering of input events on focus from text input with placeholder?

在 IE 11 中,如果我有一個帶有placeholder的空電子郵件input ,然后在單擊(聚焦)它時,將觸發input事件。

有誰知道為什么,有沒有解決方案,因為input值並沒有真正改變?

 var el = document.getElementById('myEmail'); el.addEventListener("input", myFunction, true); function myFunction() { alert("changed"); }
 <input id="myEmail" type="email" placeholder="Email">

我參加聚會很晚,但我遇到了同樣的問題,我找到了一種解決方法來修復 IE 上的這種行為。 事實上,有兩個不同的錯誤(或者更確切地說,只有一個錯誤但有兩種行為,具體取決於目標是輸入還是文本區域)。

  • 對於input :每次字段的視覺內容發生變化時都會觸發該事件,包括鍵盤輸入(自然地),以及占位符出現/消失(沒有內容時模糊),或者當可見占位符以編程方式更改時。
  • 對於textarea :它基本上是相同的,除了當占位符消失時事件不會觸發。

 function onInputWraper(cb) { if (!window.navigator.userAgent.match(/MSIE|Trident/)) return cb; return function (e) { var t = e.target, active = (t == document.activeElement); if (!active || (t.placeholder && t.composition_started !== true)) { t.composition_started = active; if ((!active && t.tagName == 'TEXTAREA') || t.tagName == 'INPUT') { e.stopPropagation(); e.preventDefault(); return false; } } cb(e); }; } var el = document.getElementById('myEmail'); el.addEventListener("input", onInputWraper(myFunction), true); function myFunction() { alert("changed"); }
 <input id="myEmail" type="email" placeholder="Email">

還有一個完整的示例,您還可以在其中更改占位符值

 function onInputWraper(cb) { if (!window.navigator.userAgent.match(/MSIE|Trident/)) return cb; return function (e) { var t = e.target, active = (t == document.activeElement); if (!active || (t.placeholder && t.composition_started !== true)) { t.composition_started = active; if ((!active && t.tagName == 'TEXTAREA') || t.tagName == 'INPUT') { e.stopPropagation(); e.preventDefault(); return false; } } cb(e); }; } function handle(event) { console.log('EVENT', event); document.getElementById('output') .insertAdjacentHTML('afterbegin', "<p>" + event.type + " triggered on " + event.target.tagName + '</p>'); } var input = document.getElementById('input'), textarea = document.getElementById('textarea'); input.addEventListener('input', onInputWraper(handle)); textarea.addEventListener('input', onInputWraper(handle)); // input.addEventListener('input', handle); // textarea.addEventListener('input', handle); // Example's settings function removeListeners(elem) { var value = elem.value, clone = elem.cloneNode(true); elem.parentNode.replaceChild(clone, elem); clone.value = value; return clone; } document.querySelector('#settings input[type="checkbox"]').addEventListener('change', function (event) { if (event.target.checked) { document.getElementById('output').insertAdjacentHTML('afterbegin', '<p>Filter enabled !</p>'); //input = removeListeners(input); console.log(input.value.length, (input == document.activeElement)); input = removeListeners(input); input.addEventListener('input', onInputWraper(handle)); input.composing = input.value.length > 0 || (input == document.activeElement); textarea = removeListeners(textarea); textarea.addEventListener('input', onInputWraper(handle)); textarea.composing = textarea.value.length > 0 || (textarea == document.activeElement); } else { document.getElementById('output').insertAdjacentHTML('afterbegin', '<p>Filter disabled !</p>'); input = removeListeners(input); input.addEventListener('input', handle); input.composing = void 0; textarea = removeListeners(textarea); textarea.addEventListener('input', handle); textarea.composing = void 0; } }); document.getElementById('input_cfg').addEventListener('click', function () { document.getElementById('input').setAttribute('placeholder', document.getElementById( 'input_placeholder').value); }); document.getElementById('textarea_cfg').addEventListener('click', function () { document.getElementById('textarea').setAttribute('placeholder', document.getElementById( 'textarea_placeholder').value); });
 * { font: 15px arial, sans-serif; } dd { background: FloralWhite; margin: 0; } dt { padding: 15px; font-size: 1.2em; background: steelblue; color: AntiqueWhite; } p { margin: 0; } button, label { width: 300px; margin: 5px; padding: 5px; float: left; color: DarkSlateGray; } #settings label { width: 100%; margin: 15px; } #forms input, #forms textarea, #settings input:not([type]) { display: block; width: calc(100% - 340px); padding: 7px; margin: 0; margin-left: 320px; min-height: 25px; border: 1px solid gray; background: white; cursor: text; } ::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ color: LightBlue; opacity: 1; /* Firefox */ } ::-ms-input-placeholder { /* Microsoft Edge */ color: LightBlue; } :-ms-input-placeholder { /* Internet Explorer 10-11 */ color: LightBlue; }
 <dl> <dt>Forms</dt> <dd id="forms"> <label for="input">Input: </label> <input id="input" name="input" class="testing" placeholder="Type some text" /> <label for="texarea">Textarea: </label> <textarea id="textarea" name="textarea" placeholder="Type some text"></textarea> </dd> <dt>Settings</dt> <dd id="settings"> <p> <label><input type="checkbox" checked>Enable filtering script</label> <button id="input_cfg">Change input's placeholder to</button><input id="input_placeholder" /> </p> <p> <button id="textarea_cfg">Change textarea's placeholder to</button> <input id="textarea_placeholder" /> </p> </dd> <dt>Output</dt> <dd id="output"></dd> </dl>

或在 jsfiddle

這似乎是一個錯誤。 oninput已經被支持,因為 IE9 應該只在值改變時觸發。 另一種方法是使用onkeyup

https://developer.mozilla.org/en-US/docs/Web/Events/input

如果您想處理輸入和驗證,您只需添加第二個事件偵聽器(假設您的 html 與上述相同)。

var el = document.getElementById('myEmail');
function myFunction() {
  console.log("changed");
}
el.addEventListener("keyup", myFunction, true);
function validation() {
  console.log("validated");
}
el.addEventListener("keyup", validation, true);

解決方案很短!

起初,我們不需要在接受的答案中看到的那么多代碼。 其次,您必須了解為什么會發生這種情況:

  1. oninput事件僅在具有placeholder輸入上觸發,並且僅在輸入值為空時才觸發。 之所以會這樣,是因為IE的不良開發人員認為輸入值從placeholder value變為實際value ,但這是IE的不良開發人員的誤解。
  2. 沒有占位符的input沒有這個問題。

第一個解決方案非常簡單:如果您真的不需要,請不要使用placeholder 在大多數情況下,您可以為元素添加title而不是placeholder 您還可以在input之前、下方或上方編寫placeholder文本。

如果必須使用placeholder

第二種解決方案也非常簡單和簡短:保存input對象上的先前value並將其與新value進行比較——如果它沒有更改,則從代碼之前的函數return

生活實例

 var input = document.querySelector('input[type=search]'); input.addEventListener('input', function(e) { if(this.prevVal == this.value /* if the value was not changed */ || !this.prevVal && '' == this.value) //only for the first time because we do not know the previous value return; //the function returns "undefined" as value in this case this.prevVal = this.value; //YOUR CODE PLACE console.log('log: ' + this.value) }, false);
 <input type="search" placeholder="Search..."/>

或者,如果您將其用作內聯 JavaScript:

 function onSearch(trg) { if(trg.prevVal == trg.value /* if the value was not changed */ || !trg.prevVal && '' == trg.value) //only for the first time because we do not know the previous value return; //the function returns "undefined" as value in this case trg.prevVal = trg.value; // save the previous value on input object //YOUR CODE PLACE console.log('log: ' + trg.value); }
 <input type="search" placeholder="Search..." oninput="onSearch(this)"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM