我有一个带有孩子的包装器(DIV),包装器上有一个事件侦听器。我想处理键盘并通过包装上的 dataset 值单击事件。
在捕获包装器中所有针对孩子的事件。
简单的例子:
let wrap = document.getElementById("wrap");
let status = document.getElementById("status");
let keyact = {
a: function(e) {
status.textContent = "Do A " + e.key;
},
b: function(e) {
status.textContent = "Do B " + e.key;
},
};
function keycheck(e) {
let t = e.target,
d = t.dataset;
status.textContent = "X trap";
if (d.keyact && keyact[d.keyact])
keyact[d.keyact](e);
else
status.textContent = "No trap";
}
function tabtrap(e) {
if (e.target.className == "tab_trap")
wrap.focus();
}
document.addEventListener('keydown', keycheck);
document.addEventListener('keyup', tabtrap);
status.textContent = "ready";
div, a {
border : 1px solid #eee;
margin: 2px;
}
*:focus {
border : 1px solid red;
outline : 0;
}
<div tabindex=0 class="tab_trap"></div>
<div id="wrap" data-keyact="a" tabindex=0>
<ul>
<li><a href="#">Dummy 1</a></li>
<li><a href="#">Dummy 2</a></li>
<li><a href="#">Dummy 3</a></li>
</ul>
</div>
<div tabindex=0 class="tab_trap"></div>
<p id="status"></p>
如果用户在#wrap
DIV处于焦点状态时按了一个键,则会处理keyact
函数(因为它的 dataset -act值为{{1} }。
我希望在将焦点放在DIV包装器的任何子元素上时按下键时执行a
。例如,“虚拟对象1” , 无 设置每个子元素的数据集值。
如果将keyact.a()
的值更改为data-keytrap
,我希望执行b
等。
答案 0 :(得分:1)
如果我正确理解了您的问题,则您尝试基于keyact
中显示的相应DOM属性调用#wrap
中的函数。有很多方法可以实现,但是以下内容应满足您的要求(有关更多详细信息,请参见摘录中的注释):
let status = document.getElementById("status");
let keyact = {
a: function(e) {
status.textContent = "Do A " + e.key;
},
b: function(e) {
status.textContent = "Do B " + e.key;
},
};
// Query all nodes in document with data-keyact attribute
document.body.querySelectorAll('[data-keyact]').forEach(element => {
// For this data-keyact node add keydown event handler
element.addEventListener('keydown', function(event) {
// When keydown event happens, access the "keyact" attribute value from #wrap
const actionKey = element.dataset.keyact;
// Access the keyact function by the aquired actionkey
const actionFunction = keyact[actionKey];
// Saftey check - make sure actionFunction is a function before attempting to call
// it
if(typeof actionFunction === 'function') {
// Pass the keydown event to actionFunction
actionFunction(event);
}
// This is important, we don't want the keydown behaviour to propagate
// up to parent nodes with same attribute
event.stopPropagation();
});
// For this #wrap decendant, add keyup event handler
element.addEventListener('keyup', function(event) {
// When keyup happens, refocus the element
element.focus();
// This is important, we don't want the keyup focus behavior to propagate
// up to parent nodes with same attribute
event.stopPropagation();
});
});
div, a {
border : 1px solid #eee;
margin: 2px;
}
*:focus {
border : 1px solid red;
outline : 0;
}
<div tabindex=0 class="tab_trap"></div>
<div id="wrap" data-keyact="a" tabindex=0> (keyact a)
<ul>
<li><a data-keyact="b" href="#">Dummy 1 (keyact b)</a></li>
<li><a href="#">Dummy 2</a></li>
<li><a href="#">Dummy 3</a></li>
</ul>
</div>
<div tabindex=0 class="tab_trap"></div>
<p id="status"></p>