Scenario: display alert message onblur (or onchange) as a part of javascript field validation.
User action with onblur:
1) click inside input
2) click outside the input
3) close the alert message
4) move mouse around
Result: mousedown seems to be performed at the position where you clicked out before the alert came up -- elements on the page get selected when you move the mouse around.
Note: This doesn't happen when tabbing out of the input.
Demo: http://jsfiddle.net/s9sc4/
<body>
Click inside the input and then outside of it.
<input type="text" onblur="alert('Close this alert message and move the mouse around.');" />
TEST TEST TEST
</body>
Reproduced on:
Firefox 28 and 29
Platforms: Windows 7 & 8 and OSX Mavericks (4 different machines).
Using a clean Firefox profile made no difference.
QUESTION:
Is this a bug, or default behavior? Chrome, Safari and IE don't behave like this.
If it's as designed, do I need to do something with preventDefault or cancel bubbling/stop propagation after the alert to stop this behavior?
You can try to add:
window.getSelection().removeAllRanges();
This will solve your issue.
To answer your question: this seems to be a bug of FireFox and needs a workaround. What happens is FireFox messed up the priority of events where focus is set first, prior to onblur. Browsers who don't have the bug will not fire the focus event when onblur occurs.
DEMO
That's interesting. This feels like a bug. I did get around it be calling setTimeout, and then calling alert:
<input ... onblur="setTimeout(function() { alert(...); }, 0);">
Related
Imagine this codepen: https://codepen.io/anon/pen/awoXKv
As you can see, I got an input field inside my a element. (This cannot be changed currently). What I want to do, that when I click the input, the input gets focused and I don't get redirected.
The above snippet does exactly this in Chrome/Firefox. But now, I tested it on IE and am experiencing an issue, that the input only gets focused, if I use double click.
I tried to focus it manually by using this $(e.currentTarget).find('input').focus();, but this didn't help. Som eother StackOverflow thread said, this is because IE lazy loads the events and I have to use a timeout fucntion
setTimeout(function () {
$(e.currentTarget).find('input').focus();
}, 100);
But even this didn't work. How can I focus an input behind an a tag in IE?
Update:
Doesn't seem like a focus problem, because when I use alert($(e.currentTarget).find('input').is(':focus')); it returns true. What else could be the problem here?
I have the following situation:
One selectbox and a tooltip that appears when the user clicks on the box to select an option. To show the tooltip can be easily done with css (select:focus ~ .tooltip) or jquery using the focus() event.
When the user picks something the select box closes and the tooltip dissapears. This can be done with the change() event.
But there is one issue. If the user opens the selectbox and clicks somewhere else on the page, the list closes and in Firefox the blur event is not triggered right away, so the tooltip remains visible. If the user makes the second click outside of the select the blur event triggers and the tooltip dissapears.
Chrome and IE is ok, Firefox is not.
Do somebody know a workaround in Firefox?
thanks,
Istvan
After playing around with this for about half an hour, I'm afraid to say my input would be: no. And for the following reasons:
Firefox doesn't fire the blur event until the second click. This is evident from looking at the dropdown on the select, which remains blue.
Therefore a pure CSS solution would definitely never work
A JavaScript solution would also be next to impossible too, as the first click seems to go nowhere
I've checked this by trying to note body and document clicks, you'll see that neither fire the first time. In fact, neither does the select, so I have on which level that click registers
See my JSFiddle for my workings. Sorry! I guess it's just a FF issue.
$(document).click(function() {
console.log("document");
});
$("body").click(function() {
console.log("body");
});
$("select").click(function(e) {
e.stopPropagation();
console.log("select");
});
Edit: Sorry, posted an old JSFiddle.
This question comes with a bit of background. Please see two other questions I've recently posted that relate:
How to select text in a textbox cross-browser
Infinite loops created in google chrome
Word of warning: it's possible that the second link is a red herring.
Ok so my problem is that I'm trying to have it so when a user first clicks or tabs in to a textbox, all the text should become selected. If the textbox has focus, subsequent clicks on the text inside the textbox should behave normally (ie. doesn't re-select all the text). The answer I choose in the first link above is the one I found worked across all browsers. Code posted below for your convenience:
$('input[type="text"]').live('focus', function (event) {
var inp = this;
setTimeout(function () {
inp.select();
}, 1);
event.stopPropagation();
event.preventDefault();
return false;
});
Now my second link above is what I seem to be running in to with this approach. It seems that intermittently, google chrome gets stuck somewhere and starts changing the focus between textboxes really fast. You can see what I think is happening here: http://jsfiddle.net/ajbeaven/XppG9/14/
Like I said, it seems to be an intermittent problem so you might have to try reloading the page a couple of times in order to see what I think might be causing the changing of focus. Remember, it only seems to happen in chrome.
Thanks to anyone who can shed some light!
Put any additional work in the setTimeout function. And add a clearTimeout() before you setTimeout():
var focusTimeout = 0;
$('input[type="text"]').live('focus', function(event) {
var inp = this;
clearTimeout(focusTimeout);
focusTimeout = setTimeout(function() {
$('#message-container').html($('#message-container').html() + "*\u200b");
inp.select();
}, 1);
});
http://jsfiddle.net/XppG9/19/
In Chrome, writing the html to the page is (apparantly) causing the field to lose focus, and select() is causing it to receive focus 1ms later, thus triggering the focus event and causing the infinite loop. Moving the write html call into the function that selects the text seems to do the trick.
Oh man, I just figured it out. This bug probably won't happen to you on a real website. It's happening because you are updating the DOM adding a "*" to the message div. When you do this, it pushes the content of the page down. This moves the top text box to where the mouse is, and the mouseup event is triggered on the top text box, causing both text boxes to fire a setTimeout and getting in an infinite loop. Total dibs on reporting this.
edit: it's probably not the mouseup event. looks like chrome thinks you are legit focusing on both. Here's the bug test case for Chrome: http://jsfiddle.net/delvarworld/AnBE8/
edit2: This happens in Safari too. Most likely a webkit issue.
tldr simple workaround is to not update the dom in a way that causes reflow on the focus event, as in get rid of the html() line
You could also try:
$('input[type="text"]').live('mouseup', function (event) {
Which works in Chrome for me
How do you programmatically select the text of an input field on iOS devices, e.g. iPhone, iPad running mobile Safari?
Normally it is sufficient to call the .select() function on the <input ... /> element, but this does not work on those devices. The cursor is simply left at the end of the existing entry with no selection made.
input.setSelectionRange(0, 9999);
https://developer.mozilla.org/en/DOM/Input.select
Nothing in this thread worked for me, here's what works on my iPad:
// t is the input field
setTimeout(function() {
t.setSelectionRange(0, 9999);
}, 1);
See this fiddle: (enter some text in the input box and click 'select text')
It is selecting text in an inputbox on my iPod (5th gen iOS6.0.1), opening the keyboard and also showing the Cut/Copy/Suggest... menu
Using plain javascript. Did not try this with jQuery
document.getElementById("p1").selectionStart = 0
document.getElementById("p1").selectionEnd = 999
Note that the number 999 is just a sample. You should set these numbers to the number of characters you want to select.
UPDATE:
iPod5 - iOS6.0.1 - Working ok.
iPad1 - iOS5.1.1 - Only text selected. Tap selection once to open Cut/Copy menu
iPad2 - iOS4.3.3 - Only text selected. Tap selection once to open Cut/Copy menu
For the last two, you might experiment by triggering a click event on the input element
UPDATE: (07-10-2013)
iPod5 - iOS7.0.2 - Using the fiddle in the link: Can't see typed text in input box.
Pressing select redirects me to facebook.com (??? wtf ???)
no idea what's going on there.
UPDATE: (14-11-2013)
iOS 7.0.3 : Thanks to the comment from binki update that the
.selectionStart and .selectionEnd does work.
UPDATE: (15-01-2015)
iOS 8.x.x : Thanks to the comment from Michael Siebert. Taken from the comment:
I had to listen for both focus AND click events and then setTimeout/_.debounce
to make it work in both cases: click the input or focus through tabbing
It's hard to prove a negative, but my research suggests this is a bug in Mobile Safari.
Note that focus() works, more or less—though it can require more than one tap to succeed, and it's not necessary if you're trying to respond to a user tap on the field in question as the tap itself will give the field focus. Unfortunately, select() is simply non-functional in Mobile Safari.
Your best bet may be a bug report with Apple.
Sorry, in my earlier post, I didn't notice the Javascript implying that you wanted an answer in Javascript.
To get what you want in UIWebView with javascript, I have managed to scrape together two important pieces of info to get it to work. Not sure about the mobile browser.
element.setSelectionRange(0,9999); does what we want
mouseUp event is undoing the selection
Thus (using Prototype):
input.observe('focus', function() {
this.setSelectionRange(0, 9999);
});
input.observe('mouseup', function(event) {
event.stop();
});
does the trick.
Matt
It looks like focus will work but only when directly called from a native event. calling focus using something like SetTimeout does not appear call up the keyboard. Control of the ios keyboard is very poor. Its not a good situation.
I went nuts looking for this solution, while all your responses did help it opened another can of worms for me.
The client wanted the user to be able to click and select all, and also let the user 'tab' and select all on the iPad (with an external keyboard. I know, crazy...)
My solution to this problem was, rearrange the events. First Focus, then Click, then touchstart.
$('#myFUBARid').on('focus click touchstart', function(e){
$(this).get(0).setSelectionRange(0,9999);
//$(this).css("color", "blue");
e.preventDefault();
});
I hope this helps someone, as you lot have helped me countless times.
Something like the following is working for me for me on Webkit that comes with Android 2.2:
function trySelect(el) {
setTimeout(function() {
try {
el.select();
} catch (e) {
}
}, 0);
}
See Chromium Issue 32865.
With iOS 7 on iPad the only way that I was able to make this work was to use actually <textarea></textarea> instead of <input> field.
e.g.
<textarea onclick="this.setSelectionRange(0, 9999);">My text will be selected when textarea is clicked.</textarea>
How to prevent user from changing text inside area was more difficult, since is you make textarea readonly the selection trick won't work anymore.
If you are using HTML5-compliant browsers, you can use placeholder="xxx" in your input tag.
That should do the job.
It might be a beginner question but I can't understand why the onchange event is never called by IE while it works Ok with Firefox.
<input type="text" id="mytext" size="48" value="" onchange="execute()"/>
<button type="button" onclick="execute()">Go</button>
The execute function is called when the button is clicked but not when the text in the input box is changed.
Any idea?
IE only fires the onchange event when the element loses focus - if you were to click outside the element or tab to a different element it should fire then.
You can get around this by using a different event, for example onkeypress.
While annoying, it is not a bug that onchange is not fired until the element loses focus. (I get around the issue by having multiple bindings for different events; make sure not to clobber a handler and use an update aggregation if appropriate.)
Here is the "official" W3C documentation on the subject:
The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus. This attribute applies to the following elements: INPUT, SELECT, and TEXTAREA.
Here is the MSDN reference:
This event is fired when the contents are committed and not while the value is changing. For example, on a text box, this event is not fired while the user is typing, but rather [it is fired] when the user commits the change by leaving the text box that has focus.
The behavior, while often annoying, is as specified.
As answered elsewhere, IE doesn't fire the event till you click outside the input field.
Just a quick expaination of how I fixed it with jQuery. (This is a translation of my code, so it may contain bugs...)
<input id="somecheck" name="somecheck" value="1" onchange="dosomething();">
...was changed to...
<input id="somecheck" name="somecheck" value="1">
<script language="javascript">
$(document).ready(function() {
$('#somecheck').change(function() { dosomething(); } );
});
</script>
For those new to jQuery you are basically waiting for the page to become fully loaded, then you are adding the event handler 'dosomething' to the input box.
As far as i remember, IE doesn't handle onchange event the same maner as FF.
The event will be fired when the mouse is clicked.
I advise you to use a library to handle events such as jQuery, Dojo, etc..
ohhh, I spent some time on that issue as well months ago.
I came up with this solution for FF/IE onchange
$("input[name*='delivery_method']").bind(($.browser.msie ? "click" : "change"), function() {
//your code here
});
IE does it after your input loses focus, which isn't until you click the button, tab out, or click somewhere else on the screen. Try onclick or one of the other events.