如何通过继承属性 contenteditable 的元素捕获 'keydown' 事件?

问题描述 投票:0回答:1

作为介绍,我想解释一下我试图实现的目标:

*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>


我进行了以下调查:“keydown”事件仅对于具有“contenteditable = true”属性的元素可检测到。顺便说一下,无论“contentEditable”属性设置为何,“点击”事件都是可检测到的。

当在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 内的任何元素,但这对我来说似乎不太优雅。

javascript html
1个回答
0
投票

一旦父元素设置为内容可编辑,其子节点就不再可检测/可定位。一切都简化为整体文本内容,事件目标将始终是最顶层的内容可编辑元素节点。

为了实现 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>

© www.soinside.com 2019 - 2024. All rights reserved.