Ie 10, 11. How To Prevent The Triggering Of Input Events On Focus From Text Input With Placeholder?
Solution 1:
I came very late to the party, but I had the same problem, and I came to a workaround to fix this behavior on IE. In fact, there's two different bugs (or rather, only one bug but with two behavior depending on whether the target is an input or a textarea).
- For
input
: the event is triggered each time the visual content of the field change, including keyboard inputting (naturally), but also when a placeholder appears/disappears (blur when no content), or when a visible placeholder is changed programmatically. - For
textarea
: it's basically the same, exepts that the event don't trigger when the placeholder disapears.
functiononInputWraper(cb) {
if (!window.navigator.userAgent.match(/MSIE|Trident/)) return cb;
returnfunction (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();
returnfalse;
}
}
cb(e);
};
}
var el = document.getElementById('myEmail');
el.addEventListener("input", onInputWraper(myFunction), true);
functionmyFunction() {
alert("changed");
}
<inputid="myEmail"type="email"placeholder="Email">
And there's a full-working example, where you can also change placeholders value
functiononInputWraper(cb) {
if (!window.navigator.userAgent.match(/MSIE|Trident/)) return cb;
returnfunction (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();
returnfalse;
}
}
cb(e);
};
}
functionhandle(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 settingsfunctionremoveListeners(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 = void0;
textarea = removeListeners(textarea);
textarea.addEventListener('input', handle);
textarea.composing = void0;
}
});
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;
}
#settingslabel {
width: 100%;
margin: 15px;
}
#formsinput,
#formstextarea,
#settingsinput: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><ddid="forms"><labelfor="input">Input: </label><inputid="input"name="input"class="testing"placeholder="Type some text" /><labelfor="texarea">Textarea: </label><textareaid="textarea"name="textarea"placeholder="Type some text"></textarea></dd><dt>Settings</dt><ddid="settings"><p><label><inputtype="checkbox"checked>Enable filtering script</label><buttonid="input_cfg">Change input's placeholder to</button><inputid="input_placeholder" /></p><p><buttonid="textarea_cfg">Change textarea's placeholder to</button><inputid="textarea_placeholder" /></p></dd><dt>Output</dt><ddid="output"></dd></dl>
Solution 2:
It seems like a bug. oninput
has been supported since IE9 should only fire when the value is changed. An alternate approach would be to use onkeyup
https://developer.mozilla.org/en-US/docs/Web/Events/input
If you want to handle input and validation you can just add a second eventlistener (assuming your html is the same as above).
var el = document.getElementById('myEmail');
functionmyFunction() {
console.log("changed");
}
el.addEventListener("keyup", myFunction, true);
functionvalidation() {
console.log("validated");
}
el.addEventListener("keyup", validation, true);
Solution 3:
The solution is very short!
At first we don't need so much of code what we can see in accepted answer. At second you have to understand why it is happening:
- Fake
oninput
event triggers only on inputs with aplaceholder
on getting a focus and only if the input value is empty. It happens because bad developer from IE had thought that the input value changes fromplaceholder value
to realvalue
, but it is misunderstanding from this bad developer from IE. - An
input
without placeholders doesn't have this problems.
The first solution is very simple: do not use a placeholder
if you do not really need it. In most cases you can add a title
to the element instead of a placeholder
. You could also write your placeholder
text before, below or above the input
.
If you have to use a placeholder
The second solution is also very simple and short: save the previous value
on the input
object and compare it with a new value
– if it was not changed then return
from the function before your code.
Life examples
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 valuereturn; //the function returns "undefined" as value in this casethis.prevVal = this.value;
//YOUR CODE PLACEconsole.log('log: ' + this.value)
}, false);
<inputtype="search"placeholder="Search..."/>
Or if you use it as inline JavaScript:
functiononSearch(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 valuereturn; //the function returns "undefined" as value in this case
trg.prevVal = trg.value; // save the previous value on input object//YOUR CODE PLACEconsole.log('log: ' + trg.value);
}
<inputtype="search"placeholder="Search..."oninput="onSearch(this)"/>
Post a Comment for "Ie 10, 11. How To Prevent The Triggering Of Input Events On Focus From Text Input With Placeholder?"