Can child elements be protected from deletion when their parent is set to contentEditable?

When a website element has the attribute contentEditable, its child elements can be removed. However, if one of those child elements is not set to be contentEditable, then the content within it cannot be edited but the entire element can still be deleted. This behavior can be observed in the example below.

Is there a way to prevent the deletion of these child elements?

div {
  height: 100px;
  border: 1px solid #CCC;
  margin: 5px;
  padding: 5px;
  width: 300px;
}

span {
  color: #999;
}
<div contentEditable="true">Hello <span contentEditable="false">world</span>!</div>

Answer №1

If utilizing classes is an option, the task will become simplified.

<div class="editableContent">Greetings <span class="nonEditableContent">universe</span>!</div>
<div class="storeContent" style="display: none;"></div>

Snippet in Javascript/Jquery

<script>
$(".editableContent").on("click",function(){
 // clear .storeContent
 $(".storeContent").html("");

 // duplicate any nonEditableContent class within the selected editableContent class.
 $( this ).find(".nonEditableContent").clone().appendTo( ".storeContent" );

 // clear editableContent
 $( this ).html("");

 // clone nonEditableContent to editableContent
 $( ".storeContent" ).find(".nonEditableContent").clone().appendTo( ".editableContent" );
});
</script>

Answer №2

Is there a way to protect these child elements from being deleted?

Unfortunately, preventing the deletion of these child elements is not possible. However, here is an alternative approach.

Example:

Given that direct children cannot be retained, we will need to create two distinct elements instead.

<div class="editor">
  <label class="editor-label">You can't delete me</label>
  <div class="editor-area" contentEditable="true"></div>
</div>


Eventually, eliminate the label from the flow to prevent any interference with the area.

.editor {
  border: solid 1px #CCC;
  position: relative; // Establishing context for label
  line-height: 1.5;
}

.editor-area {
  min-height: 100px;
  padding: 5px;
}

.editor-label {
  position: absolute; // Exclusion from the flow
  margin: 5px 0 0 5px;
  user-select: none;
}


Lastly, to ensure the caret begins after the text in the label, determine its width and assign it to the text-indent value of the area.

var editorLabel = document.querySelector('.editor-label');
var editorArea = document.querySelector('.editor-area');

var editorLabelRect = editorLabel.getBoundingClientRect();

editorArea.style.textIndent = editorLabelRect.width + 'px';
editorArea.innerHTML = '&nbsp';

Finalized code:

var editorLabel = document.querySelector('.editor-label');
var editorArea = document.querySelector('.editor-area');

var editorLabelRect = editorLabel.getBoundingClientRect();

editorArea.style.textIndent = editorLabelRect.width + 'px';
editorArea.innerHTML = '&nbsp';
.editor {
  border: solid 1px #CCC;
  position: relative;
  line-height: 1.5;
}

.editor-area {
  min-height: 100px;
  padding: 5px;
}

.editor-label {
  position: absolute;
  margin: 5px 0 0 5px;
  user-select: none;
}
<div class="editor">
  <label class="editor-label">You can't delete me</label>
  <div class="editor-area" contentEditable="true"></div>
</div>

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

Alternative to dynamic arrays in Javascript

I successfully implemented a masonry grid using Flexbox. Initially, the items were ordered vertically, so I developed a function to rearrange them horizontally: Original Order: 1 4 7 2 5 8 3 6 9 New Order (with my sorting function): 1 2 3 4 5 6 7 8 9 ...

Is there a simple solution to show script 1 to visitors from the US and Canada, while displaying script 2 to visitors from other countries?

I'm looking for a simple script that can show one script to visitors from the US and Canada, and another script to visitors from other countries. It doesn't have to be perfect, but using a service like seems too complex for me. Is there a stra ...

Tips for showcasing the chosen option from an autocomplete input field in a React application

Currently learning React and working on a search feature for a multi-form application. The goal is to allow users to search for a student by first name, last name, or student ID using an autocomplete text field. The options for the autocomplete text field ...

Understanding the Typescript definitions for different event types in React

