Two event Listeners overlapping Javascript - javascript

document.querySelector(".profile_icon").addEventListener("click",function(e){
document.querySelector(".profile").classList.add("show");
});
document.addEventListener('mouseup',function(e){
var container = document.getElementById('profile');
if(!container.contains(e.target)){
document.querySelector(".profile").classList.remove("show");
}
});
When i click on profile icon the drop drop appears but if i click on icon again, it doesnt disappear as window event listener overlaps with the icon event listener. I want the menu to close both when user clicks outise the profile box as well as on the icon button.

You are always adding the class and never removing it in the icon event handler
Try using toggle() instead of add()
document.querySelector(".profile_icon").addEventListener("click",function(e){
document.querySelector(".profile").classList.toggle("show");
});

You only need to change mouseup to mousedown event. If you use the mouse up, click on the profile icon will add the show class and mouseup will be activated just when you raise your hand. But in this scenario, if you use the mousedown event, your next move will be processed good than that.
document.addEventListener('mousedown',function(e){ // Only change this line.
var container = document.getElementById('profile');
if(!container.contains(e.target)){
document.querySelector(".profile").classList.remove("show");
}
});

Related

JavaScript Bind Event at Certain Time

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();
});

How to disable all click actions for context menu abort?

We have custom context menus that replace the browser menus on right click. We would like to be able to abort (hide) the context menu in the same way that the default context menu is hidden by the browser- a click anywhere outside the menu that does not register as a click. The solution should apply to both bound events and default browser actions, but not impede the ability for other events, ie. hover from firing.
An example:
In firefox, right click on this page to open the context menu. Hover over the
Questions-Tags-Users-Badges-Unanswered
at the top of this page. Even though the context menu is open, highlighting still occurs. Now, click on a text area on this page, like the search box at the top. The context menu will hide, but your cursor will not focus the text box (unless you click it again with the menu closed).
How can we emulate this behaviour in JavaScript?
Rejected options we've considered:
Use a transparent div over the whole page. Problem: This can capture clicks anywhere, but breaks hover events and hover css.
Check for a context-menu-open variable in each click handler, and assign handlers to all links, and input elements to detect the context menu open state, which closes the context menu, unset the open state and prevents the handlers default. Problem: Very sloppy code and a maintenance nightmare.
Consider a variation of rejected option #2, where you have a single event listener on the document.
document.addEventListener('click', function (e) {
if (contextMenuOpen) {
e.preventDefault();
e.stopPropagation();
}
}, true);
For more information about that true, look up useCapture and event flow.
Guest was on the right track with event capture, but the solution had a few glitches. This is a more robust solution that solves the following problems:
Don't immediately close the menu in the right click event that fires right after context menu.
Don't let text fields get focused when the context menu is open- the focus event fires first and is not caught by a capture click event. We need to setup a capture handler on focus too.
Deal with the problems created by having a focus and click handler, which both fire.
To do this, you need two capture event handlers:
document.addEventListener('focus', function(e){eDocumentFocusCapture(e)}, true);
document.addEventListener('click', function(e){eDocumentClickCapture(e)}, true);
// If the context menu is open, ignore the focus event.
eDocumentFocusCapture = function(e){
if(RowContextMenuIsOpen){
console.log('focus event sees the menu open: cancel focus, but leave menu be. Click will take care of closing it.');
e.stopImmediatePropagation();
e.preventDefault();
e.target.blur(); // tell the clicked element it is not focused, otherwise you can't focus it until you click elsewhere first!
}
}
eDocumentClickCapture = function(e){
// A right click fires immediatly after context menu is fired,
// we prevent the menu from closing immediately by skipping one right click event
if(RowContextMenuWasJustOpened===true && e.button===2){
console.log('right click self bypass');
RowContextMenuWasJustOpened=false;
return;
}
if(this.protected.RowContextMenuIsOpen){
console.log('click event sees menu open, I will close it.');
this.HideRowContextMenu();
e.stopImmediatePropagation();
e.preventDefault();
}
}

