I have document.addEventListener('mousedown', ...) performing some visual feedback to the user. But I also have dynamicaly created elements with elem.addEventListener('click') which are not fired. If I remove document mousedown listener then clicks on elements are triggered (or if I change document's mousedown to click event). Why is that and how to solve this? I would realy need document to handle mousedown and still be able for elements to recieve their click/tap events.
FIDDLE: http://codepen.io/hpet/pen/izpJK
if you uncomment document mousedown event, element receives click ok, otherwise click on element is never triggered.
Fiddle updated. Uncomment lines 22/23 (setting position) will not fire click event.
The root cause of your problem is overlapping elements.
Since you're moving the circle element on top of the square element in your mousedown handler, the subsequent mouseup event will be triggered on the circle. Since that event was not triggered on the square element, no click event will be generated.
If you have to keep the circle element on top of the square, you can use the pointer-events CSS rule to force mouse events to "go through" the circle element.
Related
I have a seemingly trivial problem but cannot find the cause. There is a minimal html structure:
<div id="bg">
<div id="panel"></div>
<div id="helper"></div>
</div>
Element #helper has display:none, and on mousedown event on #panel I set dipslay:block on #helper.
The problem can be described briefly like this: when I click inside element #panel, the click event always fires on element #bg, despite all effort to stop the event propagation on event handlers on #panel and #helper. I made a codepen to illustrate the problem:
https://codepen.io/tony124/pen/LYpQzwx?editors=1111
when I click outside of #panel, I get in console:
"onMouseDownBg" "bg" "bg"
"onMouseUpBg" "bg" "bg"
"onClickBg" "bg" "bg"
which is to be expected. However when I click on #panel, I get
"onMouseDownPanel (stop)" "panel" "panel"
"onMouseUpHelper (stop)" "helper" "helper"
"onClickBg" "bg" "bg"
which I cannot understand why. There is even no logging from onMouseDownBg and noMouseUpBg. How did the click event can ever fire?
It's about the order in which the events get called in and the actions taking place within the handlers.
onMouseDown event:
event is consumed & cancelled by #panel.
#helper becomes active
onMouseUp event:
event is consumed & cancelled by #helper.
#helper becomes inactive
onClick event:
From MDN:
An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element. If the button is pressed on one element and the pointer is moved outside the element before the button is released, the event is fired on the most specific ancestor element that contained both elements.
(emphasis mine)
In this case, the most specific ancestor element would be #bg, thus it handles the click event.
To get the effect you're probably looking for, just move the activation of the #helper element to the onMouseUpPanel handler
Because your onMouseDownPanel function makes <div id="helper"> as display block and as you release mouse button because helper was visible and due to positioning it is triggering onMouseUpHelper and finally as they are all children of bg it calls onClickBg
I have a table where i have bound all my elements with class="shift" to a click function.
Now, because I also need to use another click event on part of the element, I would like to unbind the click event on element when the mouse enters the element and rebind when i leaves (meant for some touch events and whatnot)
Now, I bind like this
$("table").on("touchstart mousedown",".shift", function(e){ ... })
But when i try to unbind on a specific element, say it has a class="selected" added to distinguish the current element i use:
$("table").off("touchstart mousedown",".shift.selected")
which does not work....
I can remove all the handlers at once, but it would be wasteful to remove all the handlers and reinsert them as soon as the mouse leaves.
So, is there a way to remove the handler on a single element after the event is bound to all current and future elements?
Thanks in advance!
You don't need to unbind the click event on the element when the mouse enters. I know, the element click event will trigger when you click an inner element with the click event bound, right ? you can stop that:
The click handler of the inner element must look like this:
$("some inner element").click(function(event) {
//That's what are you looking for ;)
event.stopPropagation();
//You code here
});
event.stopPropagation() will prevent the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
Is there any (css or dom) property that could be set on a DIV element or any other clean/standard way to avoid firing a click event when the mouse is moved after the mousedown?
Suppose there is one div element within another div. The goal is to prevent the click event on the parent also when the mouse is moved on its (smaller) descendant (to avoid event handling on descendants).
With no prevention, mousedown + mousemove + mouseup fires a click event.
The goal is either kind of mousemove "aborts" the mousedown on the element or prevents the click after mouseup
I am having a problem with my Javascript code for Android tablets.
Suppose I have grid made of several div tags. with class "box";
Now I bind event handlers for all these divs in the grid.
When the touchstart (mousedown) event occurs and I move the cursor to some other div in the grid (without releasing the cursor) and then release the cursor (touchend) on this current div. When I tried to alert the id of this current div (i.e. touchend div), the alert shows the id of the div where the "touchstart" has occurred.
$(".box").bind('touchstart',function () {alert($(this).attr("id"))});
$(".box").bind('touchend',function () {alert($(this).attr("id"))});
Actually this is my first program for the Android tablet. So I need help for this.
This is expected and it would be be very confusing if it did anything else. If the element it ended up on did not have a registered listener you would never get the touchEnd event at all.
You can see where the touch went by looking at the coordinate properties of the touches and you can track it in progress with touchmove.
Don't really get your question. Are you trying to get the alert to display the div id of where you mousedown? You will need to store the id in the touchstart event in a variable and display the value when touchend has occured.
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.