Devil of a time with jQuery delegate and .not - javascript

I've searched hi and low but couldn't find a solution. I've tried everything.. but can't get this thing to work.
NOTE: Can't use ".on()" . Using an older version of jQuery that only supports .live/.delegate
basically, I have a very involved webpage.. and there are event handlers flying everwhere.. BUT, I basically want to attach a click event on the body BUT exclude certain id's. Great. Figured it would be easy.
tried:
jQuery('body').delegate('.not("#mainID #anotherID")','click', function(e){
// do something
})
jQuery('body').delegate(':not(".class1 .class2")','click', function(e){
// do something
})
etc...
and a bunch bunch more.. basically, cannot get this thing to work. No matter what I do, the whole page is clickable.
when I do something simple like: Great it works.
jQuery('body').delegate('#someID','click', function(e){
// do something
})
But that isn't what i need. I need to basically allow for clicking on the whole body except for two subsets, smaller sections of the page. I figured this would be trivial.. but for some reason, just not working.
The two items I want to exclude are:
id: mainID w/ a class of ".class1"
id: anotherID w/ a class of ".class2"
another note: mainID sits outside of anotherID - two distinct sections of the page. Both divs.

Let me point out few things related to event delegation:
First of all, use .on() function, .delegate() is deprecated.
Second, .class1 .class2 will match class2 which is inside of class1
jQuery('body').on('click', ':not(.class1, .class2)', function(e) {
// do something
})
But, this is also not what you need, you need:
$(".class1, .class2").on('click', function() { return false; });
If you are using older versions of jQuery and for some reason cannot change it, use .live() or normal .click() handler:
$(".class1, .class2").click(function() { return false; });
Now, if you click on .class1 and .class2 nothing will happen. If you want to select only specific class within a id you can use #mainID .class1 as selector. Or with older event delegation:
jQuery('body').delegate(':not(.class1, .class2)','click', function(e){
// do something
// but this will execute on every where you click except .class1, .class2
})

Related

is this javascript code correct?

I am trying to remove a class when clicking on an element with a specific class. I made this javascript and it does work. But is this correct syntax to do it this way Can this be more efficient?
// Clear notifications alerts
$(document).on('click', '.js-clear-notifications', function() {
$('.AlertNotifications').remove();
});
// clear inbox alerts
$(document).on('click', '.js-clear-inbox', function() {
$('.AlertInbox').remove();
});
Your javascript code is correct, provided that you load jQuery as well.
Furthermore you have the most efficient solution, where you use a single event handler to handle events that originate on multiple elements.
The alternative would be:
$('.js-clear-notifications').on('click', function() {
$('.AlertNotifications').remove();
});
Which attaches as many event handlers as there are elements in the jQuery object. Slightly less efficient, though probably you would never notice except in extreme cases.
To me a more proper way to do it is something like this:
...
$('.js-clear-inbox').on('click', function() {
$('.AlertInbox').remove();
});
...
I will also suggest to have more specific selectors i.e.
$('div .js-clear-inbox')
I hope that this helps.
I am editing this in response to the feedback in the comments.
If what you want is to remove all elements with AlertNotifications class, which is what your code does, then what you have is correct.
If what you want is to remove only the class, which is what the text of the post said, you want removeClass, not remove:
$('.js-clear-notifications').on('click',function() {
$(this).removeClass('AlertNotificitions');
}
The new way, if you have already defined the variable, the proper way to delete it from the DOM would be:
var elem = document.getElementById("myDiv");
elem.remove();
But if you are just beginning out, .remove would be your best opinion.

Change Exposed elements (jQuery Tools )

I would like to cancel an exposed element and expose another one in one onClick(). Is that possible? My code doesn't work..
Here's the js:
function tutStep1(){
jQuery('#workspace_menu').expose({
onLoad: function(event) {
jQuery('.next').fadeIn();
}
});
jQuery('.tutorial .next').click(function() {
jQuery.mask.close();
tutStep2();
});
});
function tutStep2(){
jQuery('.action_list').expose();
}
Here's the html
<span onclick="tutStep1();" >tutorial</span>
The mask just won't open again unless I click on the span.
Or is there another way by not closing the mask, and switch elements to expose?
Probably not a good idea to put a click event inside a click event. I'm not familiar with this mask plugin, but speaking in the abstract, you can clean it up by doing something like this:
$('.open').click(function() {
$('#workspace_menu').show();
});
$('.tutorial, .next').click(function() {
$('.mask').hide();
$('.action_list').show();
});
Make sure you separate multiple selectors with a comma in the case of .tutorial and .next
You have your onClick events nested inside one another.
Recode and keep them all separate.

jQuery .on('click') firing multiple times when used with :not() selector

