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
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.
Whenever a blur event is triggered from any input element, I want to set focus to one particular element.
This issue arises when I am trying to focus to the same element triggering the blur event.
Why does this only works, when the element I am trying to focus on to, is not the one triggering the event?
[Issue Illustration]
and explanation as per the fiddle:
The element I am trying to focus to is col0
Unless the element to trigger the blur event is not col0 it works perfect
But when blur is triggered from col0 itself, then $("#col0").focus() does not work.
Q: Why? & What is the workaround/solution?
P.S: I am just trying to know the cause of the behavior and ways to overcome it. Concerns about the usability, is NOT THE QUESTION.
This works in FF for me...
$('input').on('blur', function() {
setTimeout(function () { $("#col0").focus(); }, 0);
});
it is just to postpone a UI action a bit (after processing the blur event is finished).
Warning: in jsfiddle FF won't let you edit the code after you try it, once you get to the input you are stuck there until refresh
Update: The explanation is tricky, as it is a matter of implementation in FF (as Chrome and IE behave as you expected), my guess is that FF prevents firing related events when you are in the event handler for the same element (a thing that may potentially lead to infinite cycle), using setTimeout you are firing the event soon after you leave the handler (and even UI has a chance to redraw itself)
It looks like you're trying to keep focus on everything except the control you're on. Try this:
$('input:not(#idofcontrol)').blur(function() {
$('#idofcontrol').focus();
});
I have a problem with my web application which is designed for iPad.
I use jQuery and jQuery UI for dragging elements on the screen. Because on iPad, the element can not be dragged by default, I added this library:
http://code.google.com/p/jquery-ui-for-ipad-and-iphone/
Including it, I can drag and drop elements on iPad, but also a problem occurs. I have on the draggable element also a div are with an image, which should be clickable.
So I integrate these lines:
$(document).ready(function() {
$(".note").draggable();
$('.closebutton').click(function() {
alert("test");
});
});
The problem is, including the drag-library, the alert message test pops up twice or the screen is frozen.
I created a full working demo here:
http://jsbin.com/oliwo/2/
On normal desktop browsers, like Firefox 4 Beta and Safari, it works, only one test message appears by clicking with the mouse on the x - delete image. On iPad, I get the message twice or the screen froze.
Does anyone can help me? Thank you a lot in advance & Best Regards.
This is not really a response, as i don't known why you have it twice. But you can try a workaround if you're sure your click event is the only click event behavior that should be attached to this button; Make an unbind() just before you're bind, this will remove any previous click binding (so if this is run several times, you'll get only one event):
$('.closebutton').unbind().click(function() { ...
or better:
$('.closebutton').unbind('click').click(function() { ...
I've found that events get fired twice when showing an alert box on a click. I've managed to overcome this problem by using a setTimeout to show the alert box...
$("#myButton").unbind("click").click(function () {
// Have to use a setTimeout else on iPhone the alert may appear twice in certain scenarios
setTimeout(function () { alert('The message'); }, 300);
return false; // Return false to prevent href being followed
});
I do not know why, but if I do not use alert messages, it will work. I create new elements and then it is only called once, on iPad and Desktop Safari.
I'm seeing this issue only on iPad, perhaps some version of webkit related. The unbind worked for me, and I also read this only exists if jquery code is in the body html tag, if its in head it is not an issue.
just simply avoid the propagation of the click
$("tr").live('click',function() {
...
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
});
Because of the issue explained in this question I have a situation where I need to attach the mousewheel event to the drop down list only when it is expanded (I do this in the onclick event). However I need to remove the mousewheel event when the list collapses. How do I go about detecting this?
I can't just use the onchange event because the user may not have actually changed their selection. I've tried the onblur event but in most browsers (except IE) the drop list stays focused when the list is collapsed.
Cheers.
var list = document.getElementById("list");
list.onclick = function (e) {
// attach mousewheel
list.onmousewheel = function (e) {
// ...
}
// attach click off
// This event fires fine in all browsers except FF when the list is expanded.
// In firefox it only fires when anywhere in the document is clicked twice.
// The first click closes the drop down list as expected and the second one
// fires the event.
window.document.onclick = function (e) {
list.onmousewheel = null;
window.document.onclick = null
}
};
EDIT:
Unfortunately meder's solution doesnt work in firefox. The click event on the document doesn't get fired until i click twice off the drop down list. How do I get around that? It works fine in IE.
EDIT2:
I've done some more testing and the following browsers behave as expected
IE 7,
Chrome 3
Opera 10
Firefox requires 2 clicks in the window to make it work & Safari doesn't work at all.
It appears that even when you click off the drop down list firefox maintains focus on it. It's not until the second click occurs that the drop down list eventually loses it's focus.
Are you looking for something like this? If the user clicks anywhere that's not within #el, it will branch out and you can do what you want, though this requires jQuery but it would take far too many lines of DOM Scripting.
var dropdown = $('#el');
$(document).click(function(e){
if ( (!$(e.target).is(dropdown)) || !$(e.target).closest('#el').length ) {
// do what you need to
}
});
If not, can you be more specific and include an example?
PS - I did not test the snippet, sorry if it isn't what you want.
OK, I still have no idea what you're trying to achieve with such a tightly-scripted select box, but in general trying to change the internal working of a native <select> isn't fruitful. There's no standard that says how events flow internally to the form element, and browsers that implement select as an OS-level widget (IE) can't do much to support it anyway.
If you must have this behaviour, I'd suggest using scripting to replace the <select> box on-fly with a JavaScript-powered analogue made out of <div>s. Then you can control exactly how each mouse and keyboard interaction behaves. There are many libraries that do this already, though again if you need to be very specific about the exact behaviour they might not suit you.