使用击键导航列表
Navigating a list with keystrokes
我正在创建一个项目列表,我希望用户能够使用键盘与之交互。 所以像这样的事情...
<ul contenteditable="true">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
我的理解是,为了捕获键下/键控事件,我必须设置内容可编辑属性。 这有效,但现在 li 的内容是可编辑的,我不想要。 我只需要捕获键下/键控事件。
如何在不使内容可编辑的情况下捕获这些事件?
编辑
感谢跳转代码,以下内容可以使其保持只读...
$('ul').on('click', 'li', function (e) {
e.preventDefault();
});
。但我仍然在 li 上留下一个闪烁的光标。 我该如何摆脱它?
编辑
开始赏金,需要对下面的预防默认答案进行以下更新。
- 如何摆脱闪烁的光标?
- 如何使不可选择? 我真的只想捕获键控事件! 如果我可以在不设置内容可编辑的情况下完成此操作,那将是可取的。
- 我可以在文档级别捕获键控,但问题是键控是从哪里发出的? 可能有几个插件在运行,所有插件都需要响应相同的事件,但前提是它们是活动范围。
正如您所说,您不需要编辑列表项,因此没有理由使用 contenteditable
.
您需要的是一个与列表的当前活动项相对应的索引,并在按下箭头时用于递增和递减该索引的功能。下面是一个构造函数,它实现了您需要的功能:
var NavigableList = function (ul, selectedClass, activeClass) {
var list = null,
index = 0,
walk = function (step) {
var walked = true;
index += step;
if (index < 0 || index === list.length) {
index -= step;
walked = false;
}
return walked;
},
active = false;
this.active = function (state) {
if (state !== active) {
active = state;
if (active) {
ul.addClass(activeClass);
} else {
ul.removeClass(activeClass);
}
}
};
this.isActive = function () {
return active;
};
this.down = function () {
var previous = index,
changed = false;
if (walk(1)) {
$(list[previous]).removeClass(selectedClass);
$(list[index]).addClass(selectedClass);
changed = true;
}
return changed;
};
this.up = function () {
var previous = index,
changed = false;
if (walk(-1)) {
$(list[previous]).removeClass(selectedClass);
$(list[index]).addClass(selectedClass);
changed = true;
}
return changed;
};
this.currentIndex = function () {
return index;
};
this.currentElementx = function () {
return $(list[index]);
};
ul = $(ul);
list = ul.find('>li');
selectedClass = selectedClass || 'current';
activeClass = activeClass || 'active';
$(ul).click(function (e) {
this.active(true);
NavigableList.activeList = this;
}.bind(this));
$(document).keydown(function(e) {
var event = $.Event('change');
if (this.isActive() && e.keyCode === 40) {
if (this.down()) {
event.selected = $(list[index]);
event.index = index;
ul.trigger(event);
}
} else if (this.isActive() && e.keyCode === 38) {
if (this.up()) {
event.selected = $(list[index]);
event.index = index;
ul.trigger(event);
}
}
}.bind(this));
$(list[index]).addClass(selectedClass);
};
使用它非常简单:
var list = new NavigableList($('#list'), 'current', 'active'),
list2 = new NavigableList($('#list2'));
$(document).click(function (e) {
if (NavigableList.activeList) {
switch (NavigableList.activeList) {
case list:
list2.active(false);
break;
case list2:
list.active(false);
break;
}
} else {
list.active(false);
list2.active(false);
}
NavigableList.activeList = null;
});
此外,我在列表中实现了一个 change
事件,您可以通过这种方式使用:
$('#list').change(function (e) {
console.log('List. Selected: ' + e.index);
});
$('#list2').change(function (e) {
console.log('List 2. Selected: ' + e.index);
});
为了跨浏览器兼容性,您需要在所有Javascript代码之前使用它:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
这是一个工作演示。
试试这个。
<ul contenteditable="true">
<li tabindex="1">Item 1</li>
<li tabindex="2">Item 2</li>
<li tabindex="3">Item 3</li>
</ul>
Tabindex 将设置 HTML 中元素的 Tab 键顺序。
相关文章:
- 自定义导航栏切换(从下拉列表到从左侧滑动)
- JQuery 滚动列表框模仿键盘导航
- 在Oracle Apex 5.0中,无法在侧面导航列表模板中使用title属性
- 使用击键导航列表
- 定义导航列表 (css) 的样式规则
- 在对齐作为 css 圆圈的导航列表元素的基线时遇到问题
- BootstrapJS - 导航导航列表在单击时不会折叠
- Boostrap JS - 导航列表树无法正常工作
- 选择导航列表项,其中包含一个跨度
- Javascript:通过递归迭代对象来构建导航列表
- 如何创建不同的按钮导航列表,所以当我点击按钮的内容/文本将根据我点击按钮的变化
- 需要改进导航列表
- 垂直引导旋转木马箭头和导航列表
- 引导导航条在单击侧边栏导航列表后隐藏页面的部分
- 导航/子导航列表,如何给点击后的项目活动类重新加载页面
- 使用Jquery选择导航列表项(带URL加载)
- 如何将导航列表显示为选择项
- 引导3导航列表项目悬停问题
- 如何自动显示/隐藏元素与引导导航列表
- 导航列表菜单在IE8中不工作