简体   繁体   中英

Javascript - Get element behind caret in child elements of [contenteditable]

I am building a simplistic and easy-to-use text editor in Javascript, basically a WYSIWYG editor. I will be using the contenteditable attribute to the main wrapper ( .wrapper ). When you press enter inside the .wrapper , a new <p> element with a unique id gets appended to the wrapper.

I need a way to fetch which child element of the .wrapper that is currently selected (ie, being focused or having the caret/text marker inside of it).

I've searched for days without any results, and I've tried using document.elementFromPoint() but without any proper results.

When using $(":focus") , I get the entire .wrapper and not the specific child element.

Edit:

Example HTML structure:

<div class="container t-wrapper" contenteditable>
</div>

Example Javascript code:

$(document).ready(function() {
    $currentElement = $("[contenteditable]");

    $(".t-wrapper").each(function() {
        var id = generateIdentifier(6); // Ignore this

        /* This creates the initial <p> child element, where you start typing. */
        $(this).html('<p class="t-empty t-first" id="' + id + '"></p>');

        $(this).on("mouseup", function() {
            /* $currentElement = whatever element the caret is inside. */
        });

        $(this).on("keyup", function() {
            /* $currentElement = whatever element the caret is inside. */
        });
    ));
});

Edit 2:

I managed to get it fairly working with the mouseup event, since you're actually clicking on something. But I need this to work when moving the caret using the keyboard . Alternatively, I need some way to get the position of the caret in pixels, and then use document.elementFromPoint() to get the specific element.

:focus doesn't select your elements because they are not focusable.

You can make them focusable by adding tabindex="-1" in HTML, or tabIndex = -1 in JS.

 var generateIdentifier = Math.random; var currentElement = document.querySelector("[contenteditable]"); [].forEach.call(document.querySelectorAll(".t-wrapper"), function(el) { var first = document.createElement('p'); first.className = "t-empty t-first"; first.id = generateIdentifier(6); first.textContent = 'Press enter to create new paragraphs'; first.tabIndex = -1; el.appendChild(first); }); 
 .container > :focus { border: 1px solid blue; } 
 <div class="container t-wrapper" contenteditable></div> 

It seems that if you add it to the first paragraph, new paragraphs obtain it automatically. But if you want to be sure, I guess you could use a mutation observer or a keyup event listener to detect paragraphs without tabindex , and add it:

el.addEventListener("keyup", function(e) {
  var newChild = el.querySelector('p:not([tabindex])');
  if(newChild) newChild.tabIndex = -1;
});

document.activeElement将返回当前关注的元素。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM