TransitionEnd listener firing on child elements - javascript

I added a transitionend event listener to a div. This div has children who have transition on some elements. I want the transitionend event to only fire for the element I added it for, is this a bug? or expected behavior? How to make it fire only if its the one i added the listener to?

Events are bubbling by default,
meaning that they will be "transmitted" to the parent element until they hit the body or a handler that will stop them.
You can either :
Filter by the event's target being sure it's the element you're targetting.
Listening to the event on children and event.stopPropagation() on them. That way, they won't bubble through the parent anymore.
If you'd show us some code, it would be easier to help you, depending on your current implementation.

This process is called as Event Bubbling.The thing you can do is either detect the bubbling using the event handler or prevent the bubbling by stopping the propogation. You can do this by
event.stopPropagation()
In IE beofore 9.
You can do it as
window.event.cancelBubble = true;
Please have a detailed look here

Related

Need to get info from any element, which was clicked, but not from parent elements

Need to get info from any element, which was clicked.
Example:
<div>text1<section>text2</section></div>
and JS
$(function(){
$('body *').click(function(){
alert($(this).get(0).tagName.toLowerCase());
});
});
If I click text2, parent element throw alert too. I need only first alert from section. How I can block next alerts from all parent elements of section.
Use event.stopPropagation() to prevent the event from firing on the containing elements.
$(function(){
$('body *').click(function(e){
e.stopPropagation();
alert($(this).get(0).tagName.toLowerCase());
});
});
Just wanted to expand on Kooilnc answer - Using on with event delegation is another option.
Event delegation would be nice if you have an event listener bound before or after on a node that needs to listen to a click handler that has bubbled up. If you stopPropagation, this obviously would be an issue.
Here's a fiddle with a demo:
http://jsfiddle.net/ahgtLjbn/
Let's say a buddy of yours has bound an event listener to a node higher up in the DOM tree. He expects any events that bubble up to it, to be handled by his script.
Using event delegation, the event still bubbles up (so your buddies code will still fire), but it will only alert once (since we called e.stopPropagation).
Calling on without event delegation, or binding the event directly using click (which, under the hood, is just calling on) will prevent the event from bubbling, so your buddies code will never run.

How do I make it so that if I click an <a> element it goes to the link, but it doesn't trigger the .click() event of its parent element?

I want to be able to click on a particular <a> and activate the link out, but not the parent's click.
preventDefault() doesn't work because then it won't link out.
You should use e.stopPropagation() to stop the event from bubbling.
Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
~from jQuery docs .stopPropagation
You have to use stopPropagation instead of preventDefault
$('a').click(event){
event.stopPropagation();
});

Direct vs delegation and bubbling vs capturing in jQuery

HTML
<div>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
jQuery
$('div span').on('click', function(){
//direct - 1st method
});
$('div').on('click','span', function(){
//delegation - 2nd method
});
I have used both above method in my code. I know second method is better due to it has only got single handler. My problems are:
Is first method (direct) refers to the concept called event capturing? Is it an example for event capturing?
Is second method (delegation) refers to the concept called event bubbling? Is it an example for event bubbling?
It appears as though All jQuery event methods use Event Bubbling, not Event Capturing.
Therefore, both of your examples will use Event Bubbling.
There is an edge case with focus and blur events not bubbling in some browsers. In the affected browsers, Event Capturing is used for focus and blur events.
For reference, you can simply view the source. http://code.jquery.com/jquery.js
$('div span').on('click', function(){
//direct - 1st method
});
This event only attached the event handler to the spans inside Div that are currently present in the DOM.. i.e; if a new span element is added to the div , that span will not have a click event associated with it..
The first and second one are example's of Event Bubbling
There comes the concept of Event delegation where in the ancestor is given the event handler and it is delegated to the children..
The second example is an example of event delegation .
Wherein event is attached to the parent element..So all the span element's inside the div class are attached to the event handler ..
So if a new span element is added to the div , becoz the event is associated with the span's ancestor the event will fire in this case
This helps in cases
$('div').on('click','span', function(){
//delegation - 2nd method
});
I have no idea where event capturing is used in the jQuery library
Answers to your questions:
This isn't bubbling, capturing, or delegating. It's just adding an event listener directly to an element.
Yep, this is delegation that under the hood relies on clicks bubbling up.
Event bubbling and capturing are different implementations of the same concept, brought to you by Microsoft and Netscape, respectively. Both listening for events on parent elements. Note that they occur in a different order: capturing happens from the parent down to descendent, whereas bubbling happens the other way around.
More details and its history on PPK's website: http://www.quirksmode.org/js/events_order.html
Modern browsers support both capture and bubbling (bubbling is the default now), and you can specify which one you want to use when you use the native addEventListener:
element.addEventListener('click', function(){}, false); // bubble
element.addEventListener('click', function(){}, true); // capture
However, some events, such as focus, blur, scroll, mouseover, etc only are supported through capture phase events, so you MUST specify "true" when you use addEventListener.
Unfortunately, it looks like jQuery doesn't support delegation for all capture phase events, only focus and blur (see https://github.com/jquery/jquery/blob/ad032d3c7df04827989a4187117614c29bf3a4ad/src/event.js#L728).
The short answer: for delegation of capture-phase events other than focus and blur, you need to use the native addEventListener, not jQuery.

how to work with stopPropagation

I have element with stopPropagation, but within that element I have another element which I need to be able to use for event. But because it's child element of the one with stopPropagation. It's not working. Is there some way to enable propagation on element within element with stoped Propagation.
Thank you...
Can't you simply trigger the event programmatically on the other element?
$('#firstElement').click(function(e){
e.stopPropagation();
$('#anotherElement').trigger("click");
});
By default many events bubble up the DOM, so the click handler you have will obviously affect parent elements - it seems like you'd have an easier time using e.preventDefault() rather than e.stopPropagation()
See http://css-tricks.com/return-false-and-prevent-default/ for a great explaination on the differences

event.stopPropagation stops propagation of live events, although it should not

The documentation for says that event.stopPropagation shouldn't stop propagation of live events (http://api.jquery.com/event.stopPropagation). However it works just the opposite for me. Try this: http://jsfiddle.net/PSYg8. Clicking on the red Div should fire the live event attached to the html element.
What the documentation is telling you is that it is not possible to call stopPropagation from a live handler.
Because jQuery implements live events by listening to all events that propagate up to the <html> element and then seeing if the firing element matches your original selector, stopping propagation from a regular event handler on an element prevents the event from ever reaching the live handler.
Edit: If you're not clear on how DOM events and event propagation works, QuirksMode has a wonderful analysis of the capturing and bubbling models, and Microsoft has a great page that lets you visualize how event propagation works in the W3C, classic, and IE models.
You're swapping the items. Inside .live, you cannot use stopPropagation. So for example this does generate two alerts: http://jsfiddle.net/PSYg8/1/.
$(document).ready(function(){
$('html').live('click', function(){
alert('html');
event.stopPropagation();
});
$('div').click(function(event){
alert('div');
});
});
Inside .click (.bind), stopPropagation works seamlessly. It just stops the div event from bubbling up to the html element.
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events
Meaning
$('html').live('click', function(e){
e.stopPropagation(); // does nothing
alert('html');
});
You misinterpreted the documentation. When you stop propagation on the click event it does not bubble upto the live event.

Categories