I'm trying to implement the following functionality and am having some trouble. What I want is when a user clicks a certain image, a popup div will appear containing some information about that image. Then if the user were to click anywhere on the page outside of that popup div, it would simply hide and then remove the popup.
What I am trying to do is register an eventListener after the popUp div is added to the page. Tried with both jquery and without and am after the same issue. (I included both below but only one is active in the code at a time.)
createProfilePopUpEventListener: function(){
$('body').on('click', function(){
$('.profile_pop_up').fadeOut('fast').remove();
});
},
createProfilePopUpEventListener: function(){
var el = document.getElementsByTagName('body')[0];
el.addEventListener("click", $('.profile_pop_up').fadeOut('fast').remove();
},
showPopUp: function(e){
//creates popUp and adds it to the DOM
this.createProfilePopUpEventListener();
}
What seems to be happening is that the event is being triggered right away on the initial click to show the popup and thus it is never displayed. How can I create an eventListener that only starts listening for those clicks at a certain time?
I guess your problem is event propagation. Your image that is used as the trigger to open the popup bubbles your event up the whole DOM, eventually to the body. Thus the fadeout/remove event is triggered at the same time as your open event.
You will need to stop the propagation of that in such a fashion (using :
$('#popup_trigger').on('click', function(event){
event.stopPropagation();
$('.profile_pop_up').fadeIn();
});
Related
I'm making a popup menu. The user clicks on it to show the menu, then if they click outside the popup menu I want to hide it.
I can find many solutions (most popular is here: How do I detect a click outside an element?) but they all seem to have the same issue.
They rely on handling clicks that bubble up to the window element.
Their Logic:
All clicks bubble up to window element. Handle those clicks - if menu is open, then close it. Also call preventDefault to stop any links being followed (let's just say that the user happens to click on a link when they are clicking outside the menu - we don't want to follow that link)
$(window).click(function(e) {
if (!e.isDefaultPrevented()) {
if($('.mainNav').hasClass('menuVisible')){
//stop any other actions happening (e.g. following a link)
e.preventDefault();
//Hide the menus
$('.mainNav').removeClass('menuVisible');
}
}
});
The issue
If the thing the user clicks on happens to have an onclick event itself then that code still gets fired. Elements lower down the tree get the click even first, so I cannot use preventDefault or stopPropagation to stop these events..
Any ideas how to fix it? My only idea is to put a transparent div across the whole screen on top of everything to catch the clicks first?
You need to use addEventListener() and the useCapture property. the useCapture property allows events from object higher in the DOM tree to be triggered first. You can then prevent your normal click behaviour from occurring:
var button = document.getElementById("myButton");
var response = document.getElementById("myResponse");
var windowClick = function (evt) {
response.innerHTML += "<p>The Window</p>";
evt.stopPropagation ();
}
var buttonClick = function (evt) {
response.innerHTML += "<p>The Button</p>";
evt.stopPropagation ();
}
button.addEventListener("click", buttonClick);
// If true, the window event fires first, if false, the button fires first.
var useCapture = true;
window.addEventListener("click", windowClick, useCapture);
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<button id="myButton">Hello!</button>
<div id="myResponse">Who Clicked?</div>
</body>
</html>
Updated
I originally misunderstood that we were trying to stop inline onclick events from firing. I found a potential solution from another StackOverflow question, you can see it here.
Otherwise, take a look at this:
$('button[onclick]').each(function(){
$(this).data('onclick', this.onclick);
this.onclick = function(event) {
if($('.mainNav').hasClass('menuVisible')) {
return false;
};
$(this).data('onclick').call(this, event || window.event);
};
});
It overrides the elements click handler. I've updated your jsFiddle to show it in action.
you can add a class to the body when menu is opened, and attach an event listener to the click event of body which will hide the menu and remove the listener
when showing the menu
$('body').addClass('menu-open');
$('body.menu-open').one('click', function(e) {
e.preventDefault();
// code to hide your menu goes here
$('body').removeClass('menu-open');
});
Note the usage of .one for attaching the event handler. It automatically removes the event handler after it is executed once.
Ref https://api.jquery.com/one/
Some code that looks like the following is firing the click event via the Enter key, but is not responding to the mouse click.
//a is an anchor element
a.addEventListener('click', function (e)
{
//Do Stuff...
});
This page demonstrates the problem. The relevant bit of code is at line 176. This is in the middle of development and currently only (sort of) works in Chrome.
Also, I just verified that it works if I use mousedown, so it's not just the case of an invisible element sitting in front of the anchor.
Any ideas?
Edit: Now that you've shown us the actual code you're using, the problem is related to the fact that the autoSuggest() function has it's own click handler and in that click handler, it is clearing the container which removes all <a> elements in the container so your link object gets destroyed (probably before your click event gets to process). So, you can get events that happen before the click (like mousedown), but after a click, the element is removed from the DOM.
If you tell us what you're trying to actually do when an auto-suggest item is clicked that is different than the default behavior of the autoSuggest() function and you point to any documentation for that function, then perhaps we could offer a better way to solve your issue.
The link may be firing and taking you off to a new page (or reloading the current page), thus preventing you from seeing the click code run. Usually when you process a click event on a link element, you need to prevent the default behavior:
//a is an anchor element
a.addEventListener('click', function (e) {
e.preventDefault();
//Do Stuff...
});
Another possibility is that you are trying to install the event handler too soon either before the DOM has been loaded or before this particular link has been created and thus no actual click event handler is attached to the DOM object. You can verify whether the event handler is even getting called by temporarily putting an alert("Click handler called"); in the event handler and see if that pops up or not.
I have a very simple click handler that makes an AJAX GET request on click like so:
$('span.switch-option').click(function() {
$(this).parents('div.log-in-option').hide();
$(this).parents('div.log-in-option').siblings('div.log-in-option').fadeIn();
});
This works perfectly anywhere else on the website. However, when I try to click a <span> element with the class switch-option inside a modal window, the event does not fire. Entering the contents of the click-handler function in the console and running them does perform the desired behavior, however.
Why will the click handler not fire in this modal window? I am using the popular SimpleModal plugin http://www.ericmmartin.com/projects/simplemodal/ and jQuery 1.9.1.
A live example is here: http://ec2-107-22-8-70.compute-1.amazonaws.com/thread/19. If you click the 50,000 reps or any user's reputation then try to click the big blue link in the dialog, the click handler does not fire. This behavior happens with other click handlers in different modal windows as well.
When your script(main.js) is running the elements 'li.log-in, a.log-in' does not exists in the dom, they are loaded dynamically when the popup is created thus jQuery is not able to bind the event handlers
Try event propagation
$(document).on('click', 'li.log-in, a.log-in', function() {
$.get('/login/', function(data) {
//make a modal window with the html
$.modal(data);
});
return false;
});
I have a gallery type of interface that I'm trying to get to work, I want to be able to click outside of it to close it, however there is a div inside that contains the main elements, photos, and things to click. However as it is now when you click inside the div it closes, because it's a child in the element that when you click it closes.
I have the divs like this:
<div class="theater-wrapper">
<div class="theater-container"></div>
</div>
everything is loaded into theater-container via ajax.
When you click .theater-wrapper it should fire the event to close, however when you click theater-container it shouldn't.
This is how I have tried to close it:
$(".theater-wrapper").click(function (event) {
$('.theater-wrapper').hide();
event.stopPropagation();
});
I have a jsfiddle showing this in action: http://jsfiddle.net/Cs8Kq/1/
If you want to stop propagation of the click event on .theater-container, then that's where you need to put the command. Right now you have it applied to the .theater-wrapper click action.
$(".theater-container").click(function (ev) {
ev.stopPropagation();
});
I have an application that works like a virtual desktop (icons in a horizontal bar in the bottom). When you click on an icon, a window opens (dynamically created). If you click on another (or the same) icon another window opens 10px down and 10px to the right from the last one, and is moved on the top.
When a window gets created, the function below runs adding a click event to the window. If the window is clicked it gets moved to the top.
Now to the problem. One of the windows contains thumbnails of images. When clicking on an image a new window gets created with the image in full size. I want the new window with the full size image to be placed on top, which doesn't happen because the event (in the moveOnTop function) fires after the new window is created on the thumbnail window (because I clicked that window when I clicked on a thumbnail).
I guess one way to solve this would be if it was possible to prevent the event to be fired if a thumbnail is clicked, though I don't know how. What could otherwise be a good way to solve this? Thanks in advance!
Windows.prototype.moveOnTop = function(){
var container = '#desktop';
$(container).on('click', '.window', function() {
var thisWindow = $(this);
if(thisWindow.next().length > 0){
thisWindow.appendTo('#desktop');
}
});
};
Inside the click event handler for thumbnails you can cancel the the event for other (parent) elements:
$("img.thumbnail").on("click", function(e) {
...
// Finally, prevent the click event from bubbling up to parent elements
e.stopPropagation();
});
See: event.stopPropagation()
That depends on the situation. If both cases are handled by the same event handler, you can simply compare against event.target.
If, on the other hand, you've bound another event handler to the click event of the icon and you're trying to prevent the window's click event from firing when an icon is clicked, you can either let the event handler return false or call event.stopPropagation(), like so:
$('.icon').click(function(event) { // <-- parameter 'event' is automatically passed to handlers
// Open window with icons
event.stopPropagation();
});
NB: from what I can tell, you're still (re-)attaching the click handler to all windows in the moveOnTop function. See my answer to your previous question for a solution.