Using jQuery, the following is not working in FF, but it is in IE
$(this).focus().select();
I looked around for this and found that you could use a timeout to get around this, but that is not something I want to do if I can avoid it. Does anyone know another way to do this and have it work in FF?
Metropolis
I've run into this before as well. I believe that the setTimeout() solution is the only way this will work in Firefox. The issue has to do with order of events processing, if I remember correctly: IE immediately changes control focus when the focus() method is invoked, but Firefox handles it by adding a focus event to the event queue, which doesn't resolve until after the current event processing has completed. The setTimeout() trick works because it adds the remainder of your code to another event to the event queue after the focus change event, causing it to resolve before your code continues processing.
Please try this code
setTimeout(function()
{
$(Selecter).focus();
}, 0);
i used
$('input').focus().select();
on
<input type="text" value="Some text" />
and it worked in firefox. maybe I dont understand what your problem exactly is.
A solution to this that I just found is to use the below code.
[elementHere].setSelectionRange(0, [elementHere].value.length);
According to the Mozilla Developer Network documentation, this selects the text but does not focus it. At least for me, this prevented issues with selecting text inside a focus event handler, since selecting the text does not cause the element containing it to be focused again.
Related
I've noticed a rather odd behavior when running a unit test which passed on PhantomJS but occasionally failed in Chrome, Firefox and IE. In a nutshell:
I set a focus listener for a DOM element.
I invoked element.focus(), yet the listener was not run.
Calling element.focus() for a second time actually ran the listener.
Unfortunately I couldn't reproduce this issue in a fiddle, but it can be done, for instance, in jQuery's website. I do the following steps on Chrome:
Open www.jquery.com and then open DevTools.
Run $("input[name=s]").on("focus", () => console.log("a"));.
Run $("input[name=s]").focus();. No output is generated.
Run $("input[name=s]").focus();. Now "a" is printed to the console for the first time!
What is causing this issue and how could I work around it?
Had a quick delve around the jquery source code, and it seems that focus actually uses focusin, and the code is trying to map to focusin. so if you try this:
$("input[name=s]").on("focusin", () => console.log("a"));
$("input[name=s]").focusin();
it will work. There is a difference between focus and focusin around bubbling:
http://api.jquery.com/focusin/
The focusin event is sent to an element when it, or any element inside
of it, gains focus. This is distinct from the focus event in that it
supports detecting the focus event on parent elements (in other words,
it supports event bubbling).
It seems like the behaviour is a hard to replicate bug, that must be caused by other bit of code somewhere (maybe a lib). Although the code above should help work around it.
I am trying to optimize the combobox code because I have some latency in my project due to the fact that I create four input boxes in a row. I have some improvement using appendChild() instead of insertAfter() in this jFiddle. But I get strange behavior when I click in the dropdown arrow on the right of each input field.
Question: Why is that happening? or What exactly is happening? Can someone point out how to solve this issue?
Update#1: My explanation and question implie that I have already tried the original code and as is slow I want to optimize it!
Update#2: After a short profiling with Chrome Developer Tools I think I may have resolved this issue. Although the original question is still on.
I took three tests:
Using insertAfter(). Picture#1 Picture#2
Using insertAfter() and removing $.Widget.prototype.destroy.call(this); in _destroy() function. Picture#3
Using appendChild() and removing $.Widget.prototype.destroy.call(this); in _destroy() function. Picture#4
Comments on tests:
It seems that some event triggering is happening. Due to $.Widget.prototype.destroy.call(this); call from _destroy() function, I have multiple $.widget._destroy() calls which leads to ~25% of usage. See Picture#2. Behavior of comboboxes as excepted.
It seems that removing $.Widget.prototype.destroy.call(this); from the code removes this event triggering. I don't see latency issues anymore. Behavior as excepted.
It seems that removing $.Widget.prototype.destroy.call(this); from the code removes this event triggering. I don't see latency issues anymore. Behavior not as excepted. Same behavior as stated in the explanation above.
Since I'm creating a HTA code I'm stuck with IE :(
We needed to trap the change event in a <select> element, but guess what, IE does not support that event.
So I created a way to mimic it. With a <input type="text"> that when it is being click show the <select> just below. That part works fine. The problem is, I want to hide the select when the user click outside the select.
I tried to catch a click on the body, it works fine the first time but the second time the select gets hidden try away.
Here a simplify version of the code:
$('.product').live('click',function(){
// Show the <select id="select"> code goes here
// this is the event to close the select
$('body').die().live('click', function(){ $('#select').fadeOut(250); return;});
// get the click on the select element
$('#select').die().live('click',function(){
// kill the close the select
// THIS IS THE .die() THAT DOES NOT WORK
$('body').die();
});
Question
Is there something wrong with this code? OR is there a better way to do this? Remember I'm stuck with IE.
Internet Explorer 7 and up (and probably 6, since IE7 is mostly IE6 with lipstick, but I can't test that easily) do support the change event. Here is a jsfiddle with a really simple demo.
It's definitely true that IE does weird things with events. For example, "change" won't bubble (from <select> at least, and probably other things), but jQuery patches over that for you. Also there's the classic issue with checkboxes and radio buttons, which don't fire "change" until they lose focus (which makes it basically useless). For those, I find that "click" works fine.
In order for .die() to function correctly, the selector used with it must match exactly the selector initially used with .live().
I have taken a look around Stack Overflow on the topic of onblur but so far have not been able to locate an approach to solve what I want to do.
What I have is a simple two column tables with an unknown number of rows. Rows are created at render time based on the number of boxes being shipped. Each column has the following name and id for the input box:
For column 1: shipItems[ rowNum ].barcode
For column 2: shipItems[ rowNum ].trackingcode
Pretty straight forward. What I want to do is validate the trackingcode and if in error alert the user and re-focus the cursor on the column/row that caused the problem. Users will be using a scanner to scan in the information.
Every things works except that I can not get the cursor to go back to the column/input that caused the issue in the onBlur event.
My understanding is that when the onBlur event fires the element is losing focus and thus the focus is being transferred to the new/next element.
I have tried to playing around with the onfocus event, onkeypress events but still have not been successful.
I am open to any ideal to get this done, I have spend way to much time on it as it is. JQuery is not out of the questions or just plan old Javascript.
UPDATE
Here is a link to the script on jsFiddle:
After reviewing your code, best I can tell you are experiencing an unusual bug in jQuery. I have seen some quirky things happen when using focus() (like having to use setTimeout). But, in your case the $(this) is somehow not resolving correctly when calling focus().
At first I thought it was because the id is not following HTML-4 standards, but correcting the id did not help. $(this) still failed to focus, despite the fact it correctly refers to the <input> element. Then I tried identifying the id with jQuery as a string $("'#" + thisId + "'")...still did not work. But, a hard coded id did work...
So, here's how I modified your code and worked around the problem to get it to focus
if( null === $text.match(/\b(1Z ?[0-9A-Z]{3} ?[0-9A-Z]{3} ?[0-9A-Z]{2} ?[0-9A-Z]{4} ?[0-9A-Z]{3} ?[0-9A-Z]|[\dT]\d\d\d ?\d\d\d\d ?\d\d\d)\b/))
{
alert("No Match");
//$(this).focus();//don't use jquery $this
var thisId = $(this).attr('id');//get the id
//use the setTimeout workaround for firefox
setTimeout(function() {
document.getElementById(thisId).focus();//use javascript to set focus
},0);
$(this).css('background-color','Red');
}
Feel free to look at the fiddle (linked above). This approach does correct the focus problem.
I figured out the issue. It turns out that IE and FireFox have very different behavior when it comes to onBlur.
I was calling focus() during the execution of the blur(). since the blur has not completed it either ignored the focus command or executes and then completes the blur.
Some browsers the focus command can cause a blur to be triggered thus creating an infinite loop with the cursor bouncing between the two fields.
Using a timeout will cause the focus to trigger outside of the blur call back function.
Under IE I can make use of onBlur and have no issues, under FF the focus never got called event with a timeout, so it needs an onChange.
I have updated my script - it runs fine on IE - http://jsfiddle.net/boyd4715/3wbtQ/34/
So I have created a Firefox extension and it works great, however when I submitted it (although it was accepted) it came up with one security warning. It said setTimeout() was removed in an else clause.
So, is there a way to listen for any DOM change? (or even a specific element changing, I have an ID for both). However, divs do not have an onChange event so any ideas?
I don't mind if it's ANY change, doesn't have to be div-specific.
DOMSubtreeModified event sound like something you want to use. Keep in mind, that it is deprecated and after some time its support will probably be removed from browsers.
http://help.dottoro.com/ljrmcldi.php
It turns out adding an "onChange" event to a div works fine, although it might not be W3C valid it doesn't really matter as it's only a Firefox extension (plus it works!).