【问题标题】:How do I simulate hover with Javascript on keydown?如何在 keydown 上使用 Javascript 模拟悬停?
【发布时间】:2013-01-22 17:43:42
【问题描述】:

首先,我想只使用原生 JavaScript 来完成这项任务。

假设我要制作一个自定义下拉菜单,HTML 代码看起来像这样。

<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>

在 CSS 文件中,我有类似的东西:

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

是的,确实没有下拉行为,但实际上这不是讨论的重点。问题是我想不出一种体面的方法来为此下拉菜单启用键盘控制。期望的结果如下:我按下向下键,第一个选项被突出显示;我再次按下它,第二个选项被突出显示,依此类推。

此时我看到的唯一选择(刚开始学习 JS)是获取所有ul 的孩子,将它们粘贴到一个数组中,并通过 JS 方法以适当的方式为标签分配背景颜色每次按下向下键时的方式。

另一方面,我仍然有鼠标控制的 CSS 中描述的 :hover 行为。有模拟悬停的聪明方法吗?

【问题讨论】:

标签: javascript hover onkeydown


【解决方案1】:

我会在你的 li 元素上简单地分配一个类,并使用 keydown 处理程序来控制它。以下代码并不完整,而是为您提供一些可以使用的东西。

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");
}

你可以看到一个working example here

【讨论】:

  • 谢谢你们的时间。
  • 非常感谢您的解决方案,我在同一个问题上苦苦挣扎了很长时间。
【解决方案2】:

【讨论】:

  • 感谢您的回答,但是,正如我所提到的,我正在尝试研究原生 JS,所以我实际上想从头开始编写整个代码。我知道 JQuery 提供了很多可能性和自定义选项,我承认它们很酷而且很有用,但我最终会谈到它:)
  • jsfiddle.net/Hd7X9 - 给你。我已经在 facebook 上给你写信了,我想我需要给你一些背景知识。
【解决方案3】:

我建议从 css 中删除 hover 属性。 并且只添加一个应用于按键和鼠标悬停的悬停类

这在代码中可能如下所示

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";
});

这是JSFiddle上的一个例子

【讨论】:

    【解决方案4】:

    现实你不需要任何 js 来进行下拉,但你可以使用 JavaScript 事件来模拟它。您可以使用 hoverfocusonclick

    等事件

    在 JS 中你可以用它来设置事件

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

    在 JQuery 中,您可以使用 bindclick、...

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

    事件列表

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

    【讨论】:

    • @Christoph 是的,我们可以使用焦点事件quirksmode.org/dom/events/index.html
    • 好吧,支持焦点元素的事实并没有改变默认情况下只有window、链接和表单域可以被聚焦的事实。否则,您需要在元素上声明 tabindex,即使那样,焦点也不一致支持。
    猜你喜欢
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 2013-05-30
    • 2017-07-13
    • 1970-01-01
    • 2012-02-16
    • 2014-05-17
    相关资源
    最近更新 更多