JavaScript event handler - javascript

I am trying to fix a bug with the mouseenter and mouseleave handler.
listener.addEventListener('mouseenter', function(){
element.style.visibility = "visible";
}, true);
listener.addEventListener('mouseleave', function(){
element.style.visibility = "hidden";
}, true);
The events work as expected except for when i am moving the mouse over the element it flashes the mouse leave event.
Any fixes for this?
Plain javascript solutions only, please (no 3rd party libraries).

The pointer in Javascript is only "hovering" the topmost (visible) element.
This means that if you've say a background div and when "entering" it you display another div on top of it the cursor will exit the background to enter the new div.
May be you can just set opacity to 0 instead of hiding the div and leave it always "visible" (also placing the event handler in the appearing div, not in the background one).

There is property named relatedTarget in the mouse event, which would help you fix it. you should check if it is not in the area like:
listener.addEventListener('mouseleave', function(event){
if(!event.relatedTarget ||
(event.relatedTarget != listener && event.relatedTarget.parentNode != listener))
element.style.visibility = "visible";
else
alert("I am still in listener area but mouseleave got triggered :)))");
}, true);
The point here is I have checked only for the first parent level, but you better create a function to check it for all the DOM tree in the listener node. I mean it could be one of the nested childNodes in the listener node.
I know it seems kind of weird, but it is the way it is, sometimes when it enters to a child nodes area mouseleave gets triggered.

Related

Unexpected ionicons behaviour

Consider this code.
I cannot figure out why it behaves as it does. All I need is the play icon alternating with pause icon everytime I click anywhere inside the <td>. It behaves as expected when I click inside the <td> but outside the icon itself. However, if I click on the icon itself, it behaves fine the first time, and then stops.
'The ionicon is wrapped in the <a> tag, which is a child of the <td> element. The event listener is on the <td>, so what could be the problem?
Thanks.
As #Vijai said your problem with the hover event .. And While I don't know a lot about your project and you really need .empty() on hover or you just need to hide() the icon .. You can try this part of code instead of yours
var hovOn = function(event) {
if($(this).find('a').length < 1){
$(this).html(playButtonTemplate);
}else{
$(this).find('a').show();
}
};
var hovOff = function(event) {
$(this).find('a').hide();
}
Codepen Here
Ok, figured it out. It seems like an artefact that arises from creating an element from a template and the way mouseenter is implemented.
The problem is that the mouseenter event (hoverOn part of the .hover()) triggers when it shouldn't. Each time a new ionicon is created from a template it will trigger the mouseenter event if the cursor moves a little.
Logically mouseenter shouldn't be triggered when the element appears, because mouseenter should trigger when a listener element or its descendent is hovered over, and then only call when the cursor leaves all of the elements associated with the event and then enters again. I think this is an artefact of creating an element from a template like that. Maybe it's because DOM get updated and it discards the fact that the cursor is already within the element. So mouseenter triggers again and in turn triggers creating a new play icon. Then it repeats..
This codepen should explain it well. If you hover over the play button the mouseenter counter will increment each time you move your mouse even a little, because each time a mouse is moved, a new play button is created. If you delete the line that creates a new play button, it behaves as mouseenter should, triggering only when the cursor enters the element.
When you click on the <a> tag it seems it is also triggering the parent <td> hover event. Once solution is try the below code for hover.
var hovOn = function(event) {
if(playOrPause==='play') {
$(this).html(pauseButtonTemplate);
playOrPause = 'pause';
} else {
$(this).html(playButtonTemplate);
playOrPause = 'play';
}
};

JavasScript changing DOM in mouse-event

I have 2 DIVs and in each DIV there's a Button which does something on click.
Now I've added a piece of code to bring the DIVs to front when they get a mousedown. Which works very well. The problem is, that they swallow the mousedown of the inner button... The inner button can only be clicked by double clicking it.
http://jsfiddle.net/nUtz6/
$('div').mousedown(function (event) {
$(this).parent().append($(this));
});
how could I solve this problem? I did it this way because I don't want to increment the z-index of the CSS property to some magic number everytime I click the div. I read that jquery also does the DOM manipulation trick.
The problem seems to occur because I change the DOM right before the click-Event of the button. If I don't do anything in the mousedown, everything works fine.
Just check that the DIV is actually the target of the event :
$('div').mousedown(function (event) {
if (event.target.tagName.toLowerCase() != 'button')
$(this).parent().append($(this));
});
FIDDLE

Disable mouse events on overlapping divs without pointer-events

I have a div with a onClick event, but it's not detecting the mouse because of an overlapping div. I can't put it below the 1st one, so changing the z-index isn't an option.
Is there any way to disable the mouse events on the 2nd div without the pointer-events? I need this to be cross-browser.
Requested sample. Right now all the event does is fire an alert:
<div class="buttonDiv" onClick="buttonAction()"></div>
<div class="filterDiv"></div>
You can try this:
HTML
<div class="buttonDiv" onClick="buttonAction(event)">
OUTER
<div class="filterDiv">INNER</div>
</div>
Javascript
var buttonAction = function(e) {
if(e.target.className == "buttonDiv") {
//code here
alert('got here');
}
}
Example: http://jsfiddle.net/aFRcd/1/
Basically on the click, you send along the click event and then you can see which div was actually clicked using event.target
You'll notice in the example that clicking on OUTER fires the alert whereas INNER does not.
The only solution I could find was having a Mouse Move event attached to the canvas and compare the coordinates of the button to the position and dimensions of the buttons. It's a pain, but at least it does the job

How do I hide a div if the user clicks outside of the div?

