I was reading through MaterializeCSS's js files, in its "cards.js" file, there are these lines:
$(document).on('click.card', '.card', function (e) {
//something
});
I am not unfamiliar with jQuery's .on() function, but I never used custom event as the first parameter. What I don't understand is there seems to be nowhere defining this custom event click.card(if it is a custom event), because I only load this card.js and another velocity.min.js file from the MaterializeCSS package besides jQuery, and I searched velocity.min.js there is nothing related to this event. It seems to me that the custom event is in this pattern:original event.classname, but I tried replacing card with other class name and it didn't work.
I tried to look for more information about how to define a custom event but couldn't find anything useful.
My question is how to find where this custom event is defined.
This is not a custom event, this is a DOM event with a namespace:
click is the DOM event, and card the event namespace.
If you have multiple handlers on the same element, this can help you discern them. You could remove only this listener (and leave all other click listeners):
$(document).off('click.card');
And you can trigger them manually using $('...').trigger:
$('.card').trigger('click.card'); // only triggers this specific click listener, not the others
You can find out more about event namespaces here.
Related
I'm using smarty streets jquery.liveaddress plugin in an angular single page app. I need to unbind all of the event listeners from the liveaddress instance when I transition to next page. Right now, if I come back to the page, all events are fired twice, then the next time on page, three times.
I've tried everything i can think of. My last solution was to unbind all of the event names from the $(document) because it looks like that is where the plugin is attaching all of the events to. but even that didn't work.
jQuery(document).unbind("AddressChanged");
jQuery(document).unbind("AutocompleteUsed");
jQuery(document).unbind("VerificationInvoked");
jQuery(document).unbind("RequestSubmitted");
jQuery(document).unbind("ResponseReceived");
jQuery(document).unbind("RequestTimedOut");
jQuery(document).unbind("AddressWasValid");
jQuery(document).unbind("AddressWasAmbiguous");
jQuery(document).unbind("AddressWasInvalid");
jQuery(document).unbind("AddressWasMissingSecondary");
jQuery(document).unbind("OriginalInputSelected");
jQuery(document).unbind("UsedSuggestedAddress");
jQuery(document).unbind("InvalidAddressRejected");
jQuery(document).unbind("AddressAccepted");
jQuery(document).unbind("Completed");
Ok for anyone trying to implement SmartyStreets jquery.liveaddress plugin in an angular application.
The trick was to not register anonymous event handlers.
In my case I was instantiating SmartyStreets in a directive, so put all the eventHandlers on scope and call liveAddress.deactivate() upon $destroy. No more duplicate events.
In jQuery, event handler functions are stored in an array. Therefore, unbind() function looks just for the function in the aforementioned array. It further means that you can only unbind() event handlers which are already added with bind().
Check out jQuery documentation on .bind()
I am working on converting some of our code base away from jQuery. Up until we got to events, everything was going pretty smoothly. We have a lot of namespaced code with jQuery, and so for now we are not converting the trigger function calls away from jQuery. However, we are trying to use js event listeners. Here is problem with custom events:
window.addEventListener("testevent", function(e){
console.log("js fired"); // this doesn't log, but it should!
});
$(window).on("testevent", function(e){
console.log("jquery listener fired"); // this logs fine, like it should
});
// trigger the custom event with jQuery
$(window).trigger("testevent");
If I run the code above in console, I get a log for the jQuery listener, but not the listener. Does anyone know why that is happening?
jQuery custom events are meant to be used to perform abstractions and simplifications, or to provide more meaning to some event just called click.
Furtheremore, these custom events are triggered by jQuery and can be only listened by jQuery.on. DOM event listeners will listen DOM events (i.e. ones defined by the W3C's standard).
According to the documentation, .trigger() executes any event handlers with the corresponding event. It also says that .trigger() only simulates an event and does not perfectly replicate a naturally-occurring event.
You'll see that they both work if you use window.dispatchEvent(new Event("testevent")) to fire a real event.
Similar question answered here
jQuery events are a level higher than the native events. Trigger fakes
a jQuery event.
Suppose I have a dynamic tag injected at the end of the loading page, using some jquery plugin. Say this tag has a class '.myclass' I want to bind an event so I tried :
$(document).on( 'click', '.myclass', function(){console.log('yes');});
The problem is that, no function is triggered, even when I run this code on my console so it seems that all the related events are listened elsewhere. How can I make this code run correctly ?
Find where the problem was coming from. It was related to the jquery plugin icheck, which customize all the eventlisteners (example, $('document').on('change', target,...) becomes $('document').on('Ifchanged', target,...)), so this plugin captures all the events related to checkbox.
Is there a way to temporarily disable an event listener?
In my case, I have a third party library (not jQuery centric) that creates mouseover/mouseout events on an element using addEventListener/attachEvent.
Under certain circumstances another event fires on a different element and I need to disable those event listeners. My solution thus far has been to simply unbind the mouseover/mouseout. This usually works fine because that event generally causes the page to refresh.
However, every now and again an error can occur (think validation error) that results in the page not refreshing, and I need to re-attach the mouseover/mouseout event listeners.
Helpful information
It's probably worth mentioning that because the mouseover/mouseout event listeners are created and attached within a third party library I cannot simply assign the event to a variable and bind/unbind it in that manner (which AFIK is the best way to do this).
Update
I had originally asked
Is there a way in jQuery to get the event listeners already assigned to an object?
I have since found out it is impossible to access events assigned by addEventListener/attachEvent: Access events added with attachEvent() / addEventListener() in JavaScript
jQuery uses data to store events internally, so you can use it to get all of the event handlers for an object:
$("#foo").data("events")
You can then remove a specific handler by using unbind:
$("#foo").unbind('click', $("#foo").data("events").click[42]);
Unfortunately, you can't access them. At best, you can remove event listeners using W3C's removeEventListener (docs) and/or Microsofts detachEvent (docs). Once the listener is removed, however, it's gone for good.
There's one caveat with removeEventListener, in that if the event was registered twice, once indicating to capture, and once indicating not to capture, you must remove it twice; once for each case.
To learn more about capturing and not capturing, see the W3C spec.
If you want to temporarily disable an event handler being run, why not just add escape code to the function?
like so:
$('#button').click(function(){
var clicked_element = $(this);
if(elem.hasClass('event-click-disabled'))
{
// logging code so we know exactly what events are being skipped
console.info(
'The click event on following element was skipped',
clicked_element
);
return;
}
alert('Button clicked');
});
Then if you want to disable an event on a specific element, just call
element.addClass('event-click-disabled');
The event handler is still run, but it will return immediately.
When I'm writing some JavaScript I have a set of interface buttons that have their events assigned when the page is loaded. My problem is anything created dynamically wont receive these events.
For example, I'm making a URL checker, whose job is to make sure that any link that goes to another domain brings up an exit interface letting the user know they are leaving. Any links created after the page is loaded, post ajax (no pun intended) or whatever wont have that event naturally as those that existed when the page loaded.
In practice, what's the best way to ensure any newly created items get these sorts of global events?
I like to use jQuery, but this is really a conceptual question.
Should I create a function to re-apply any global link effects, or is there a smarter way besides doing it piecemeal?
If using jQuery, you can use the .live() method.
Normally when binding an event handler, the event handler is bound to a specific set of elements. Elements added in the future do not receive the event handler unless it is re-bound.
jQuery's .live() method works around this by binding its own special event handler to the root of the DOM tree (relying on event bubbling). When you click on an element, if it has no event handler directly attached, the event bubbles up the DOM tree. jQuery's special event handler catches the event, looks at its target and executes any user-specified event handlers that were assigned to the target through .live().
Look into jQuery's live function. It will allow you to attach to events when control are created during load, and whenever new ones are created. There is a performance penalty, but it is not significant unless you are loading a lot of elements.
You can use the .live() jQuery method to add listeners to elements that are created after the page is finished loading. Using your example of the exit link (if I understand it correctly):
$(function(){
$('a.exitLink').live('click',function(event){ /* do stuff when a link of class exitLink is clicked */);
});
This will respond to the click event on any link of class exitLink, regardless of when it was created (before or after onload fires).
Hope this helps :)
Yes put simply, where you might have had this before:
$('selector').click(function () {});
Replace it with:
$('selector').live('click', function() {});