I need to change behavior of jQuery library (date range picker), it have code like this:
box.find('.month').off("change").change(function(evt) {
dateChanged($(this));
});
box.find('.year').off("change").change(function(evt) {
dateChanged($(this));
});
Those are two select elements. It don't return false and functions inside handler don't access the event. But for some reason my events that use delegation doesn't work. They are ignored.
$picker.on('change', 'select', function() {
console.log('CHANGE');
});
The console log is not executing, but if I remove previous lines from the library, my event delegation code works fine.
NOTE: $picker is object in my code that is parent of box element. But I also have event added on $(document) that is also not working.
First time I see something like this. Adding event directly to element, prevents event propagation. Can someone explain what is happening here? Is this documented anywhere?
This happens in Firefox and Chrome.
If someone need simple example, I can create one. But thought that this is self explanatory.
EDIT: I've created a simple reproduction and it works fine. I have complex application with a lot of files (R Shiny Application), but I don't see any change events in dev tools. Are there any way of making the event not propagate? Maybe using event capturing. What should I search for in order to find the code that is preventing the events from propagating?
I'm working on some code where I want send custom events to the window object where I have an event listener that will perform an action. This works fine for one of the listeners, but I have a second one I want to use, but it's not registering all the time. Is there a way to debug this as the javascript console isn't very helpful? Or, is there a way to detect if the event listener has been added to the window object using Javascript? If I look at the HTML element in the inspector, I can see if the event is attached or not manually.
My code looks something like this:
$.when($.ready).then(function () {
// Set up the event listener to capture search terms.
window.addEventListener('search_terms', function(evt) {
saveSearchTerms(evt.detail);
});
window.addEventListener('profile-update', function(evt) {
console.debug('got the event');
console.debug(evt.detail);
updateProfile(evt.detail);
});
});
The firt one works fine. It's the second one that's giving me issues.
Thanks.
I'm registering a lot of custom triggers on the window, and for debugging purposes would like to see in the console when those events are triggered without having to manually register a console.log(); for each trigger.
Are there any ways to detect custom jQuery triggers on an element and console.log(); information about the event when triggered?
If click and other standard events are included, that's OK.
The simplest way to accomplish this: extending jQuery's built-in trigger function.
var oldTrigger = $.fn.trigger;
jQuery.fn.extend({
trigger: function(event,data) {
console.debug("Triggered %s on %s",event,this[0]);
var trigReturn = oldTrigger.apply(this,arguments);//$(this).trigger(event,data);
return trigReturn;
}
});
Then any triggers should show up in the console. For example: $(document).trigger("MYEVENT"); outputs Triggered MYEVENT on #document in the console.
Obviously this should only be used for testing and not in a production environment.
Example: http://codepen.io/shshaw/pen/tDfho
This only works in Chrome (I am not aware of one that works in other browsers, see here).
events = []
for (event in getEventListeners(document)) {
events.push(event);
}
monitorEvents(document, events);
Caveat emptor: I tried this on Stack Overflow and it almost froze my browser because it was outputting so much data.
Source: Chrome developer tools.
I'm trying to make it so that if you click the CKEditor's text area (where you type), it shows an alert, but I can't get it working and I'm not sure why.
Here's the JSFiddle: http://jsfiddle.net/C7N7r/44/
Please help!
HTML:
<form>
<textarea class="ckeditor" id="editor1">Some text.</textarea>
</form>
JS:
CKEDITOR.replace("editor1", {});
$(document).on("click", ".cke_contents", function() {
alert("CLICKED");
});
You can use the CKEditor API to do it in a simple way:
function clickListener(e) {
alert("clicked")
}
CKEDITOR.on('instanceReady', function(ev){
ev.editor.editable().attachListener(ev.editor.document, "click", clickListener)
})
demo at http://jsfiddle.net/up3HG/1/
The problem
With delegated event handler you are capturing click events for any elements with class cke_contents that will ever exist in the document. And you are doing it right.
The problem is that .cke_contents is never clicked. It never handles click event. You can click it from code and your alert pops up.
CKEDITOR.on('instanceReady', function(){$('.cke_contents').click()})
This is because of an iframe filling the full area of .cke_contents. Events are not propagated across frames, nor are they generated independently for the frame.
How to solve it
You can set event handler inside the iframe. You can access its contents as it does not violate same-origin policy (both the document and the frame have the same document.domain).
CKEDITOR.on('instanceReady', function() {
$('.cke_contents iframe').contents().click(function() {
alert('Clicked!');
});
});
jQuery.contents() returns its content document for iframe, if it does not violate same-origin policy.
Problem is that instanceReady is triggered for each CKEditor instance and the code above adds click handler to all CKEditors, therefore the handlers could be duplicated.
However, this can be solved by assigning the handlers more locally, just to the currently becoming ready editor:
CKEDITOR.on('instanceReady', function(evt) {
$(evt.editor.container.$).find('iframe').contents().click(function() {
alert('Clicked!');
});
});
This works OK as you can see on JsFiddle.
Side notes
Originally I did not get jQuery event delegation and thought you are trying to add your event handler before the element with .cke_contents exists (your code is executed much earlier). Without event delegation you would need to use CKEditor API, namely instanceReady event of the editor, only that way you can be sure you are adding your event handler to an already existing element. ($(document).ready(…);) is still too early as you can see via console.log($('.cke_contents').toSource());.
BTW your attempt to replace your textarea with CKEditor manually just throws an exception as it already has been replaced. Try wrapping it in try {…} catch (e) { console.log(e); } to see it.
I need to debug a web application that uses jQuery to do some fairly complex and messy DOM manipulation. At one point, some of the events that were bound to particular elements, are not fired and simply stop working.
If I had a capability to edit the application source, I would drill down and add a bunch of Firebug console.log() statements and comment/uncomment pieces of code to try to pinpoint the problem. But let's assume I cannot edit the application code and need to work entirely in Firefox using Firebug or similar tools.
Firebug is very good at letting me navigate and manipulate the DOM. So far, though, I have not been able to figure out how to do event debugging with Firebug. Specifically, I just want to see a list of event handlers bound to a particular element at a given time (using Firebug JavaScript breakpoints to trace the changes). But either Firebug does not have the capability to see bound events, or I'm too dumb to find it. :-)
Any recommendations or ideas? Ideally, I would just like to see and edit events bound to elements, similarly to how I can edit DOM today.
See How to find event listeners on a DOM node.
In a nutshell, assuming at some point an event handler is attached to your element (eg): $('#foo').click(function() { console.log('clicked!') });
You inspect it like so:
jQuery 1.3.x
var clickEvents = $('#foo').data("events").click;
jQuery.each(clickEvents, function(key, value) {
console.log(value) // prints "function() { console.log('clicked!') }"
})
jQuery 1.4.x
var clickEvents = $('#foo').data("events").click;
jQuery.each(clickEvents, function(key, handlerObj) {
console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
})
See jQuery.fn.data (where jQuery stores your handler internally).
jQuery 1.8.x
var clickEvents = $._data($('#foo')[0], "events").click;
jQuery.each(clickEvents, function(key, handlerObj) {
console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
})
There's a nice bookmarklet called Visual Event that can show you all the events attached to an element. It has color-coded highlights for different types of events (mouse, keyboard, etc.). When you hover over them, it shows the body of the event handler, how it was attached, and the file/line number (on WebKit and Opera). You can also trigger the event manually.
It can't find every event because there's no standard way to look up what event handlers are attached to an element, but it works with popular libraries like jQuery, Prototype, MooTools, YUI, etc.
You could use FireQuery. It shows any events attached to DOM elements in the Firebug's HTML tab. It also shows any data attached to the elements through $.data.
Here's a plugin which can list all event handlers for any given element/event:
$.fn.listHandlers = function(events, outputFunction) {
return this.each(function(i){
var elem = this,
dEvents = $(this).data('events');
if (!dEvents) {return;}
$.each(dEvents, function(name, handler){
if((new RegExp('^(' + (events === '*' ? '.+' : events.replace(',','|').replace(/^on/i,'')) + ')$' ,'i')).test(name)) {
$.each(handler, function(i,handler){
outputFunction(elem, '\n' + i + ': [' + name + '] : ' + handler );
});
}
});
});
};
Use it like this:
// List all onclick handlers of all anchor elements:
$('a').listHandlers('onclick', console.info);
// List all handlers for all events of all elements:
$('*').listHandlers('*', console.info);
// Write a custom output function:
$('#whatever').listHandlers('click',function(element,data){
$('body').prepend('<br />' + element.nodeName + ': <br /><pre>' + data + '<\/pre>');
});
Src: (my blog) -> http://james.padolsey.com/javascript/debug-jquery-events-with-listhandlers/
The WebKit Developer Console (found in Chrome, Safari, etc.) lets you view attached events for elements.
More detail in this Stack Overflow question
Use $._data(htmlElement, "events") in jquery 1.7+;
ex:
$._data(document, "events") or $._data($('.class_name').get(0), "events")
As a colleague suggested, console.log > alert:
var clickEvents = $('#foo').data("events").click;
jQuery.each(clickEvents, function(key, value) {
console.log(value);
})
jQuery stores events in the following:
$("a#somefoo").data("events")
Doing a console.log($("a#somefoo").data("events")) should list the events attached to that element.
Using DevTools in the latest Chrome (v29) I find these two tips very helpful for debugging events:
Listing jQuery events of the last selected DOM element
Inspect an element on the page
type the following in the console:
$._data($0, "events") //assuming jQuery 1.7+
It will list all jQuery event objects associated with it, expand the interested event, right-click on the function of the "handler" property and choose "Show function definition". It will open the file containing the specified function.
Utilizing the monitorEvents() command
ev icon next to elements
Within the Firefox Developer Tools' Inspector panel lists all events bound to an element.
First select an element with Ctrl + Shift + C, e.g. Stack Overflow's upvote arrow.
Click on the ev icon to the right of the element, and a dialogue opens:
Click on the pause sign || symbol for the event you want, and this opens the debugger on the line of the handler.
You can now place a breakpoint there as usual in the debugger, by clicking on the left margin of the line.
This is mentioned at: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_event_listeners
Unfortunately, I couldn't find a way for this to play nicely with prettyfication, it just seems to open at the minified line: How to beautify Javascript and CSS in Firefox / Firebug?
Tested on Firefox 42.
Looks like FireBug crew is working on an EventBug extension. It will add another panel to FireBug - Events.
"The events panel will list all of the event handlers on the page grouped by event type. For each event type you can open up to see the elements the listeners are bound to and summary of the function source." EventBug Rising
Although they cannot say right now when it will be released.
I also found jQuery Debugger in the chrome store. You can click on a dom item and it will show all events bound to it along with the callback function. I was debugging an application where events weren't being removed properly and this helped me track it down in minutes. Obviously this is for chrome though, not firefox.
According to this thread, there is no way in Firebug to view what events are attached to listeners on a DOM element.
It looks like the best you can do is either what tj111 suggests, or you could right-click the element in the HTML viewer, and click "Log Events" so you can see which events are firing for a particular DOM element. I suppose one could do that to see what events could be firing off particular functions.
With version 2.0 Firebug introduced an Events panel, which lists all events for the element currently selected within the HTML panel.
It can also display event listeners wrapped into jQuery event bindings in case the option Show Wrapped Listeners is checked, which you can reach via the Events panel's options menu.
With that panel the workflow to debug an event handler is as follows:
Select the element with the event listener you want to debug
Inside the Events side panel right-click the function under the related event and choose Set Breakpoint
Trigger the event
=> The script execution will stop at the first line of the event handler function and you can step debug it.
Firebug 2 does now incorporate DOM events debugging / inspection.