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?
Is it possible to have multiple click events for the same element? I have tried to simply have it like so:
$('#templates').click(function(e) {
do something..
});
$('#templates').click(function(e) {
do something else also..
});
Yet only the second event fires. I cannot find any decent answers explaining how to do this for a singular element in an on-click?
Note: the first click event calls server-side and loads a new PHP template (this may have an effect on what I can use in the second call I guess, as individually both clicks work but the server call does not work if I try a second click for the same element)
$('#templates').click(function(e) {
functionOne();
functionTwo();
});
function functionOne(){
}
function functionTwo(){
}
perhaps?
Please check this fiddle:
http://jsfiddle.net/DqSSd/
As you can see it should work well.
So please provide more information, and it would be better, if you provide JS fiddle as well.
Because so far the problem might be in:
second event is fired before first event returns the result
first event returns error from the server
some of events contains syntax error
etc
You may check something of those with investigation of NET calls to server (with Firebug or Chrome Developer toolbar).
Also for testing purposes you can type in console $('#templates').data("events"), so you will be able to see all events and handlers for particular element.
I am a new programmer and still learning.
This is the code that I am trying to figure out:
<div id="buy" class="buy button">Buy</div>
When I click on the div (button), some JavaScript code is executed but I don't know were it is. How can I tell what function is fired when click happens? Some how a listener is attached to this element.
In Google chrome's developer tools (click the wrench icon >Tools>Developer tools), select the element in the Elements tab, on the right open the 'Event Listeners' panel you'll will see all events
If you use Firefox and Firebug you can try installing FireQuery. It will make it so you can see the handlers bound by jQuery. http://firequery.binaryage.com/
You can't do it in a really good manner by "just" using ECMAscript itself. For instance, if there was a click event handler added by DOM Level 1 in the form of
document.getElementById('buy').onclick = function() {};
you can of course easily intercept that property on the node itself. Things are getting more complicated if DOM Level 2 comes into play with .addEventListener() respectevily .attachEvent(). Now you don't really have a "place" to look for where all the different listener functions where bound from.
It gets better by using jQuery. jQuery will hold all it's event handler functions in a special object which is linked to the DOM node of invocation. You can check for that by getting the .data()-expando property for a node like
$('#buy').data('events');
However, now I already described three different ways of binding event listeners to a node (actually its two because a library like jQuery also uses DOM Level 1 or 2 methods of course).
It's really getting ugly if an event is triggerd by delegation. That means, we bound our click event on some parent-node just waiting for that event bubbling up to us so we can check the target. So now we don't even have a direct relationship between the node and the event listener.
Conclusion here is, lookout of a browser plugin or probably a thing like VisualEvent.
You may use "Visual Event 2" script as a bookmark or same script as Chrome extension.
This script shows all js events attached to dom-elements.
Use jQuery("#buy").data('events');
http://api.jquery.com/jQuery.data/ may be interesting.
Event handlers attached using traditional element.onclick= handler or HTML <element onclick="handler"> can be retrieved trivially from the element.onclick property from script or in-debugger.
Event handlers attached using DOM Level 2 Events addEventListener methods and IE's attachEvent cannot currently be retrieved from script at all. DOM Level 3 once proposed element.eventListenerList to get all listeners, but it is unclear whether this will make it to the final specification. There is no implementation in any browser today.
If you're using FireFox, you should have FireBug installed. Once you have that, you can install FireQuery, which will show you what jQuery events are bound to which objects.
http://getfirebug.com/
http://firequery.binaryage.com/
This is the easiest way I've found of how to do it:
http://www.sprymedia.co.uk/article/Visual+Event
When working with events in Javascript, it is often easy to lose track
of what events are subscribed where. This is particularly true if you
are using a large number of events, which is typical in a modern
interface employing progressive enhancement. Javascript libraries also
add another degree of complexity to listeners from a technical point
of view, while from a developers point of view they of course can make
life much easier! But when things go wrong it can be difficult to
trace down why this might be.
It is due to this I've put together a Javascript bookmarklet called
Visual Event which visually shows the elements on a page that have
events subscribed to them, what those events are and the function that
the event would run when triggered. This is primarily intended to
assist debugging, but it can also be very interesting and informative
to see the subscribed events on other pages.
There's a bookmark button there you can drag to your toolbar (FF or Chrome), then just click the button on any page where you want to see the events attached. Works great! (at least for events attached by jQuery or other libraries).
Are you using jQuery? If so, you want to search for one of these three lines of code:
$("#buy").click //the div is refered by its id
or
$(".buy").click //the div is refered to by the style "buy"
or
$(".button").click //refered to by the style "button"
Most newer browsers have "Developer Tools" built into them by pressing F12 (at least in IE and Chrome). That may help you do some further debugging and tracing.
Below is something I’ve used in the past that I think may be what you're looking for. What this does is watch a property on a page element (In the example below, it's the document's "Title" property) and then display an alert with the JS callstack whenever that property is changed. You’ll need to get this into the DOM before whatever code you're trying to find fires, but hopefully you’ll be able to identify what’s causing the problem.
I would recommend using Firefox and getting Firebug for JavaScript debugging.
// Call stack code
function showCallStack() {
var f=showCallStack,result="Call stack:\n";
while((f=f.caller)!==null) {
var sFunctionName = f.toString().match(/^function (\w+)\(/)
sFunctionName = (sFunctionName) ? sFunctionName[1] : 'anonymous function';
result += sFunctionName;
result += getArguments(f.toString(), f.arguments);
result += "\n";
}
alert(result);
}
function getArguments(sFunction, a) {
var i = sFunction.indexOf(' ');
var ii = sFunction.indexOf('(');
var iii = sFunction.indexOf(')');
var aArgs = sFunction.substr(ii+1, iii-ii-1).split(',')
var sArgs = '';
for(var i=0; i<a.length; i++) {
var q = ('string' == typeof a[i]) ? '"' : '';
sArgs+=((i>0) ? ', ' : '')+(typeof a[i])+' '+aArgs[i]+':'+q+a[i]+q+'';
}
return '('+sArgs+')';
}
var watchTitle = function(id, oldval, newval) { showCallStack(); }
// !! This is all you should need to update, setting it to whatever you want to watch.
document.watch("title", watchTitle);
Right-click page, and choose to view the page's source
Find <script> tags
Look for $("#buy") and something mentioning onClick or .on("click",function(){...});
If you can't find it, search for something along these lines: document.getElementById("buy")
You have found the function, or code, where the event handler code is
$("#buy") is JQuery's way of saying find an element that has an id attribute of buy and if it has a . following it with some function, that function is acting upon the element that was found by JQuery.
First off, I don't want another plugin to do this... jQuery already has the functionality to do 99% of what I want with the live() method.
Basically, I want to change this:
$(".some-button").live("click", function() { alert('yay!'); });
into this:
$(".some-button").live(function() { alert('yay!'); });
So, what I'm saying is that I want to fire a method right away when an element is added to the page... jQuery can already do this SOOO close because that's how it adds the "click" even in my example above!
How can I achieve this without adding another plugin, but rather, just by using the same functionality as the "live" and "die" methods do?
Here's some code I've copied and pasted that seems to work in fiddle, at least on FF: http://jsfiddle.net/KQBzn/
$(document).bind('DOMNodeInserted', function(event) {
alert('inserted ' + event.target.nodeName + // new node
' in ' + event.relatedNode.nodeName); // parent
});
source: http://forum.jquery.com/topic/how-to-get-notified-when-new-dom-elements-are-added
There isn't any cross-browser way to do this, and there's nothing in jQuery itself that allows it.
You'd have to use a plugin, or just manage invoking code for your new elements manually.
The the live()[docs] method and the delegate()[docs] method are only for event handling. The code you give them will only respond to browser events, not to DOM manipulation.
The reason .live() won't do this is because it does not run any code when adding new elements to the DOM. It isn't monitoring any DOM changes. Rather it is responding to events that bubble to the document, and invoking the handler if it matches the selector you gave it.
You can't do it with the .live() method.
It seems jQuery should add a feature to the .live() method so that if its used with a specific keyword like 'created' instead of an event name then it will let you execute a function for the created element. That'd be cool! For example, the ideal scenario would be like this:
$('.foobar').live('created', function() {
// do something with each newly created .foobar element here.
});
I have a problem that happens only on a specific computer(FFX 3.6.13,Windows 7,jQuery 1.4.3).
Sometimes document.ready is fired but when trying to get elements to attach the event handlers,the elements don't exist!
the code goes something like this:
$(function(){
window.initStart = true;
$("#id_of_element").click(function()...);
window.initEnd = $("#id_of_element");
});
the window.initStart/End are there for debugging,sometimes this code runs just fine,but sometimes window.initEnd is just a empty jQuery set(length == 0).
What this means is that document.ready is always fired,but sometimes it is fired before elements are available.
Does anybody had this problem? what could the problem be?
One way that you could try to get around this would be with using .live instead of .click. The following code
$('#idOfDiv').live('click', function() { doStuff(); });
will attach the input function to the click event of everything that is dropped on the page with an id of 'idOfDiv' as soon as it makes it to the page. Whereas .click executes immediately, this should be attached no matter what time the divs make it to the page.
Cheers
There's an article on SitePoint that demonstrates how to sense when certain dom elements are available.
Also I know this is a version specific issue, but if you were on Jquery 1.5 the deferred objects stuff would be useful here.