How do I properly define the type for React events? In the beginning, I simply used any to keep things simple. However, I am now trying to improve my code and eliminate the use of any altogether. Here is a basic example: export interface LoginProps { l ...

next-pwa seems to be malfunctioning without any discernible errors in the production environment

The repository is publicly available // next.config.js const withPWA = require("next-pwa"); module.exports = withPWA({ pwa: { dest: "public", sw: '/sw.js' }, }); _document.js _app.js Live I have verified the fu ...

Interactive hexagon shape with dynamic image content on click using a combination of CSS, HTML,

As a beginner in CSS, HTML, and JavaScript, I came across a code snippet to create a pattern of hexagons with images (refer to the first code below). My goal is to change the image displayed on a clicked hexagon to another picture (see second code). First ...

Ensure that every item in the list is assigned a distinct "key" prop to avoid duplication. Follow these steps to address the issue

function App() { return <StrictMode>{data.map(createCard)}</StrictMode> } function createCard(characters) { return ( <Card id={characters._id} name={characters.name} about={characters.about} img={characters.im ...

Using display:inline-block will increase the vertical spacing

I am currently dealing with the following HTML and CSS setup: * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } body { margin: 0; } .row { background-color: red; /* display: inline-block; */ } ul { ...

Tips for retrieving text from an element that is nested within an element's promise in Appium

Here's a snippet of code I'm working with: const wd = require('wd') const driver = await wd.promiseChainRemote("http://localhost:4723/wd/hub") elements = await driver.elementsByAccessibilityId("commonElementsId") I have received a pro ...

What is the reason behind the ineffectiveness of forEach() within an iframe in IE11?

The inquiry has been classified as off-topic, hence I have indicated the absent details. Summarized issue or bug along with minimal code necessary: The following code does not function in IE11 when embedded within an iframe on specific websites. (The ter ...

Adjust the size of an element by utilizing a different element

I'm facing a challenge with this code. I need to dynamically set the width of the "wrap-description" divs to be equal to the width of the corresponding "picture-damage" images plus an additional 20 pixels. Since there will be multiple elements for bot ...

Is there a way to first run my validate function and then proceed with sending my AJAX request upon clicking a button?

Hey there! I've got a dynamic table generated from a database. You can check out the table. I have all the necessary code in place, but what I really need is to ensure proper timing of execution for specific actions: 1) Verify if all mandatory fields ...

Issue with triggering onchange action for Multiple File Upload functionality

I'm currently in the process of developing a Website that requires a feature allowing users to upload multiple files. Here is the input-field I am working with: <div class="carousel-item carousel-custom-item active input-wrapper" > <inpu ...

The entry description function is not functioning properly when used with jGFeed

I have implemented jGFeed to extract data from an RSS Feed. Below is a snippet of the code I am using: $.jGFeed('http://feeds.bbci.co.uk/news/rss.xml', function(feeds){ // Check for errors if(!feeds){ ...

Nested Blocks in React Components

I am attempting to create a layout that includes text, a line, and a button similar to the design in this image: https://i.sstatic.net/RgGFU.png Although my code functions correctly, the CSS styling is not quite right: { retrospectives.size > 0 &&am ...

Encountering difficulties linking to a stylesheet or a script in an HTML file delivered by Express server

Currently, I'm facing the challenge of breaking down my Express app code into multiple files. Unfortunately, I am unable to utilize <link href> or <script src> for linking stylesheets or scripts. Below is the relevant snippet from my inde ...

I am encountering an issue with express-session where it is failing to assign an ID to

Seeking assistance with utilizing express-session to manage user sessions on arcade.ly. I have not specified a value for genid, opting to stick with the default ID generation. However, an ID is not being generated for my session. An example of the issue c ...

I am struggling to apply custom CSS styles to the scrollbar within a Card component using MUI react

import React from "react"; import Card from "@mui/material/Card"; import CardActions from "@mui/material/CardActions"; import CardContent from "@mui/material/CardContent"; import CardMedia from "@mui/material/Ca ...

Neglecting to validate types in the personalized response format within Express

I'm new to typescript and I've run into a problem where I can't seem to get my types validated. Route app.use((req: Request, res: Response) => { // here 404 is a string but should be a number according to type defined but no error is s ...

Saving HTML form field data through erb for persistent storage

Encountering an issue with erb while trying to populate the value of an HTML form field. The situation involves a scenario where the user has inputted an incorrect password and we want them to retain their name/email address information without having to r ...