jQuery keydown 回调仅监听外部 <ul> 而不是内部 <li> 元素
jQuery keydown callback listens only on outer <ul> rather than inner <li> element
嘿,这是我制作的代码演示
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<ul contenteditable class="outerList">
<li class="innerElement">Hello</li>
<li class="innerElement">World</li>
<li class="innerElement">Hello World</li>
</ul>
<script>
$(".outerList").keydown(function () {
console.log("I am the outer ul");
});
$(".innerElement").keydown(function() {
console.log("I am an inner element");
});
</script>
</body>
</html>
这里是 运行 的 jsFiddle
基本上我有一个内容可编辑的 UL,我想捕捉回车键并传入我自己的自定义函数。但我需要知道在哪个 LI 元素上引发了 keydown 事件。如演示中所示,我似乎只能将 keydown 事件侦听器(或与此相关的任何事件侦听器)绑定到外部 UL 元素。有没有办法将 keydown 事件附加到每个 LI?或者至少有一种方法可以将它附加到 UL,但仍然可以分辨出它来自哪个 child?
提前致谢,如果有任何其他信息有帮助,请告诉我!
您必须将 contenteditable
添加到您的 li
元素才能实现这一点。您将 contenteditable
设置为 ul
元素,因此事件将绑定到该元素,您可以编辑 li
元素,但它们没有设置 contenteditable
, 因此不会为这些元素触发键盘事件。
<ul class="outerList">
<li contenteditable class="innerElement">Hello</li>
<li contenteditable class="innerElement">World</li>
<li contenteditable class="innerElement">Hello World</li>
</ul>
然后:
$(".innerElement").keydown(function() {
console.log("I am an inner element");
});
您可以勾选当前选择的节点
如果您不想让每个 li
成为一个 contenteditable
元素,您可以获取当前选择或插入符号位置的元素并对其进行检查。
嵌入式示例显示了如何使用 Web API Interface for contenteditable
selections 实现此目的。 (我在Chrome中对此进行了测试,但它可能需要额外的逻辑来实现跨浏览器兼容性)。
还值得注意的是,您 可以 将 一些 事件侦听器绑定到 contenteditable
元素的子元素。例如,click
事件可能绑定到 li
元素,如您在嵌入式示例中所见。
$(document).ready(function() {
function getCurrentNode() {
var node = window.getSelection().getRangeAt(0).commonAncestorContainer;
return node.nodeType === 1 ? node : node.parentNode;
}
$('.outerList').on('click keyup', function (e) {
var $target = $(getCurrentNode()),
$closest = $target.closest('b');
console.log(e.type);
console.log('I am the outer ul');
console.log($target);
// Optional. Filter by clostest selector.
if ($closest.length) {
console.log('Target matches selector', $closest);
}
});
$('.innerElement').on('click', function (e) {
console.log(e.type);
console.log('I am an inner element');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul contenteditable class="outerList">
<li class="innerElement">Hello</li>
<li class="innerElement"><i>Hello</i></li>
<li class="innerElement"><b><i>Hello</i></b></li>
<li class="innerElement"><b>Hello</b></li>
<li class="innerElement">Hello</li>
<li class="innerElement">Hello</li>
</ul>
嘿,这是我制作的代码演示
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<ul contenteditable class="outerList">
<li class="innerElement">Hello</li>
<li class="innerElement">World</li>
<li class="innerElement">Hello World</li>
</ul>
<script>
$(".outerList").keydown(function () {
console.log("I am the outer ul");
});
$(".innerElement").keydown(function() {
console.log("I am an inner element");
});
</script>
</body>
</html>
这里是 运行 的 jsFiddle
基本上我有一个内容可编辑的 UL,我想捕捉回车键并传入我自己的自定义函数。但我需要知道在哪个 LI 元素上引发了 keydown 事件。如演示中所示,我似乎只能将 keydown 事件侦听器(或与此相关的任何事件侦听器)绑定到外部 UL 元素。有没有办法将 keydown 事件附加到每个 LI?或者至少有一种方法可以将它附加到 UL,但仍然可以分辨出它来自哪个 child?
提前致谢,如果有任何其他信息有帮助,请告诉我!
您必须将 contenteditable
添加到您的 li
元素才能实现这一点。您将 contenteditable
设置为 ul
元素,因此事件将绑定到该元素,您可以编辑 li
元素,但它们没有设置 contenteditable
, 因此不会为这些元素触发键盘事件。
<ul class="outerList">
<li contenteditable class="innerElement">Hello</li>
<li contenteditable class="innerElement">World</li>
<li contenteditable class="innerElement">Hello World</li>
</ul>
然后:
$(".innerElement").keydown(function() {
console.log("I am an inner element");
});
您可以勾选当前选择的节点
如果您不想让每个 li
成为一个 contenteditable
元素,您可以获取当前选择或插入符号位置的元素并对其进行检查。
嵌入式示例显示了如何使用 Web API Interface for contenteditable
selections 实现此目的。 (我在Chrome中对此进行了测试,但它可能需要额外的逻辑来实现跨浏览器兼容性)。
还值得注意的是,您 可以 将 一些 事件侦听器绑定到 contenteditable
元素的子元素。例如,click
事件可能绑定到 li
元素,如您在嵌入式示例中所见。
$(document).ready(function() {
function getCurrentNode() {
var node = window.getSelection().getRangeAt(0).commonAncestorContainer;
return node.nodeType === 1 ? node : node.parentNode;
}
$('.outerList').on('click keyup', function (e) {
var $target = $(getCurrentNode()),
$closest = $target.closest('b');
console.log(e.type);
console.log('I am the outer ul');
console.log($target);
// Optional. Filter by clostest selector.
if ($closest.length) {
console.log('Target matches selector', $closest);
}
});
$('.innerElement').on('click', function (e) {
console.log(e.type);
console.log('I am an inner element');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul contenteditable class="outerList">
<li class="innerElement">Hello</li>
<li class="innerElement"><i>Hello</i></li>
<li class="innerElement"><b><i>Hello</i></b></li>
<li class="innerElement"><b>Hello</b></li>
<li class="innerElement">Hello</li>
<li class="innerElement">Hello</li>
</ul>