I have created a very simple jQuery "dropdown list" that consists of two div elements. When the first div is clicked, the second div is displayed. Now I want the second div to be closed again, when I click outside that div. But I can't (and actually don't want to, if it's not necessary) use a document- or body-event-listener like this:
$('#div2').click(function(e) {
doSomething();
e.stopPropagation();
});
$(document).click(function() {
$("#div2").hide();
});
Reason: I have other elements on the page that use e.stopPropagation();
and if a user clicked on those elements after opening the dropdown, it wouldn't close again.
I found this plugin, jALDropdown, that somehow handled to close the dropdown even if I click on e.stopPropagation();
, or even somewhere outside the page or the browser, and it doesn't seem to use any document/body-event-listener: http://india.assigninfo.com/assignlabs/jaldropdown
Sorrily it's not working with Opera, so I can't use it. And I didn't find a version of the sourcecode that was not minimized, thus I was not able to find out how it works.
Do you have any ideas how to archieve this behaviour, so that the dropdown closes (element is hidden) if I click outside the element, page or even browser, without a document/body-event-listener? Thanks!
Why not keep the $(document).click() function to hide your division, then add this function to your code and call it instead of event.stopPropagation():
function stopPropAndCloseDiv2(event) {
$('#div2').hide();
event.stopPropagation();
};
I tested it, and it seems that it would work fine. You'd just have to remember to use it.
UPDATE:
This gnawed at me, and I found another answer on this great website I know. Here's the link:
add code to a function programatically with JS
I tried that approach and it seems to work: http://jsfiddle.net/kXkFS/8/
Here's the code (there are two buttons in the test page markup):
jQuery.Event.prototype.stopPropagation = (function() {
var cached_function = jQuery.Event.prototype.stopPropagation;
return function() {
if ( this.type == "click") {
// Your logic here.
console.log("I am a modified version of event.stopPropagation()!");
}
cached_function.apply(this, arguments); // use .apply() to call it.
};
}());
$(document).click( function() { console.log("The document caught the event, too."); });
$('#clicker').click( function() { console.log("I'm going to let this event bubble."); });
$('#anotherClicker').click( function(event) { event.stopPropagation(); });
Spoiler: when you click the "clicker" button, the document logs to the console also. When you click the "anotherClicker" button, the custom event.stopPropagation() function logs to the console, and the document doesn't log to the console. Now, you can add your click event handler to the document.
One thing: this might add some overhead, but only if you're calling stopPropagation() pretty darned often.
If anybody wants to weigh in on the wisdom of screwing with the jQuery object like this, please do so. I wonder, but I can't see that an innocuous change such as this one will blow up the web page in the future.