I have a button which, when clicked, changes the visibility of a div as such:
<button type="button" id="editbutton" onclick="plus()" alt="Edit"></button>
function plus() {
var f = document.getElementById('edit');
if (f.style.visibility == 'hidden') {
f.style.visibility = 'visible';
}
else
f.style.visibility = 'hidden';
}
This works fine. But now I want to add the functionality so that if the user clicks anywhere outside of the div, the div will go back to being hidden.
Initially I tried my own methods, but was unsuccessful because whenever I click the button to make the div visible, it is made hidden again by the new code. I've looked into some of the jQuery examples others have posted, however none of the ones I have tried fix this problem. Any help would me much appreciated.
EDIT: To clarify, the issue is that because the div is initially made visible by the user clicking on a button, whenever I click the button, the div is made visible but is immediately hidden again because that counts as clicking on the body of the page.
You could call 'e.stopPropagation()' on the event from within your click event handler when a user clicks within your div - this will stop the event from 'bubbling' up the DOM.
And then if you attach an event handler to the BODY element listening for clicks, you can use that event handler to hide the DIV; knowing that a click on the DIV itself won't bubble the event up to the BODY handler.
In this way any click on another element, unless the handler also calls stopPropagation(), will get caught by your handler. So if there are other cases where you don't want the div to hide you can stop it happening by calling stopPropagation() as required.
E.g.:
$("#edit-button").click( function(e) {
$("#edit").toggle();
e.stopPropagation();
});
$('#edit').click(function(e) {
e.stopPropagation();
});
$("body").click( function(e) {
$("#edit").hide();
});
Set a click handler on the body element. In the event you can check event.target to see if it matches the div, if it does: do nothing, else: hide it.
document.body.onclick = function(event) {
if (event.target === f) {
// user clicked on the div, do nothing
} else {
f.style.visibility = "hidden";
}
};
This becomes a bit more complex if you have elements within the edit div (and the .target doesn't match), but I'm sure you can come up with a solution :) (it can be done).
you seem like you know what you're doing so I'll keep it short.
write a .click function in jquery.
you give your button an id (or the div it is in)
$('#buttonidordiv').click(function(){
$('#divtoshow').show() // put in a number to create a fade in seconds.
//your stuff here
}
and if someone clicks anywhere outside it... I think you should be able to use window. Else you can use another div (like your wrapper).
so
$('window').click(function(){
$('#samediv').hide() //same as above
//your stuff here
}
do realize, I suck with the )}; so you might have to add one of those somewhere ;)
best of luck!

jQuery blur handler not working on div element?

I don't understand why the jQuery blur handler isn't working in the most simple case. I'm literally creating a div 100px by 100px and setting a blur event on it, but it's not firing (JSFiddle):
<div id="test">this is a test</div>
$(document).ready(function() {
$('#test').bind('blur', function() {
alert('blur event!');
});
});
Is my understanding of blur wrong? I expect the blur event to fire when I click anywhere that is not the div...right?
According to jQuery's documentation:
In recent browsers, the domain of the event has been extended to
include all element types. An element can lose focus via keyboard
commands, such as the Tab key, or by mouse clicks elsewhere on the
page.
I've tried it on the latest Chrome and Firefox on Mac.
From the W3C DOM Events specification:
focus
The focus event occurs when an element receives focus either via a pointing device or by
tabbing navigation. This event is valid for the following elements: LABEL, INPUT, SELECT,
TEXTAREA, and BUTTON.
blur
The blur event occurs when an element loses focus either via the pointing device or by
tabbing navigation. This event is valid for the following elements: LABEL, INPUT, SELECT,
TEXTAREA, and BUTTON.
The jQuery docs state browsers extended the events to other elements, which I'm guessing means blur and focus are aliases for the more generic DOMFocusIn and DOMFocusOut events. Non-input elements aren't eligible to receive those by default though, and an element has to somehow gain focus before losing it - a blur still won't fire for every click outside the div.
This SO question mentions that giving an element a tabindex would allow that, and seems to work for me in Chrome after modifying your jsFiddle. (Albeit with a fairly ugly outline.)
As far as I knew, blur happens on inputs that had the focus, either way you say
I expect the blur event to fire when I click anywhere that is not the div...right?
Not exactly, the blur event only happens for an element that had the focus first
So in order for a blur event to occur, you would first have to give focus to the div, how is the div getting focus first?
If you are really try to determine if there was a click outside of your div, you need to attach a click handler to the document, and then check to see where your click came from.
var div_id = "#my_div";
var outsideDivClick = function (event) {
var target = event.target || event.srcElement;
var box = jQuery(div_id);
do {
if (box[0] == target) {
// Click occured inside the box, do nothing.
return;
}
target = target.parentNode;
} while (target);
}
jQuery(document).click(outsideDivClick);
Just remember that this handler will be run for EVERY click on the page. (in the past if i ha to use something like this, i attach the handler when I need it, and remove it when I no longer need to look for it)
A can't "blur" because that would involve the div having focus in the first place. Non-input elements like a and textarea can have focus, which is what jQuery's documentation refers to.
What you need is the "mouseout" or "mouseleave" event (mouseleave doesn't bubble, mouseout does), which will be fired when the cursor leaves the div. If you need to have clicks, I would attach a "click" event to the body, as well as the div and stopping the event propagation on only the div:
$("div").click(function(e) {
return false; // stop propagation
});
Or, if you're really determined, you can fake the appearance of a div with a and some CSS rules :)
If you want something to happen while you move your mouse over the box, you could use the mouseover event.

Categories

Resources