作为介绍,我想解释一下我试图实现的目标:
在
*div#content*
内,我想检测 keydown
事件并获取检测到 keydown 元素的元素。例如“编码很有趣”段落中的 TAB。应该返回段落元素和按下的 TAB 键。
//javascript
const buttonEditable = document.getElementById("buttonEditable");
const contentDiv = document.getElementById("content");
const paragraph = document.getElementById('paragraph');
paragraph.addEventListener('keydown',keydown);
function keydown(){
console.log(event.key); // should return TAB
console.log(event.target); //should return paragraph element
}
buttonEditable.addEventListener('click',toggleEditable);
function toggleEditable(){
if(contentDiv.contentEditable === 'false'){
contentDiv.contentEditable = true;
} else {
contentDiv.contentEditable = false;
};
}
<!-- HTML -->
<div id="content"> <!-- div container keeps HTML element wich are toggled from editable to non-editable-->
<p id="paragraph">Coding is fun.</p>
<!-- ...bunch of further html element-->
</div>
<button id="buttonEditable">toggleEditable</button>
当在html代码中添加
contenteditable = true
时。它有效...检测到段落内的 TAB 键按下:
<div id="content">
<p id="paragraph" contenteditable="true">Coding is fun.</p> <!-- <<<<<<<<<<-------contenteditable added -->
</div>
<button id="buttonEditable">toggleEditable</button>
有人知道继承
contenteditable = "true"
的段落如何检测 TAB 键按下 AND 元素的方法吗?
当然,使用查询选择器,我可以将分配 contenteditable 属性分配给 div#content 内的任何元素,但这对我来说似乎不太优雅。
一旦父元素设置为内容可编辑,其子节点就不再可检测/可定位。一切都简化为整体文本内容,事件目标将始终是最顶层的内容可编辑元素节点。
为了实现 OP 想要的目标,必须伪造父元素的
contentEditable
状态以及处理子元素特定 contentEditable
状态的实现。
也有类似的东西...
function handleTargetSpecificKeydown(evt) {
console.log(evt.key); // - should return TAB
console.log(evt.target); // - should return paragraph element
}
function handleTargetSpecificEditableState({ target }) {
if (!target.matches('#content')) {
const recentlyEditable = target.contentEditable === 'true';
const currentlyEditable =
(target.closest('#content').dataset.contenteditable === 'true');
if (!recentlyEditable && currentlyEditable) {
target.addEventListener('keydown', handleTargetSpecificKeydown);
target.contentEditable = true;
target.focus();
} else if (recentlyEditable && !currentlyEditable) {
target.contentEditable = false;
target.removeEventListener('keydown', handleTargetSpecificKeydown);
}
}
console.log({
target,
'target.contentEditable': target.contentEditable,
});
}
function toggleOverallEditableState () {
const { dataset } = contentDiv;
dataset.contenteditable = (dataset.contenteditable !== 'true');
console.log({ contentDiv });
}
const buttonEditable = document.querySelector('#buttonEditable');
const contentDiv = document.querySelector('#content');
buttonEditable.addEventListener('click', toggleOverallEditableState);
contentDiv.addEventListener('click', handleTargetSpecificEditableState);
.as-console-wrapper {
left: auto!important;
bottom: 0;
width: 70%;
min-height: 100%;
}
#content { width: 30%; }
<div id="content">
<p>Coding is fun.</p>
<p>The quick brown fox ...</p>
<p>... jumps over the lazy dog.</p>
</div>
<button id="buttonEditable">toggleEditable</button>