Span Child Object on Click - javascript

How can I get this code to only execute its button:
​<span id="spanClicker">
<span id="subClicker">
[Click Me]
</span>
​</span>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
like this fiddle: http://jsfiddle.net/rpCVy/

http://jsfiddle.net/malet/rpCVy/3/
You can use e.stopPropagation() to prevent the click event firing for both elements.
Also on a side note the .live function is deprecated as of jQuery 1.7 .on should be used instead.

Here is what you're looking for:
$( '#subClicker' ).on( 'click', function (e) {
alert( 'subClicker' )
// Now here is the magic you want:
e.stopPropagation( )
} )
As you can guess, e.stopPropagation() allows you to prevent the event from propagating to its parent elements.

This ought to do it.
http://jsfiddle.net/rpCVy/2/
New javascript
$(function()
{
$("#spanClicker").live("click",function()
{
alert('Span Clicked');
});
$("#subClicker").live("click",function(e)
{
alert('Button Clicked');
e.stopPropagation();
});
});​
The anonymous function associated with .click can take an event for the first argument. Call the stopPropagation() method of the event object to stop the click event from bubbling up to containers of the target element of the event.

Related

Stop links from executing with JavaScript

I can stop normal inks from working with this:
$('#container a').click(function(event) {
return false;
});
However my site has existing javascript that fires when a link is clicked. The code above doenst stop these from firing.
You may unbind click and stopPropagation
$('#container a').unbind('click').click(function(event) {
event.stopPropagation();
//event.preventDefault();
return false;
});
if the other click events are bound with jquery, as long as this event is bound after those you should be able to do:
$('#container a').off('click').on('click', function(event) {
return false;
});
the .off will remove previously bound click event before binding the new
one
(off is unbind for events added with on)
You can unbind event from selected elements http://api.jquery.com/unbind/
$('#container a').unbind("click");
You need to use event.stopImmediatePropagation() and .off() it removes event handlers.
Keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.
$('#container a').off('click').on('click', function(event) {
event.stopImmediatePropagation();
event.stopPropagation();
});
A bit of an aside, but this can also be done with CSS
pointer-events: none

Using .on() and e.stopPropagation() on dynamic elements

I have been experimenting with capturing click events outside of elements using stopPropagation().
$(".container").children().on('click',function(e){
e.stopPropagation();
});
$(".container").on("click",function(){
alert("outside the box?");
})​
Here is a jsFiddle set up to demonstrate it functioning. An alert should fire when you click anywhere outside of the white box.
Now, I am trying to have the same principle applied to dynamically created elements. As far as I understand, the on() method of event assignment in jQuery should allow this to function without changing the script.
Here is a second jsFiddle where you must first click a link to create the elements. Once you have done this, the theory is that the same script will work, but it does not. What am I missing about this method?
When the item is added dynamically, you should attach the handler to the closest parent that will surely be there - in your case this is body. You can use on() this way to achieve a functionality that delegate() used to offer:
$(selector-for-parent).on(events, selector-for-dynamic-children, handler);
So your code rewritten would simply be this:
$("body").on('click', '.container', function(e){
var $target = $(e.target);
if ($target.hasClass('container')) {
alert("outside the box!");
}
});
I used e.target to find which element actually triggered the event. In this case, I identify the item by checking whether it has the container class.
jsFiddle Demo
In short word you need to put on() on existing parent element to make it works:
$('body').on('click', 'a', function(e){
e.preventDefault();
$('<div class="container"><div class="box"></div></div>').appendTo('body');
$(this).remove();
});
$('body').on('click', '.container > *', function(e){
e.stopPropagation();
});
$('body').on('click', '.container', function(){
alert("outside the box?");
})​
Code: http://jsfiddle.net/GsLtN/5/
For more detail check '.on()' on official site at section 'Direct and delegated events'
The demo.
When you bind a event handler to a element use .on, the target you bind to must exist in the domcument.
$('body').on('click', '.container > *', function(e){
e.stopPropagation();
});
$('body').on("click",'.container',function(){
alert("outside the box?");
})​
You need to bind the .on() to a parent.
What you're trying to do is - bind the handler to a parent that listens for an event, then checks whether the event was triggered by an element that matches that selector.
$("body").on("click", '.container',function(){
alert("outside the box?");
})​
Updated fiddle here
According to the documentation for jQuery.on():
Event handlers are bound only to the currently selected elements; they
must exist on the page at the time your code makes the call to .on().
You will have to bind the event to a parent container. Perhaps something like THIS.

why does this on() trigger right away instead of just binding?

Im having some problems with .on() and how to use it instead of .bind() in this situation.
What im trying to do here is i click a link and that is supose to bind another click event, but instead it triggers that event right away. I looked in the documentation/jquery.js file and this is how im suppose to do it.
Demo: http://jsfiddle.net/bNaFV/
$('#click_me').on('click', function(){
$('#show_me').addClass('remain');
//this is only suppose to bind that next time i click anywhere on the document it should hide
// not right away
$(document).on('click', 'html', function(){
$('#show_me').hide();
});
});
$("#click_me").hover(
function () {
$('#show_me').show();
},
function () {
if ($('#show_me').hasClass('remain')){
return;
} else {
$('#show_me').hide();
}
}
);
click me<br /><br />
<div id="show_me"></div>​
You need to stop the propagation of the event:
$('#click_me').on('click', function(e){
e.stopPropagation(); //Stop the event from bubbling further
$('#show_me').addClass('remain');
$(document).on('click', 'html', function(){
$('#show_me').hide();
});
});
This is because the event has been captured at the #click_me element. You then bind an event handler for that same event type somewhere higher up the DOM tree. The event then continues bubbling up the tree and reaches the document, where it triggers the new event handler.
Here's a working example.
Update (see comments)
As noted by #zerkms in the comments, I think you probably only want to bind the event handler to document once. You could use the one method to do so, which unbinds the event handler after it's been executed once:
$(document).one('click', 'html', function(){
$('#show_me').hide();
});

