stopPropagation() of MSGestureTap event - javascript

I confused about how propagation of MSGestureTap event works in IE and on Windows Phone. Here is a code example:
First
http://jsfiddle.net/gTLKB/2/
(example tested on desktop IE11 and on Windows Phone 8 IE)
As you can see there are two nested div elements. On both of them I hanged MSGestureTap event listeners using approach described here http://msdn.microsoft.com/en-us/library/ie/dn433243(v=vs.85).aspx.
As you can see there is e.stopPropagation() for MSGestureTap event of inner element. So supposed behavior is next:
User clicks on inner element and see inner click alert message.
MSGestureTap event stop propagate and nothing happens after.
Actual result: MSGestureTap fires for outer element.
The problem will be solved if stopPropagation() for both MSGestureTap and MSPointerDown but in real life I have another element upper in DOM tree which has MSPointerDown listener which should be called, so I can't stopPropagation() for MSPointerDown event.
Second
If you remove e.stopPropagation() for MSGestureTap event for inner element then MSGestureTap listener for outer element will fire twice, which for me looks very odd. Code example:
http://jsfiddle.net/gTLKB/4/
Order of events execution:
inner click
outer click
outer click
Third
In previous example if you will change order in which listeners are hanged on elements the order of event execution will change too. Example:
http://jsfiddle.net/gTLKB/5/
outer click
inner click
outer click
Order of events execution in this particular case should not depend on order in which listeners have been added.
Can someone explain all that? I will be extremely appreciate for any help.

Related

Link within a link onClick event - Avoid both click events triggering

I have a link within a link, both with an onClick event.
The outer link works as desired. However, the inner link triggers both onClick events. I would like it so that the outer event is not triggered when the inner link is clicked.
<div onClick="console.log(1)">
Inner
</div>
JSFiddle
Javascript events will propagate up through the tree.
So when you click on the inner anchor it will also emit any click events for elements higher up, so the div element.
To stop this the inner click handler has to prevent the event from propagating with e.stopPropagation();.
However this gets a little messy when you don't register handlers with .addEventListener() in JavaScript.
If you add events this way you can do it like this (first give your anchor an id, say inner) which is nice and easy:
document.getElementById('inner').addEventListener('click', function (e) {
e.stopPropagation();
console.log(2);
});
You can however pass the event into your click handler if you do wish to use the attribute, so:
Inner
//JS
function innerHandler(e) {
e.stopPropagation();
console.log(2);
}
Generally speaking (this is my opinion) i would avoid the latter. Events registered like this are difficult to remove and modify. You can't also easily register multiple handlers to the same element for the same event.
stopPropagation docs

TransitionEnd listener firing on child elements

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

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.

jQuery triggers out event even though it should be still in

I am facing a rather awkward problem. I register two event handlers, one for mouseenter and one for mouseout for the li elements on the page. It has multiple div areas inside it. When I leave the li element it calls the out handler, which is ok. What is not ok is that the out handler is also triggered when I leave a div inside that li.
Below is an image that illustrates it. The blue area is the li element which I register an enter and out event for.
I tried to register handlers on the inner divs that would stop the propagation but it only results in the triggering of the out handler when I enter those inner divs.
Any idea what is going wrong here?
Use mouseleave instead of mouseout. Mouseout triggers everytime your mouse is going off from exactly atop of the target. So when you enter the divs, your mouse goes out of the li and on the div. But it is still inside the LI of course, using mouseleave will make it work.
From JQuery doc:
The mouseleave event differs from mouseout in the way it handles event
bubbling. If mouseout were used in this example, then when the mouse
pointer moved out of the Inner element, the handler would be
triggered. This is usually undesirable behavior. The mouseleave event,
on the other hand, only triggers its handler when the mouse leaves the
element it is bound to, not a descendant. So in this example, the
handler is triggered when the mouse leaves the Outer element, but not
the Inner element.

prevent browser from generating double click event

I have two overlapping div elements in my web app.
On the underlying div an event is registered on double click.
On the div that lies above the other div a event is registered on click that hides the div.
The problem is that if I double click on the above div element it is hidden after the first click BUT the second click causes the double click event on the underlying div to fire - how can I prevent that?
Mixing "click" and "double-click" is going to be problematic at best. However, in this case things might get better if you just ensure that your handler for the "click" event (the event that hides the element) returns false to the browser.
How to do that depends on how your handler is registered. If it's like this:
<div onclick='hideMe();'>
then you'd change that to
<div onclick='hideMe(); return false'>
If you're using some framework or some other means of attaching the handler, then just having the handler function return false should do it.

Categories