.not() with .live() not working - jquery-selectors

jQuery("a").not("div#mnuMain a").live("click", function(event){
event.preventDefault();
alert("yes I got u");
});
How to make it work?

Try putting it all in the main selector:
Example: http://jsfiddle.net/8Tkex/
jQuery("a:not(div#mnuMain a)").live("click", function(event){
event.preventDefault();
alert("yes I got u");
});
EDIT:
The reason using .not() didn't work is that when you use jQuery's live() method, you're not actually placing the click handler on the element. Instead you're placing it at the root of the document.
This works because all click (and other) events on the page "bubble up" from the element that actually received the event, all the way up to the root, thus firing the handler that you placed at the root using .live().
Because this occurs for every click on the page, jQuery needs to know which item received the click so it can determine which (if any) handler to fire. It does this using the selector you used when you called .live().
So if you did:
jQuery("a").live("click", func...
...jQuery compares the "a" selector to every click event that is received.
So when you do:
jQuery("a:not(div#mnuMain a)").live("click", func...
...then jQuery uses "a:not(div#mnuMain a)" for the comparison.
But if you do
jQuery("a").not("div#mnuMain a").live("click", func...
...the selector ends up looking like "a.not(div#mnuMain a)", which wouldn't match anything, since there's no .not class on the <a> element.
I think some methods may work with live(), but .not() isn't one of them.
If you're ever curious about what the selector looks like for your jQuery object, save your object to a variable, log it to the console and look inside. You'll see the selector property that jQuery uses.
var $elem = jQuery("a").not("div#mnuMain a");
console.log( $elem );
...should output to the console something like:
Object
context: HTMLDocument
length: 0
prevObject: Object
selector: "a.not(div#mnuMain a)" // The selector that jQuery stored
__proto__: Object
This is the output I get from Safari's console.

jQuery("a:not(div#mnuMain a)").live("click", function(event){
event.preventDefault();
alert("yes I got u");
});
try this

Related

jquery triggerHandler doesn't work while trigger does

I am adding a click event to a checkbox which will show/hide additional fields depending on its checked status. I want the handler to fire on load to set up the initial page structure. For some reason triggerHandler is not working on the field. If I change it to 'trigger' the handler will fire, but the checkbox status will also change. Can you see what i've done wrong/why triggerHandler won't work?
$('body').on("click", "#hdimage", function(){
console.log('hd');
if(!$('#hdimage').is(':checked')){
$('.sd-dim').hide();
} else {
$('.sd-dim').show();
}
});
$('#hdimage').triggerHandler('click');
That happens (as described in the docs) because
Events created with .triggerHandler() do not bubble up the DOM hierarchy; if they are not handled by the target element directly, they do nothing.
and since you use the delegated syntax of the .on() method which lets body handle the click event that occurs on the #hdimage element, that event never reaches the body..
Your Event is not bound to "#hdimage" its bound to 'body'
$(document).ready(function(){
$('#hdimage').on("click", function(){
alert("dostuff")
});
$('#hdimage').triggerHandler('click');
});

How to reference dynamically added element after DOM loaded without a need to act on any events?

I know there is .on and .live (deprecated) available from JQuery, but those assume you want to attach event handlers to one ore more events of the dynamically added element which I don't. I just need to reference it so I can access some of the attributes of it.
And to be more specific, there are multiple dynamic elements like this all with class="cluster" set and each with a different value for the: title attribute, top attribute, and left attribute.
None of these jquery options work:
var allClusters = $('.cluster');
var allClusters2 = $('#map').children('.cluster');
var allClusters3 = $('#map').find('.cluster');
Again, I don't want to attach any event handlers so .on doesn't seem like the right solution even if I were to hijack it, add a bogus event, a doNothing handler, and then just reference my attributes.
There's got to be a better solution. Any ideas?
UPDATE:
I mis-stated the title as I meant to say that the elements were dynamically added to the DOM, but not through JQuery. Title updated.
I figured it out. The elements weren't showing up because the DOM hadn't been updated yet.
I'm working with Google Maps and MarkerClustererPlus to give some more context, and when I add the map markers using markerclustererplus, they weren't available in the javascript code following the add.
Adding a google maps event listener to my google map fixed the problem:
google.maps.event.addListener(myMarkerClusterer, 'clusteringend', function () {
// access newly added DOM elements here
});
Once I add that listener, all the above JQuery selectors and/or methods work just fine:
var allClusters = $('.cluster');
var allClusters3 = $('#map').find('.cluster');
Although this one didn't, but that's because it only finds direct decendants of parent:
var allClusters2 = $('#map').children('.cluster');
Do what you need to do in the ajax callback:
$.ajax(...).done(function (html) {
//append here
allClusters = $('.cluster');
});
If you want them to be separate, you can always bind handlers after the fact, or use $.when:
jqxhr = $.ajax(...).done(function (html) { /* append html */ });
jqxhr.done(function () { allClusters = $('.cluster') });
$.when(jqxhr).done(function () { /* you get it */ });
If these are being appended without ajax changes, then just move the cluster-finding code to wherever the DOM changes take place.
If that's not an option, then I guess you would just have to check on an interval.

scope of 'this' inside mootools class

I'm trying to define a click handler in a Mootools class. My handler presumes opening a block of links, each of which should be 'equipped' with its own click handler, which should trigger a link specific action. What I mean is let's suppose I have the following HTML code:
<div id="wrapper">
open options
<div class="optionsBlock" style="display:none">
1
2
3
</div>
</div>
Then I'm trying to define a class like this in Mootools:
var myHandler = new Class({
Implements : [Events],
initialize : function(element){
this.element = document.id(element);
this.elements = this.element.getChildren('a');
this.elements.addEvents('click', function(ev){
ev.preventDefault();
//'this' as a reference to the current element in the array, which is being clicked, correct?
this.getSibling('div.optionsBlock').setStyle('display', 'block');
var parentLink = this;
this.getSibling('div.optionsBlock').getChildren('a').addEvent('click', function(e){
e.preventDefault();
//should append the text of currently clicked link into the parent link
parentLink.appendText(this.get('text'))
});
});
}
});
new myHandler('wrapper');
This is just an illustration of how I can imagine the code should be like (and I'm sure this code is not good at all), but I really need some help regarding the following:
Since adding new events constatly changes the scope of 'this', how should I keep a reference both to the class instance and the element being clicked?
How should I modify the class in order not to have the entire code inside the initialize method? I tried to create separate methods for every event handler, but as a result I got confused with the scope of 'this', with binding and trying to get all of this together really annoys me, but I want to get a grip of this knowledge.
How to keep track of the scope of 'this' when adding nested event handlers inside a class? I honestly googled and searched for an answer but for no avail.
Thanks!
scope, take your pick - asked many many times - search here for [mootools]scope this:
Mootools class variable scope
mootools variable scope
Mootools - Bind to class instance and access event object
to recap:
use a saved reference var self = this; then reference self.prop or use the fn.bind pattern
add more methods. follow single responsibility principle. eg, in your class, create attachEvents: function() {} and have initialize call that.
by using the saved reference pattern. you can fix it upriver by delegating events as opposed to creating new event callbacks on parent clicks.

jQuery event handler .on() not working

I want to attach a event to dynamically created element class.So i used live function but it was not triggered. So checked live function reference ,there i red below notes
As of jQuery 1.7, the .live() method is deprecated. Use .on() to
attach event handlers. Users of older versions of jQuery should use
.delegate() in preference to .live().
so decide to use on function,But it still not working.The text field is already attached with jquery ui datpicker.On another element select i disabled that field.
jQuery("#from").attr('disabled','disabled')
.removeClass('date_picker_bg')
.removeClass('hasDatepicker')
.addClass('date_picker_disabled');
after disabled if i click i want to show alert or tooltip.so i tried this,but not working
jQuery(".date_picker_disabled").on("click", function(event){
alert('hi');
});
What may be the problem
I am using jquery 1.7.1 ( jquery-1.7.1.min.js)
The problem is that jQuery(".date_picker_disabled") finds elements with that class and binds to them. If elements don't have the class at the time the binding is made, the events will not be handled.
The on function allows you to get round this by handling them on another element when the event "bubbles up to" a parent element. In this instance, we could say the body element – there may be a more specific common parent you could choose.
jQuery(document.body).on('click', '.date_picker_disabled', function(event) {
alert('hi');
});
The event handler is now bound to the document.body element. All clicks that happen anywhere in the body are tested to see if they originated from an element matching the selector. If so, the handler is fired.
This is explained on the documentation for the on function. It is the same behaviour as was present in previous versions of jQuery with live and delegate functions.
Having taken another look at your code, you have disabled="disabled" set on your input element. click events are not fired on disabled elements.
This is tricky.
When your code runs, your element does not have .date_picker_disabled class so your jQuery(".date_picker_disabled") returns nothing and .on() is not called.
Apply .on() on the outer element and use the selector parameter:
// you can also do $(document).on()
$(<outer element>).on('click', '.date_picker_disabled', function() {
// do something
});
This will delegate the event to the <outer element>. The handler will only be executed if an element with class .date_picker_disabled has been clicked (second param).
From the documentation of .live():
Rewriting the .live() method in terms of its successors is
straightforward; these are templates for equivalent calls for all
three event attachment methods:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
So in your case, you would do:
$(document).on('click', '.date_picker_disabled', function(event){
alert('hi');
});
I was using jQuery 1.7.2 and tried all proposed methods:
Didn't work:
$(document.body).on('click', '.collapsible-toggle' function() {
console.log('clicked');
});
Didn't work:
$(document).on('click', '.collapsible-toggle' function() {
console.log('clicked');
});
None of them worked until I tried the following:
----- Worked! ----
$('body .collapsible-toggle').on('click', function() {
console.log('clicked');
});
Maybe you should do:
jQuery("body").on("click",".date_picker_disabled", function(event){
alert('hi');
});
in this way you attach the event handler to the bosy and specify to fire that event only when that selector ".date_picker_disabled" is matched.
BTW this is exactly how live() worked
try :
$(document.body).on( "click", ".date_picker_disabled", function() {
alert('hi');
});
document.body helps for dynamic html too.
Just chekc it out: .on not working on dynamic html

In jQuery Mobile, how do you target the element created using loadPage?

I load a "page" into the DOM using $.mobile.loadPage(). I then want to target the element created, but I haven't figured out how to do this. This is what I thought would work:
var toc = $.mobile.loadPage('toc.html');
toc.trigger('customevent');
The above does not work in part because toc is a "deferred promise object" rather than a good ol' jQuery DOM reference. Additionally, it does not work because the second line is triggered before loadPage finishes. Is there a way to fire a callback after loadPage?
Thanks!
If you know the id of the page being loaded then you can bind the 'pagecreate' event to that object with .live() like so:
$('#blah').live('pagecreate', function () {alert('created');});
This will fire after the page has been loaded into the dom.
I just was just able to figure this out, even if you don't have the id, here's an example of how i am performing an action (fadeIn) on the the inserted element....
$(document).bind('pageload',function(evt,data){
$(document).unbind('pageload');
$(data.page).fadeIn();
});
$.mobile.loadPage('mypage.html',{'pageContainer':$('#my_item')});
You can use pageshow in order to fire a callback when the page is loaded. Please refer to the jQuery Mobile Events API for more detail.
An example would be something like:
$('div').live('pageshow',function(event, ui){
...
});