jquery click event tr or input clicked

I have the following code:
$(document).ready(function () {
$("tr").live('click',function(){
alert("TR");
});
$("input").live('click',function(){
alert("INPUT");
});
});
Fiddle here
How can I just trigger the click function for the checkbox without triggering the tr function? Is there any solution with jQuery?
I will not set return false at the end of the input function and I really need the tr element too.
Info: event.stopPropagation doesn't work on live() events.
You can use the stopPropagation() method on the event object.
It will prevent the event from bubbling up without cancelling the default event behavior.
$(document).ready(function () {
$("tr").click(function(){
alert("TR");
});
$("input").click(function(e){
alert("INPUT");
e.stopPropagation();
});
});
As it seems you are using .live() and not direct event binding, you can't use stopPropagation().
First of all, .live() is legagcy code and has been deprecated, which means it could be removed from the library in any future new version. I don't know which version of jQuery you are using but you should consider moving to the latest (which is more optimized anyway) and use .on() for event delegation.
Nevertheless, if you can't upgrade your jquery library, here's maybe a solution to your problem. The event parameter passed to all event handler contains a property target which reference the element from which the event was initiated. So you could do something like:
$("tr").live('click',function(e){
if (e.target.nodeName !== "INPUT") {
// if ($(e.target).is('input') === false) { // jquery style but maybe less efficient
alert("TR");
}
});
Not very elegant but does the trick. Here's an example.
The problem with .live() is that events are binded to the document so as more complex as your application would become, you may end up with headaches to stop propagation.
In the meantime I've made a fiddle using .on() (here) and one using .delegate() (here).
You need to add stopPropagation() to your input click handler. It will stop the event bubbling up the DOM to parent elements.
$(document).ready(function () {
$("tr").click(function(){
alert("TR");
});
$("input").click(function(e){
alert("INPUT");
e.stopPropagation();
});
});
Example fiddle
OP Updated Question:
$(document).ready(function () {
$("TABLE").delegate("tr", 'click',function() {
alert("TR");
});
$("TABLE").delegate("input", 'click',function(e) {
e.stopPropagation();
alert("INPUT");
});
});
Use stopPropagation() for input handler
http://jsfiddle.net/KJg6Q/
http://jsfiddle.net/LwvYD/2/
e.stopPropagation() in handle on input or use e.relatedTarget
$("tr").click(function(e){
if( e.relatedTarget.tagName != "input" )
alert("TR");
});

Stop propagation with jQuery delegate/live function not working

Here's the problem html:
<ul id="update-list">
<li class="update" onclick="window.location('some_url')">
<h2> some header </h2>
<p> some paragraph </p>
<div>
<a class="popup-link">
<span> Show Popup </span>
<span> + </span>
</a>
</div>
</li>
// this repeats n times
//...
</ul>
When I click on .popup-link link, it should open the lightbox popup only (which it does) but the inline onclick on li also fires. The thing is that the li tags are all part of some partial which is fetched via ajax on different pages. So I use jQuery's delegate to bind the events as follows:
$('#update-list').delegate('.popup-link', 'click', function(e){
// e.target is <span> while e.currentTarget is .popup-link
e.stopPropagation();
//console.log(e.isPropagationStopped()); this shows 'true' in console
$.popup(); // launch popup
e.preventDefault(); // or return false
});
This doesn't seem to work and the inline onclick fires anyway. I've tried with live() as well but no success. Is there something I am missing here?
AFAIK you cannot reliably prevent an inline event handler from firing by stopping the bubbling within an attached event handler.
Furthermore, using live() or .delegate() you cannot use preventDefault() nor stopPropagation(). You need to return false to prevent the bubble phase and the default behavior.
Anyway, as I already mention you can't prevent the inline event handler to fire with that.
So either, create it completely unobtrusive (which is what I highly recommend) or remove that inline click handler in code.
Example:
$('#update-list').delegate('.popup-link', 'click', function(e){
$.popup(); // launch popup
return false;
}).delegate('.update', 'click', function(){
window.location('some_url');
})
// the rest of this is unnecessary if you can just omit the onclick attribute
.find('.update')
.removeAttr('onclick');
Ref.: .delegate()
$('#update-list').delegate('.popup-link', 'click', function(e){
e.stopImmediatePropagation();
e.preventDefault();
// do something...
});
Can you try this?
$('#update-list').delegate('.popup-link', 'click', function(e){
// e.target is <span> while e.currentTarget is .popup-link
e.stopPropagation();
e.preventDefault(); // or return false
// open popup in a timeout so that this function can return false
window.setTimeout(function() {$.popup();}, 20);
// for IE
e.cancelBubble = true;
return false;
});
You can try this as .delegate() has been superseded by the .on() method.
It will work fine

Categories

Resources