Having this sample code:
<input type="text" id="changeid">
click
<script>
$('#clickb').on("click", function(event){
alert(1);
return false;
});
$('#changeid').on("change", function(event){
alert(2);
return false;
});
</script>
When putting something into the text field and click the link immediately, only onchange event fires, but not link click event.
Why is that?
It seems that the change event is blocking the click event?
It is blocked by alert. Change alert to console.log you will find two events all fired.
The demo.
$('#clickb').on("click", function(event){
console.log(1);
return false;
});
$('#changeid').on("change", function(event){
console.log(2);
return false;
});
When you edit the input and then click on the link the following happens on the inside
You start clicking on the 'link'. No events are generated yet (not even mousedown), because first the browser will do some cleanup work:
The input loses focus and will raise a blur event
The input raises a change event, since it raised a blur and the value changed
Your change event callback opens an alert(2)
The documents loses focus since a new window appeared
The link will never experience the click.
The solution is not to use alert (as xdazz proposed).
use this
$("#changeid").live('change', function () ...
onchange event fires only after the element is blurred. So when u type some text and click on the link first the element is blurred on the text field. The best way to handle the change event on having onkeyup event to track the changes made on the text field.
Related
I have the blur event event on a text field
$(document).on('blur', '#inputEmail', function(event){
// logic here
});
When I put some text in the field click and drag on a draggable element using jQuery draggable, the event does not execute when I drop the element.
How can I fix this? It's kind of annoying.
Thanks in advance
If you want to keep the blur event, it might be a good idea to use the tradition event delegation approach. Listen for the blur event on your input with an id of inputEmail.
$("#inputEmail").on("blur", function(event) {
alert('hi');
});
http://jsfiddle.net/1qyhjshu/1
Edit: It looks like your first example worked for me as well.
http://jsfiddle.net/vbdxwt9b/
If you want to make hit on the button only after executing the code in blur event.You may hide the button and show he button after executing the blur function.
$("#inputEmail").blur( function(event) {
//code here
$("#btn").show();
});
i have:
<input type="text" />
and
$('input').blur(function(){
alert('stay focused!');
});
I want to prevent the blur function running when I'm "blurring" by clicking on an anchor element.
I.E. if i tab to another input, click somewhere on the page etc i want the blur to fire, but if i click a link, I don't want it to fire.
Is this easily achievable, or do i need to hack about with delegates and semaphores?
Thanks
I had to solve this problem myself today, too. I found that the mousedown event fires before the blur event, so all you need to do is set a variable that indicates that a mousedown event occurred first, and then manage your blur event appropriately if so.
var mousedownHappened = false;
$('input').blur(function() {
if(mousedownHappened) // cancel the blur event
{
alert('stay focused!');
$('input').focus();
mousedownHappened = false;
}
else // blur event is okay
{
// Do stuff...
}
});
$('a').mousedown(function() {
mousedownHappened = true;
});
Hope this helps you!!
If you want to keep the cursor at its position in a contenteditable element, simply:
$('button').mousedown(function(){return false;});
Delay the blur a bit. If the viewer clicks a link to another page, the page should change before this code gets a chance to run:
$('input').blur(function(){
setTimeout(function() {alert('stay focused!');}, 1000);
});
You can experiment with what delay value for the timeout seems appropriate.
You can get this behavior by calling preventDefault() in the mousedown event of the control being clicked (that would otherwise take focus). For example:
btn.addEventListener('mousedown', function (event) {
event.preventDefault()
})
btn.addEventListener('click', function(ev) {
input.value += '#'
input.setSelectionRange(ta.value.length, ta.value.length)
})
See live example here.
Some clarification that was too long to put in a comment.
The click event represents both pressing the mouse button down, AND releasing it on a particular element.
The blur event fires when an element loses focus, and an element can lose focus when the user "clicks" off of the element. But notice the behavior. An element gets blurred as soon as you press your mouse DOWN. You don't have to release.
That is the reason why blur gets fired before click.
A solution, depending on your circumstances, is to call preventDefault on mousedown and touchstart events. These events always (I can't find concrete documentation on this, but articles/SO posts/testing seem to confirm this) fire before blur.
This is the basis of Jens Jensen's answer.
is it possible to trigger a function after an autofocus? I tried but when my textarea get the autofocus i need to click away then to click again on my textarea to trigger the function
my code is :
$('#test').focus();
$('#test').focus(function() {
alert('ok');
});
Try swapping the code around. You're event wasn't attached to the test element the first time you call focus()
$('#test').focus(function() {
alert('ok');
});
$('#test').focus();
This is because you are setting the trigger after you set the focus.
Rearrange your code and this will work fine.
The .focus() method has two different meanings based on the parameters it is passed.
In your first statement.
$('#test').focus();
This is setting the focus to the element with ID test.
Your second statement though
$('#test').focus(function() {
alert('ok');
});
What is happening here is jQuery is attaching an event handler to the focus event of the element. I suggest adding your event handlers when the DOM is loaded, then calling the .focus() event when required (which will trigger the alert).
$(function(){
$('#test').focus(function() {
alert('ok');
});
});
I wrote this snippet of javascript/jQuery to change a check box.
http://jsfiddle.net/johnhoffman/crF93/
Javascript
$(function() {
$("a").click(function() {
if ($("input[type='checkbox']").attr('checked') == "checked")
$("input[type='checkbox']").removeAttr('checked');
else
$("input[type='checkbox']").attr('checked', 'checked');
return false;
});
$("input[type='checkbox']").change(function(){
console.log("Checkbox changed.");
});
});
HTML
<input type="checkbox" />
Change CheckBox
Interestingly, clicking the link alters the text box, but does not trigger the form change event that calls the function that logs a message in Chrome Web Developer Console. Why? How do I make it do that?
You need to trigger the change event, .trigger('change'), so that event knows that a change took place.
From http://api.jquery.com/change/:
Description: Bind an event handler to the "change" JavaScript event, or trigger that event on an element.
This method is a shortcut for .on( "change", handler ) in the first two variations, and .trigger( "change" ) in the third.
The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.
Demo:
http://jsfiddle.net/nPkPw/3/
Using chaining: http://jsfiddle.net/nPkPw/5/
i.e. $("input[type='checkbox']").trigger('change').attr('checked', 'checked');
This isn't surprising, but I guess you could as this to the list of non-effect in the msdn.
"This event is fired when the contents are committed and not while
the value is changing."
"The onchange event does not fire when the
selected option of the select object is changed programmatically."
You could always just .click() it jsFiddle
I'm making an edit button which pops up a modal box with a form to edit it. jQuery then sends this form to my server and I get a JSON response back. However, due to my bubbling issue, if I click on, for example, all of the edit buttons and then click on the last one and change a field, it does it across all of them.
$('.edit').click(function(event){
//more code...
modal_submit(the_id);
event.stopPropagation();
});
and then the submit event:
function modal_submit(the_id){
$('#modal form').submit(function(){
//This will alert every time I have EVER clicked on an edit button
alert(the_id);
return false;
});
}
finally all of this is inside of a getScript:
$.getScript('js/edit.js',function(){
create_edit_btn();
});
I've only used this 1 other time, and it worked, but I also had to do this.event.stopPropagation, but if I do "this" now it says this.event is undefined, but like I said, this exact code worked before for another script I did.
Does anyone have any ideas? :\
EDIT:
the html is:
<li>
<input id="item1" type="checkbox" value="webhosting|15" title="Web Hosting">
<p>Hosting for your web site</p>
</li>
An event can have multiple event listeners. Each time you use $(element).submit(whateverFunction) you are adding another whateverFunction to the submit event. If you only want only the last listener to be the action that is taken upon envoking the event, try doing this:
function modal_submit(the_id){
$('#modal form').unbind(); // this will remove all other event listeners from this element
$('#modal form').submit(function(){
//This will alert every time I have EVER clicked on an edit button
alert(the_id);
return false;
});
I think you event.stoppropagation does its job already. It stopped all the bubbling on the click event of the button (ie, if you try checking the document body, it won't have mouse click event anymore). The reason why codes within submit of the form is still executed, is because this is called by the button's default action.
Together with event.stoppropagation(), I suggest you include this:
event.preventDefault();
So that the default action will not used and only the codes within your handler is executed.
Is this in the function that creates edit buttons?
$('.edit').click(function(event){
//more code...
modal_submit(the_id);
event.stopPropagation();
});
If it this, then it will add this handler multiple times to the same elements, causing a flurry of alerts. Use live, which will place the handler on every matched element, even if is is added later in execution.