How do I simulate hover with Javascript on keydown

2020-07-11 08:04发布

First of, I'd like to use only native JavaScript to complete this task.

Let's say I am to make a custom dropdown, and the HTML code looks kind of like this.

<div class="dropdown">
  <span class="dropdown-label" style="display:block">Select a thing</span>
  <ul class="dropdownItemContainer">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
  </ul>
</div>

In the CSS file I have something close to this:

ul.dropdownItemContainer li:hover {
  background-color: #FF0000;
}

Yeah, there's really no dropdownish behavior, but it's not the point of discussion actually. The problem is that I couldn't think of a decent way to enable keyboard control for this dropdown. The desired outcome is the following: I press the down key, and the first option is highlighted; I press it again, and the second option is highlighted and so on.

The only option that I see at this point (just started studying JS) is to fetch all of the ul's children, stick'em into an array and assign the tags a background color through JS methods in a proper way whenever the down key is pressed.

On the other hand, I still have the :hover behavior described in the CSS for mouse countrol. Is there a smart way of simulating hovers?

4条回答
时光不老,我们不散
3楼-- · 2020-07-11 08:16

Reality you didn't need any js for dropdown but You can use JavaScript Event for simulating it. You can use event like hover, focus, onclick

In JS You Can use This For Set Event

  document.getElementById('id').addEventListener('focus',function(e){
    //place code that want ran at event happened
  }  

In JQuery you can use bind, click ,...

  $('#id')bind('focus',function(e){
    //place code that want ran at event happened
  }

List of Event

http://www.quirksmode.org/dom/events/index.html

查看更多
Fickle 薄情
4楼-- · 2020-07-11 08:23

I would suggest removing the hover attribute from css. And add only a hovered class which is applied on keypresses and on mouseover

This could look like this in Code

var dropDown = document.getElementsByClassName("dropdownItemContainer")[0]

document.addEventListener("keydown",function (e) {
    if(e.keyCode == 38 || e.keyCode == 40 ) {
        var key = e.keyCode
        var hovered = dropDown.getElementsByClassName("hovered")
        if(hovered.length != 0 ) {
            cur = hovered[0]
            cur.className = ""
            cur = cur[(key==38?"previous":"next")+"ElementSibling"] || dropDown.children[key==38?dropDown.children.length-1:0] 
        } else {
            cur = dropDown.children[key==38?dropDown.children.length-1:0]
        }
        cur.className="hovered"
    }
});


dropDown.addEventListener("mouseover",function (e) {
    for( var i = 0,j; j = dropDown.getElementsByClassName("hovered")[i];i++)
        j.className = "";
    e.srcElement.className = "hovered";
});

Heres an example on JSFiddle

查看更多
干净又极端
5楼-- · 2020-07-11 08:36

I would go with a simple assignment of a class on your li-elements and steer it with a keydown handler. The following code is not meant to be complete but give you something you can work with.

var active = document.querySelector(".hover") || document.querySelector(".dropdownItemContainer li");

document.addEventListener("keydown",handler);
document.addEventListener("mouseover",handler);

function handler(e){
    console.log(e.which);
        active.classList.remove("hover");
    if (e.which == 40){
        active = active.nextElementSibling || active;
    }else if (e.which == 38){      
        active = active.previousElementSibling || active;
    }else{
        active = e.target;
    }
        active.classList.add("hover");
}

You can see a working example here

查看更多
登录 后发表回答