I have a textarea or input, and I change the text, and then click a link or button (without tabbing off the input), only the change event fires, not the click event. I want them both to fire:
Enter some text and then click the link. We want f1 and f2 to appear !
<br />
<input onchange="f1();" value="input text" />
<br />
click me
function f1() {
alert("f1");
return true;
}
function f2() {
alert("f2");
return true;
}
http://jsfiddle.net/paull3876/vrcfherp/3/
I've tried it with jquery and normal js as above, and I've tried setTimeouts inside the functions, I've tried input and textarea, but whatever I do, only f1 fires.
UPDATE 1
So we've established that alerts kill any subsequent events - good. Fiddle
Now the challenge is, how to stack up these events in an object so each event can fire an alert(or confirm, or ...) and NOT block any future events. I'm just trying different ideas. More to come...
UPDATE 2
I wrote some code to stack up the functions and then execute them at the end. Its not beautiful (and it should be wrapped in a class) but it works:
http://jsfiddle.net/paull3876/vrcfherp/9/
This behavior is due to the blocking mode of alert.
Browser will trigger the events one after the another. In this case the priority must be
onChange event of <input>
onClick event of <a>
but when it first executes onChange of input, it encouters alert which blocks rest of the things, hence the event onClick of anchor tag is not triggered.
Check this if you change from alert to console.log
alert() is modal and because input loses focus on other element mousedown, there is no click event fired.
So start using console for debugging purpose.
Related
Looking for an explanation to the answers provided here and here.
Put simply, I have two elements. An input with an onBlur event, and a div with an onClick event. Without any special handling, when I blur the input by clicking the div, the onBlur event is fired, while the onClick event is not.
However, if I put a setTimeout inside the blur event handler, both event handlers are called when I click on the div. Why does this work?
HTML:
<input type="text" name="input" id="input1" />
<div id="div1">Focus the input above and then click me. (Will see 1 alert)</div>
<br/>
<input type="text" name="input" id="input2" />
<div id="div2">Focus the input above and then click me. (Will see 2 alerts)</div>
Javascript:
$(document).ready(function() {
function clickHandler() {
alert('Click!');
}
function blurHandler() {
alert('Blur!');
}
$('#input1').on('blur', function() {
blurHandler();
})
$('#input2').on('blur', function() {
window.setTimeout(blurHandler, 200);
})
$('#div1').on('click', function() {
clickHandler();
})
$('#div2').on('click', function() {
clickHandler();
})
});
Fiddle demo is here.
It happens because the blur event occurs before the click. The alert() method stops the execution of the script and once stopped, the click event will not fire after you dismiss the alert box. Using the setTimeout() method at the blur handler, you are actually allowing the click event to be fired.
i sugest you to listen to mousedown instead of click. The mousedown and blur events occur one after another when you press the mouse button, but click only occurs when you release it.
This is because of the modal nature of alert(). Try using console.log() instead and you will see that both will get called.
the setTimeout will fire the event after the time you defined.. so you'll have more time to click on the text.
in the other hand, the first input doesn't have a time to fire the blur so it's more difficult to fire the click event, but if you click fast enough, you will see two alerts even for the first input.
I am using a simplified example to describe the issue I am facing.
I have the following HTML markup:
<input ng-model="something" style="margin-top:8px;"/>
And, I have two HTML buttons:
<button id='submit'>Save</button>
<button id='btnGetAnalyzerInput'>Generate Analyzer File </button>
I used jQuery's change event on my input (to track whether any changes have been made to the input - by maintaining a simple JS variable).
When the user clicks "Generate Analyzer file button", what I want to is this:
Look up the JS variable to find out whether any changes have been made.
If yes, then prompt the user to save changes (window.dialog)
However, I find that when the focus is still on the input element, and when the button is clicked, the click event runs before the OnChange event. In all other cases, it is the OnChange event which gets fired before the click event (and so my code works as expected).
Is there any way to ensure that for such a scenario, the click event runs after the onChange event?
I am using Google Chrome to test my application.
Note :
Both events work as expected - the OnChange event gets fired when the textbox loses focus.
I can't use the keypress event since I want to track changes.
You could have the click event call the same function as the OnChange event. Something like this:
function OnChange(){
//Do stuff for on change;
}
function ClickEvent(){
OnChange();
//continue with generate stuff
}
You you may need to set up and pass in arguments to the OnChange function, depending on how you are accessing the data you need. If you need more guidance, post more of your code.
I’m running into this issue where a single action by the user is supposed to trigger two events but it only triggers the first one.
The scenario:
A user enters some text into a special field that modifies the layout on focusout , after entering the text, without leaving the field, they click a button.
What’s happening?
I have a focusout event on a text box and click event on a button. What I see is the focusout event gets fired but the click event never does.
I’ve encapsulated this in a jsfiddle:
http://jsfiddle.net/fCz6X/13/
$('#theText').focusout(function (){
$("#focusevent").text("Focusevent");
console.log("focus");
});
$('#theButton').click(function (){
$("#clickevent").text("Clickevent");
console.log("click");
});
So if you click in the text field then click the button I’d expect both events to fire, but we only see the focus out event.
I put in a temporary fix for this by having the mousedown event fire the button instead of a click event (this fires before the focusout event) but that is causing some other behaviors and issues that I don’t want to see. Due to those I think optimal solution is finding a way to get the focusout and click events to both fire. Does anyone have thoughts on how to fix this problem?
Edit: After seeing initial responses I dug a little deeper, the issue here is that the focusout event is changing the page layout which very slightly pushes the location of the button down. The click event triggers after the focusout is done but since the button is no longer in the exact same location, nothing happens.
Here is an updated fiddle that shows my problem
http://jsfiddle.net/fCz6X/11/
It's because you're calling alert - the focusout event fires, but before the browser recognizes you've clicked the button, the alert box blocks it.
Change your event handler to console.log or something else that's non-obtrusive and you'll be ok.
It is the Alert that is blocking.
Some browser security prevents firing too many window.alert at the time.
When trying with other triggers, it looks. You may try console.log()
$('#theText').on("focusout",function (){
$("#theText").val($("#theText").val()+"flb");
});
$('#theButton').on("click",function (){
$("#theText").val($("#theText").val()+"but");
});
I believe this is because the focusout event fires first, executing the handler, and the alert then prevents the browser from recognizing the click.
Try again with console.log instead of alert - it's less invasive.
As Joe said, the blocking alert call is what is breaking the event. Using a non-blocking call you will see both events.
If you really need to perform an alert like this, though, you can defer calling 'alert' until later using setTimeout()
$('#theText').focusout(function (){
setTimeout(function() { // alert after all events have resolved
alert("focus left text box");
}, 0);
});
Edit: In your updated fiddle the reason the click event never fires is because no click event occurs. If you move the button out from under the mouse on mousedown, there is no followup mouseup which is what initiates the 'click' event.
You may need to reconsider other aspects of your design. Your solution of using 'mousedown' is the best you can achieve because it's the only event that actually occurs.
How does IE handle event propagation and is there any way to know which HTML element is currently handling the element?
The problem is something like this.
<div id="someDiv">
<input type="text" id="txtName" onblur="someFunction()">
<img src="/url" id="imgIcon" onclick="someFunction()"/>
</div>
<script>
function someFunction()
{
// Open a popup
}
</script>
Now, when the user enters something in the textbox and clicks on imgIcon, someFunction is called twice and the popup is opened. How should I handle the event here so as to call someFunction() only once i.e. as if it got triggered from only one of the events?
You have called this function on both the event on blur of text box and on click of the image so when you click on the image it lost the focus from text box so event is triggered at the both time so you can check do you need to call it on both event or any of the event?
you can check whether the function is called then do not process further using a boolean variable in javascript but it will not a good solution.
I want to call a function when I have a textfield focused and then unfocus it (whether I press TAB or click elsewhere with the mouse) and I used this code:
$("#settings_view #my_profile_div input").focus(function() {
$(this).blur(function() {
change_my_profile();
});
});
When I first run it (have a field focused then unfocus it) it runs one time as expected. However, the second time it calls the function change_my_profile twice. The third time it ran 3 times and so on.
What is the problem here and how do I solve it? (I tried with 'throw' after change_my_profile and then it only ran one time, but I want to locate the problem anyway).
it is binding a blur event every time a focus event is initiated, that's why you are getting multiple executions
try
$(this).bind("blur",function(){
change_my_profile(this);
})
and then in your change_my_profile function do the following
function change_my_profile(el){
$(el).unbind("blur");
//rest of the change_my_profile code goes here
}
The .focus() and .blur() functions assign handlers to the 'focus' and 'blur' events repsectively. So every time the user focuses the textbox, your code is adding a new event handler to the 'blur' event. What you want is:
$("#settings_view #my_profile_div input").blur(change_my_profile);
You need to remove the event handler after successful execution. Otherwise, you are stacking handler upon handler and they all get triggered. I think in JQuery that is done using unbind()
Your code is asking jQuery to add (append) an onBlur event handler to an input field every time the user enters the field. So, your same event handler function gets appended over and over again. Are you simply trying to trigger a function to run when the user moves out of a field? If that is the case, you can simply use .blur to attach the onBlur handler once.