Good morning,
I have a set of boxes on a page that are presented as a list, and within these boxes there might be some links that can be clicked. I want the links within the boxes to work as normal (i.e. bubble up and either perform the default action or then be handled by event handlers further up the DOM), but if the box is clicked anywhere else then it should be caught by a particular event handler attached to the "list" containing all the boxes.
Simple html representation
<div class="boxlist">
<div class="box" data-boxid="1">
Some text, and possibly a link and another link, and perhaps even a third link.
</div>
<div class="box" data-boxid="2">
Some more text, this time without a link.
</div>
</div>
The javascript that I thought should work.
$(function () {
$('.boxlist').on('click', '.box :not(a)', function (e) {
var boxid= $(this).closest('.box').data('boxid');
console.log('open: ' + boxid);
});
});
My expectation was that the above javascript should handle all clicks that did not originate from tags. However, for some reason when the box is clicked (either the box itself, or an tag, doesn't matter), it fires this event X times, where X is the total number of tags within the list of boxes.
So I have two questions:
1. What am I doing wrong with the :not() selector.
2. Is there a better way to handle this scenario?
Thank you for helping!
linkUsing jQuery :not selector actually is very slow ex:http://jsperf.com/not-vs-notdasdsad/4 and it's way better to just use event delegation. So in this case you want to keep track of every click on the .boxlist but check the node type to see if its an anchor or not. This is an example.
$(function () {
$('.boxlist').on('click', function(ev){
if(ev.target.tagName != "A"){
// handle box click code
console.log('box click');
return false;
}
// Otherwise allow event to bubble through.
});
});
and here is a jsfiddle example
http://jsfiddle.net/drXmA/
Also their are a few reasons your code doesn't work
.box :not(a)
should be
.box:not(a)
and the reason this also does not work is because .box is not an anchor tag it has children elements that are anchor tags it will never find an anchor tag named .box if their is one the callback would not execute. Changing the .box to an anchor tag will make it so the code doesn't execute because .box is an anchor and it is only running when .box:not(a)
I guess you want something like this:
$('.boxlist').on('click', '.box:not(a)', function (e) {
var boxid = $(this).closest('.box').data('boxid');
console.log('open: ' + boxid);
}).on('click', '.box a', function (e) {
e.preventDefault().stopPropagation();
});
DEMO FIDDLE
I think better to stop the default behavior and stop the event bubbling to its parent. .on() chain to the .box items excluding <a> from it and stop the default behavior and event bubble with e.preventDefault().stopPropagation();

JQuery - how to attach a method to the 2nd state in an event that has no states?

I'm using the premade .slideToggle method in JQuery
I want to add an object to the .slideDown state of .slideToggle. ie) When I click a button I want to bind that object to the .slideDown event and 'close' it. However I obviously cannot just .add the object to .slideToggle. Is there a way to specifically target the slideDown state? Or do I have to utilize .slideUp and .slideDown if I want the privilege of specificity?
Obviously .slideToggle is another super easy JQuery "let's look like magic while we cache all the if{s and all the rest into one big variable".
I believe you'll have to give up using .slideToggle() but you can still use the convenience of .toggle()
$('#some-element').toggle(function() {
// put slideDown here, along with anything else that should accompany it
}, function() {
// put slideUp here, etc.
});
You could always do like this. It's not better than #Justin Ward's way. But it works
$("#some-element").slideToggle(function(){
if ($(this).is(":visible")) {
// Do something (showing)
} else {
// Do something (not showing)
}
});

jQuery select all elements with a common class

I want to handle a click event across a set of links so tried to approach this by adding a secondary class like following:
Test 1
Test 2
Test 3
Don't handle this one
Then tried this jquery selector to select the "external" class on links:
$('a.external').click(function(e) {
do something here...
});
However this isn't working like I expected. What's the right way to handle this? Should I just use a wildcard selector like the following or is there a better way?
$('[class^="someclass"]').click(function(e) {
....
});
What you have is exactly right (though the e probably isn't necessary in function(e) in your case).
Test 1
Test 2
Test 3
Don't handle this one
<script>
$('a.external').click(function(e) {
// will print the href in a javascript alert box
alert( $(this).attr('href') );
});
</script>
As far as I can tell the only possibility is that your <script> is actually above your <a> tags -- your script can't add the click listeners to the anchors because they wouldn't exist yet.
If so, you'll need to wrap the javascript in $(document).ready( function(){ /* code here */ });
Also, no need for the external class, just use the "select all absolute anchors, but not the ones linking to my domain" selector: $('a[href^="http://"]').not('[href^="http://mydomain.com"]')
I'm going to guess that your issue is that clicking the links actually makes it navigate somewhere? You need to tell the browser to ignore the normal link behavior. Otherwise your click function will run and then it will immediately navigate to the 'href' url. Also make sure this is all wrapped in a ready function.
$(function() {
$('a.external').click(function(e) {
// Do whatever
e.preventDefault();
});
});
I tried it out in jsFiddle and it works.
You have an extra parenthesis on the click() function.
Notice have your function(e) you have close parenthesis, remove that.
You should end up with this:
$('a.external').click(function(e) {
do something here...
});
try : http://jsfiddle.net/n6JJ3/
$('a.external').click(function() {
jQuery(this).css('background','red');
});​

Categories

Resources