I'm trying to track which element gets focus in a web app. I came across the monitorEvents API, but I'm having difficulty using it for control or focus events. Other events on body are working as expected, but not the control events. Any advice?
I'm not sure how exactly you want to "monitor" control events, but you can set event listener breakpoints on the entire category, or individual events like focus. Whenever a focus listener runs for any node on the page, DevTools pauses on the first line of the listener.
I was trying to monitor focus and blur events on the entire document today.
When using monitorEvents(document.body, 'control') I would only see the event fired when I left the tab entirely and then refocused. I believe what's happening is that once you're focused on the body, it'll never change when you focus on child elements since the listener is at a high level and the events just bubble up to the body with no change in focus.
I tried monitoring events on a few specific child elements and saw that those triggered how I expected. So I decided to add an event listener to each element in the document and that worked well. Here's the one-liner for that.
document.querySelectorAll("*").forEach((el)=> monitorEvents(el, 'control'))
Related
i'm creating a custom button with React.
The appearance based on the press/release of the mouse/keyboard.
Sometimes it cannot be done by css using :active pseudo, so i need the javascript solution.
So i created a state that listen the onMouseDown/Up & onKeyDown/Up.
The problem is, if the user click the button then drag the mouse out of the button then release the mouse,
i miss the onMouseUp event thus causing the activeState locked up forever.
Do you have a solution for the equivalent of the :active & :not(:active) pair in javascript way?
note:
watching event window.addEventListener('mouseup',...) is still not satisfying me. When the mouse click hold & move out from the browser's window, i still missing the mouseup event.
Or it's just every browser happen to implement same behaviour? Only place I found in spec is in click event section which says
If the event target is focusable, the default action MUST be to give that element document focus.
But actually focus is the default action of mousedown event, which is widely used in today's frontend development, so I'd like to know why
Isn't the answer in the very quote you've posted?
If the event target is focusable, the default action MUST be to give that element document focus.
And then https://www.w3.org/TR/uievents/#event-type-focus
4.2.4.2. focus
...
A user agent MUST dispatch this event when an event target receives focus.
In other words: the spec indeed requires focus event to be fired when and if an element receives focus
By the way, the focus as event and focus as a property - is two different things.
But!.. The quote is actually from click event, not from mousedown
And if you test it in browsers you'll see that:
They behave differently (at least mine Chrome 81 and FF 75).
If you click inside <textarea>, but move out an only then release the button Chrome won't send click to the <textarea>, but FF will
But they give focus to <textarea> and fire focus event right after mousedown.
So that probably means, that:
No the spec doesn't require focus event to be fired after mousedown. (Instead it requires it to be fired after click)
Yes it's just so happens that every browser (well... at least those two I've tested) implement same non-standard behavior
So far the only thing I found in spec is
Many implementations use the mousedown event to begin a variety of contextually dependent default actions. These default actions can be prevented if this event is canceled. Some of these default actions could include: beginning a drag/drop interaction with an image or link, starting text selection, etc. Additionally, some implementations provide a mouse-driven panning feature that is activated when the middle mouse button is pressed at the time the mousedown event is dispatched.
Although it didn't explicitly says focus, I guess it's still enough evidence
I have a collection of draggable "content" elements, and a root-level "feedback" UI element which is displayed above them to provide feedback during drag and drop.
The problem is, during the drag operation, hovering over the "feedback" element causes the dragenter and dragover events to be fired on that element, rather than the underlying content element. It effectively "blocks" the dragenter event from firing on the correct element.
Is there a way for an element to cancel, or "opt out" of a dragenter/dragover event? I could display the feedback element underneath the content, but I'd rather not do that.
jsFiddle: http://jsfiddle.net/jact8/1/
I'm using the HTML drag/drop API, not jQuery or anything like that.
I've created a new fiddle. I think you want to use currentTarget instead of target in your handler on the columns to ensure that the event you receive is from the element you added the listener to (column) rather than the element it originated from (italicised text). See explanation here (it's for ActionScript but I believe it's valid for JavaScript also).
I'm assuming the listener on the insertionCaret element is for debug purposes only and have removed it (let me know if I'm mistaken here). You won't receive the event if you don't listen for it so won't need to opt out of it!
I'm looking at this:
http://www.netmagazine.com/tutorials/create-page-flip-effect-html5-canvas
However, I have one problem with that - I need to be able to click on the pages, even the edges, without triggering the page turn. I want the pages to turn when a button outside of the canvas is pressed. Is this possible using the base they provided, or do I need to go an entirely different direction?
Yes that can be done.
From what i can see, you need a click event that doesnt trigger the page drag. You need to assign a flag for this.
Let Drag = mouse drag/mouse move, down = mouse down, release = mouse release events respectively.
Initialize your flag variable as false. When a drag event is encountered it becomes true. Otherwise it remains false. As long as it is false when the mouse release event occurs it can be treated as a click. Thats the basic principle behind using mousedown and mouseup as a click event.
You will have to use e.srcElement or e.target to give you the element your cursor is currently positioned over inorder to trigger click functions relative to that element.
If you want a more detailed explanation on the page flip technique then check this out. Helped me lot.
I'm working on a web app where I support dragging on the page, by simply watching for mousedown/mousemove/mouseup events. That part works great.
The problem is that I'm only handling dragging inside one particular element, by design, and if a user (accidentally or not) drags outside, it gets "stuck" in drag mode. That is, mouse-down, then mouse-leaves-window, then mouse-up, then mouse-returns to window looks like it's still dragging, to my app.
I haven't figured out any way to solve this -- even something simple like "when the mouse re-enters the window, is the mouse button down?" would work.
Does such functionality exist, and I'm just missing it? Or is there some clever workaround I can employ here?
Legacy support has no importance to me -- if it's an HTML5 solution that only works in FF3.5/Chr4/Sf4, I'm happy with that.
In IE7/IE8 you can detect if the mouse was released outside the window by using the following code:
document.onmousemove = function(event) {
event = event || window.event;
if (document.all && event.button != 1) {
canceldragging();
}
}
In Firefox and Webkit the mouseup event is fired on the document when the mouse is released even if mouse pointer outside the browser window. You can see this using http://www.quirksmode.org/dom/events/tests/click.html
For IE8 the document onmouseup event is fired when the mouse button is released outside the browser window only if you allow document selection to occur (as the link above does). That is, in IE8 you don't get the mouseup event if you use document.onselectstart and cancel the selection, or if you use unselectable="on" on the starting element, or if you called document.selection.clear() combined with document.selection.empty() while the mouse was down.
What if you had the onmouseout event of the element fire the mouseup event?
If you're just using inline handlers, something along the lines of:
<div id='dragElement' onmouseup='alert("stop dragging!")' onblur='this.onmouseup();'></div>
added to whatever event handling code you're already using. This would 'release' the drag whenever the element loses focus. Not the cleanest code, but you get the idea.