Detecting a Click on Stage but not on Shape in KineticJS

In KineticJS, how do you detect a Click event where the click occurs outside an object/shape?
I am trying to get a Rect to change its scale to 2 when a user clicks on it, and return back to a scale of 1 when the user clicks anywhere outside it.
JSfiddle: http://jsfiddle.net/ABTAD/8/
Managed to detect a click on stage, but clicking on the Rect also fires the click handler!!! And somehow the .setScale(1) does not do anything, while console.log printes something out. How can I prevent the click handler from firing when the click is made on the Rect instead of the empty stage?
JS Code to detect click on stage
window.stage.getContainer().addEventListener('click', function(e) {
$.each(window.layer.get('.box'), function(index, box) {
box.setScale(1);
console.log('clicked on stage');
});
});
you can access the stage content wrapper with stage.getContent(). From there, you can add an event handler like this:
stage.getContent().addEventListener('click', ...); // regular javascript
or
$(stage.getContent()).on('click', ...); // jquery

Opening a popbox when clicking a button

The PopBox plugin is useful for having a text area pop up in its own window when you click within a text area. However, I want a PopBox to appear when the user clicks a button, rather than within a text area. Is there a way to modify the PopBox functionality for this?
tl;dr: I want the PopBox to pop when a function is called rather than when clicking inside a text area
If you look at the popBox source, you'll see that when popBox is applied to an element (via $('#yourElement')).popBox(), there is a focus event bound to it:
obj.focus(function () { $(this).next(".popBox-holder").show(); var
popBoxContainer = $(this).next().next(".popBox-container");
// ...edited for brevity...
});
Attach a click event to your button and, within that, trigger the popBox by triggering the above mentioned focus event:
// Attach a click event handler to your button
$('#yourButton').click(function(){
// Trigger the "focus" event on the popBox element
$('#yourElement').triggerHandler('focus');
});
See a working demo here
Obviously, you can modify this to fit your needs - e.g. hiding the initial textarea or input if you don't want it displayed.

Restoring hover state after click for custom CSS buttons in JavaScript?

I have a CSS button that has normal, pressed and hover states. Everything works fine except that when the click has happened, I need to somehow know whether the style should be set to normal or hover. That is, I need a way of knowing if the mouse cursor is still hovering the element. How would one achieve this with JavaScript?
If you're concerned about the user doing a mousedown, then moving the pointer off (and perhaps on again) the button, you could do something like this:
EXAMPLE: http://jsfiddle.net/7zUaj/1/
var mouseIsDown = false; // Track/remember mouse up/down state for the button
// Handle mouseenter and mouseleave
$('div').hover(function() {
$(this).addClass('hover');
if (mouseIsDown)
$(this).addClass('pressed'); // If mouse button was down, and user exited
// and reentered the button, add "pressed"
}, function() {
$(this).removeClass('hover pressed'); // Remove both hover and pressed when
// the pointer leaves the button
})
// Handle the mousedown, track that it is down, and add "pressed" class
.mousedown(function() {
mouseIsDown = true;
$(this).addClass('pressed');
})
// Handle the mouseup, track that it is now up, and remove the "pressed" class
.mouseup(function() {
mouseIsDown = false;
$(this).removeClass('pressed');
});
// If user does mousedown, leaves the button, and does mouseup,
// track that it is now up
$(document).mouseup(function() {
mouseIsDown = false;
});​
The state of the mouse is tracked in a variable and set in the button's handlers for mousedown and mouseup. The mouseup is also tracked at the document level. This will help the mouseenter part of the .hover() to know if it should set the pressed class or not.
(Note that because the mouseup is also tracked on the document, if there are any other elements on the page that stop the event from bubbling, the mouseup would not be detected by the document.)
EDIT: Made it so the document only tracks mouseup, and the button tracks both.
You don't have a :visited state in your CSS? As for Javascript, OnMouseOver or JQuery mouseover, hover or mouseenter (depending on what you want to do) will tell you when the hover is happening.

Categories

Resources