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">
这似乎是一个错误。 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);
我来晚了,但我遇到了同样的问题,我想出了一个解决方法来修复 IE 上的这种行为。
事实上,有两个不同的错误(或者更确切地说,只有一个错误,但有两种行为,具体取决于目标是输入还是文本区域)。
- For
input
:每次字段视觉内容改变时触发事件,包括键盘输入(自然),也包括占位符 appears/disappears(无内容时模糊),或者以编程方式更改可见占位符时。
- 对于
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>
解决方案非常简短!
起初我们不需要那么多我们可以在接受的答案中看到的代码。其次你必须明白为什么会这样:
- Fake
oninput
事件仅在输入 placeholder
获得焦点时触发,并且仅在输入值为空时触发。发生这种情况是因为 IE 的不良开发人员认为输入值从 placeholder value
变为真实的 value
,但这是 IE 的不良开发人员的误解。
- 没有占位符的
input
没有这个问题。
第一个解决方案非常简单:如果您确实不需要,请不要使用 placeholder
。在大多数情况下,您可以向元素添加 title
而不是 placeholder
。您也可以在 input
.
之前、下方或上方写下您的 placeholder
文本
如果你必须使用 placeholder
第二个解决方案也非常简单和简短:将之前的 value
保存在 input
对象上,并将其与新的 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)"/>
在 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">
这似乎是一个错误。 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);
我来晚了,但我遇到了同样的问题,我想出了一个解决方法来修复 IE 上的这种行为。 事实上,有两个不同的错误(或者更确切地说,只有一个错误,但有两种行为,具体取决于目标是输入还是文本区域)。
- For
input
:每次字段视觉内容改变时触发事件,包括键盘输入(自然),也包括占位符 appears/disappears(无内容时模糊),或者以编程方式更改可见占位符时。 - 对于
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>
解决方案非常简短!
起初我们不需要那么多我们可以在接受的答案中看到的代码。其次你必须明白为什么会这样:
- Fake
oninput
事件仅在输入placeholder
获得焦点时触发,并且仅在输入值为空时触发。发生这种情况是因为 IE 的不良开发人员认为输入值从placeholder value
变为真实的value
,但这是 IE 的不良开发人员的误解。 - 没有占位符的
input
没有这个问题。
第一个解决方案非常简单:如果您确实不需要,请不要使用 placeholder
。在大多数情况下,您可以向元素添加 title
而不是 placeholder
。您也可以在 input
.
placeholder
文本
如果你必须使用 placeholder
第二个解决方案也非常简单和简短:将之前的 value
保存在 input
对象上,并将其与新的 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)"/>