Emphasizing the importance of nested contenteditable components

So, I have a situation with two contenteditable divs nested within another:

<div class="top" contenteditable="true">
     <div class="nested" contenteditable="true">This</div>
</div>

If you want to see an example, check out this Fiddle.

When the top div is focused, the 'nested' div should also be focused. However, when checking with

console.log(document.activeElement);
, it shows that the top div is focused and doesn't recognize the nested div.

In situations where content is being edited, it's crucial to identify the nested div element instead of the top element.

How can this be achieved? Any assistance would be greatly appreciated.

Answer №1

The handling of [contenteditable] elements by browsers can cause nested [contenteditable] elements to not respond to events, as the editing host is the parent editable element. Refer to the spec:

If an element is editable but its parent is not, or if an element is editable without a parent, then that element becomes an editing host. Editable elements are allowed to be nested. User agents are required to make editing hosts focusable (usually meaning they can be tabbed to). An editing host may contain non-editable sections, which are handled differently. These non-editable sections may also contain further editing hosts.

To address this issue, a workaround involves temporarily making the focused nested editable element the hosting host by making any of its editable parents temporarily non-editable. Check out the example below:

$('div.top [contenteditable]').on('focusin focusout', function(e) {
    $(this).parents('[contenteditable]').prop('contenteditable', e.type === "focusout");
});

-updated jsFiddle-

Answer №2

Ensure the nested div has a tabindex=-1 for focusability:

.nested {
  display: inline;
  background-color: #eef;
}
<div class="top" contenteditable="true">
    Editable div <div class="nested" tabindex=-1>Nested div</div>
</div>

Important Points:

  • The attribute contenteditable is inherited, eliminating the need for it to be redefined.
  • This feature functions solely with mouse focus; navigating the cursor over the nested div will not trigger focus. Additionally, leaving a focused nested div with the cursor does not return focus to the parent div. Strategies involving keydown event listeners, range, and selection may be required for proper handling.

Answer №3

When dealing with nested contentEditable elements, the focus should only be activated in the highest ancestor element. To determine the closest element where the caret is positioned, you can utilize selection as shown below:

function getClosestCEOfCaret(){
  const userSelection = window.getSelection()
  const textRange = userSelection.getRangeAt(0)
  const startPoint = textRange.startContainer;
  let nearestElement;
  if(startPoint.nodeType === 1) nearestElement = startPoint;
  else nearestElement = startPoint.parentElement; 
  return nearestElement.closest('[contenteditable="true"]')
}
console.log(getClosestCEOfCaret())

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble executing node commands in the terminal

After launching the terminal on my Mac, I made sure to confirm that Node was installed by running the command: node -v v14.17.5 Next, when attempting to open a file I had created called index.html from Visual Studio Code, I encountered an error message in ...

Issues occurred as the button's on-click function fails to execute the

Just starting out with JavaScript and coding, encountering a problem with an on-click scroll action that should go to another div. I've searched through several posts but still can't figure out why it's not working. Any assistance would be g ...

Increase the jQuery level and utilize the .find() method

Currently, I am delving into the realm of jquery and facing a minor hiccup with selectors. Below is the structure of my DOM: <li> <header class="title"> <span>Text</span> <a href="#work-1">My trigger</a> ...

Embedding an Inline Frame on Chrome while preserving Internet Explorer preferences

I am currently facing a situation where my webpage looks different on Internet Explorer compared to Chrome. I am considering loading the webpage within an iframe, but I want it to render as it does in Internet Explorer regardless of the browser being use ...

PHP variables are unable to fetch HTML option values in real time

Let's create a website with a product addition feature using PHP code. For instance, we can add a phone as a product where the category is Mobile Phones and the subcategories could be Samsung or iPhone. Another example could be adding Cars with option ...

What is the process of combining two identical objects in Angular JS?

Is it possible to merge and sort two objects in Angular JS that have the same fields, notifications.fb and notifications.tw, based on their time field? ...

React forms are experiencing issues with characters overlapping

Having trouble with overlapping label and input letters in my React form. Looking for: The appearance shown in the top image Experiencing: What is displayed in the bottom image Any solutions on how to resolve this issue? https://i.sstatic.net/Y3W2m.png ...

Sort JSON data based on keys (not values)

I have the following JSON data: json = [{ "code3": "ALB", "asset": 9, "biodiversity": 4, "infrastructure": 15 }, { "code3": "GHN", "asset": 4, "biodiversity": 5, "infrastructure": 5, }, { "code3": "TGO", "asset": 3, ...

Reloading nested Iframe with Selenium automation script

Currently, I am facing a challenge while working on an application that contains nested Iframes within the user interface. Some of these Iframes undergo refreshing during the test execution process. Is there any approach that allows us to simulate the refr ...

What is preventing me from including onclick functions within a loop?

As someone who has recently started learning about node js, I am facing a challenge. When a player connects to the server, I want to send them the current list of available rooms and allow them to join a room by clicking on it. However, I'm running in ...

Is there a way to restart a setTimeout loop upon receiving a response from an API server?

Currently, I am in the process of developing my very own "smart light" controller right from an HTML document. For testing purposes, I have crafted a setup where upon clicking a button, an API POST request is dispatched to my localhost API server (which ru ...

Retrieve data from Last.fm API by utilizing both Node.js and Angular framework

I am currently working on implementing the node-lastfmapi track.search method into my project. I have successfully retrieved the results, but I am facing challenges in integrating them into the front end using Angular. My backend is powered by mongoDB and ...

Navigating in a react login interface

Recently, I developed a backend code for a login system that verifies the validity of usernames and passwords. While everything is functioning as intended, I am facing an issue with automating the redirect to /dashboard. The client side operates on Port ...

The code appears to function properly in Internet Explorer, yet encounters compatibility issues with other

The following code snippet functions properly in Internet Explorer but encounters issues in Firefox, Chrome, and Edge. Unfortunately, I am unable to modify the code since it is a crucial component of our web-based ticketing system used at my workplace. Cou ...

Maintaining the selected radio button based on previous input with the use of jQuery or PHP

I am in the process of developing an online quiz system. I am fetching questions and options from getquestion.php through ajax on quiz.html. On this page, I've included next and previous buttons so that users can navigate through the quiz. However, I& ...

Guide to removing a colon from my JSON.stringify output

I'm encountering an issue with a JSON.stringify function. It is adding a colon after the JSON object. axios.post('http://54.196.61.131/api/v0/user/250/product/add/scan', JSON.stringify({ name: currentProduct.product. ...

Express Promises Linked Together: Lack of Data in Last Stage

When handling put requests for my restful API, I utilize the findOneAndUpdate method of Mongoose. The password is left to the second step where the 'save' pre hook of Mongoose is used to hash the password. router.put("/:id", function(req, res, n ...

Utilizing React, manipulating the DOM by utilizing getElementById, and then attempting to swap out a node with a React Component

Is there a method to replace a DOM node with a ReactJS node? If so, how can it be achieved? const myComp = <span>hey</span> const elem = document.getElementById('video1') elem.parentNode.replaceChild(myComp, elem) What is the correc ...

What is the process of specifying that an Angular directive must act as a child directive within a particular directive in Angular?

I am currently developing a directive for AngularJS. How can I specifically configure it to require being a child of directiveA? For instance, consider the following example: <my-modal> <m-header>Header</m-header> </my-modal> ...

Formatting Issue with HTML Form (Width Exceeding Specifications)

Currently, I am in the process of creating a table that contains various forms and buttons within the cells. However, there seems to be excess space between the buttons which is giving the appearance of the form being too wide. I have been attempting to di ...