如何在 keydown 上使用 Javascript 模拟悬停?
Posted
技术标签:
【中文标题】如何在 keydown 上使用 Javascript 模拟悬停?【英文标题】:How do I simulate hover with Javascript on keydown? 【发布时间】: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 行为。有模拟悬停的聪明方法吗?
【问题讨论】:
键盘导航大量使用:focus
。
@AlessandroVendruscolo 是的,但除了 或常规控制元素之外,我真的无法专注于任何事情,可以吗? :)
我只想到了 jQuery 解决方案 :(
添加tabindex
属性,或在li
s 内放置锚点——参见this answer
@AlessandroVendruscolo 基于 tabindex 的焦点事件不是很可靠。例如。 :focus
伪类不会在某些浏览器中触发。
【参考方案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】:您可能希望使用库而不是从头开始编写代码。
http://vebersol.net/demos/jquery-custom-forms/
http://www.dreamcss.com/2009/05/15-jquery-plugins-to-enhance-your-html.html
【讨论】:
感谢您的回答,但是,正如我所提到的,我正在尝试研究原生 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 事件来模拟它。您可以使用 hover、focus、onclick
等事件在 JS 中你可以用它来设置事件
document.getElementById('id').addEventListener('focus',function(e)
//place code that want ran at event happened
在 JQuery 中,您可以使用 bind、click、...
$('#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
,即使那样,焦点也不一致支持。以上是关于如何在 keydown 上使用 Javascript 模拟悬停?的主要内容,如果未能解决你的问题,请参考以下文章