I recently encountered a problem during the development process, and I feel that it can be solved by listening to the keydown event. However, in the process of practice, I found that my original understanding of the keydown event was not very correct. So, after learning about the keydown event in detail, here is a summary.
This article mainly includes the following aspects:
- problems encountered
- keydown event
- solution
problems encountered
During the development process, I encountered such a requirement:
When the mouse hovers over the target dom, the mouse needs to be set to a special style:
- Without holding down the ctrl key, the mouse style is set to style 1;
- Hold down the ctrl key and set the mouse style to style 2.
My first thought is to determine whether the mouse is hovering over the target dom by listening to the mousemove event. Then use event.ctrlKey to determine whether the ctrl key is held down at this time:
- If not pressed, handle case 1 above;
- If held, handle case 2 above.
However, just listening to the mousemove event cannot cover all cases. For example, first move the mouse to the target dom, at this time the mouse does not move, press or release the ctrl key, then the style of the mouse needs to be changed. However, we didn't move the mouse after pressing or releasing the ctrl key, so the mousemove event doesn't fire.
So, I want to listen to the press and release events of the ctrl key through the keydown and keyup events.
First, I added a keydown event to the target dom. At this point, the problem comes: the keydown event is not triggered at all.
Then, I want to try to bind the keydown event on the body, and then judge the mouse position by judging whether event.target is the target dom.
Finally, I found out that event.target is the body element, not the target dom as I wanted. So, I started looking for information and found that the keydown event turned out to be different from what I imagined.
keydown event
By consulting the keydown event on the MDN, it is found that the event has the following restriction :
Keyboard events are only generated by <inputs>, <textarea> and anything with the contentEditable attribute or with tabindex="-1".
First of all, my target DOM is not input
and textarea
elements, so I consider adding contentEditable
or tabindex
attributes.
First, let's look at the contentEditable property . When the element is set to be editable (the non-editable state will not trigger the keydown event), the content of the element can be edited like textarea
. This is not the function I want, so this method does not work.
Then, tabindex="-1"
can be set. At this point, can trigger the keydown event certain conditions. This certain condition is that first, the target dom is in the focus state by clicking, and then pressing the ctrl key will trigger the keydown event. Obviously, this method can not meet the demand.
At this point, let's think about a question: why is it OK to add a keydown event to the body in the first part. The information we know is:
- Conditions for keyboard event trigger: special element, contentEditable, tabindex="-1".
So, I suspect that the body element has the tabindex attribute set:
document.body.tabIndex // -1
Sure enough!
As we mentioned earlier, the keydown event will only be triggered when the ctrl key is pressed when the dom is in the focus state. So, is the same for the body element?
First, we exit the full-screen mode of the page, and click somewhere that doesn't belong to the browser. At this point, the browser page is in a state of losing focus.
We move the mouse back to the content area of the page (note, just move over, don't click). Then, press the ctrl key, and you will find that the keydown event is also not triggered.
However, for the body element, triggering the focus event first is not a problem. In the case where the page lost focus just now, move the mouse to the elements with the hover effect on the page, and find that the hover effect of these elements will not be triggered either. Therefore, the default premise of page operation should be that the page is in the focus state. In this way, for the body element, it is not a special operation to perform the focus operation first before the keydown event is triggered.
solution
Through the content of the above section, we know that we can listen to the keydown event of the body element. Then, the next question becomes how to combine the keydown event of the body to determine whether the mouse is exactly on the target dom when the ctrl key is pressed or released.
I solved it by listening to the mousemove event of the document element. When the mousemove event fires, save event.target in a global variable. When the keydown event of the body is triggered, the subsequent logic is controlled by judging whether the global variable is the target dom. The logic of releasing the ctrl key is the same, which is monitored by the keyup event of the body.
Summarize
Hope you all get something. If there are any mistakes, please leave a message for discussion.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。