Getting the selection within a particular div – how can it be done?

Currently, I am working on a contenteditable div feature (identified by id 'editor1') which allows users to input text. Additionally, there is a function that enables users to highlight and change the color of selected text. In my JavaScript code, I utilize

window.getSelection().getRangeAt(0)
, however, I have encountered an issue where users can select text outside of the div causing all highlighted words to change color. To address this problem, I have attempted the following:


        function red(){
    {       
        var getText = document.getElementById("editor1").innerHTML;
        var selection = getText.getSelection().getRangeAt(0);
        var selectedText = selection.extractContents();
        var span = document.createElement("span");
        span.style.color = "red";
        span.appendChild(selectedText);
        selection.insertNode(span);
    }
    }

You can view a live example here: https://jsfiddle.net/xacqzhvq/

Currently, if I were to highlight "this will become red as well," the button allows me to change the color as desired. However, my main concern remains - how can I limit the color-changing functionality to only affect text within the editor1 div?

Answer №1

If you want to retrieve the node element from the selection, you can use .baseNode method. Once you have accessed the base node, you can then obtain the parent node and utilize it for comparison purposes.

function red(){
    // Stop the function and return if the selected element does not have an id of "foo"
    if(window.getSelection().baseNode.parentNode.id != "foo") return;
    ...
    // Perform highlighting if it matches our specified div.
}

In the following example, I have assigned an id to the div which can be checked to ensure it is the desired element:

Demo


As mentioned by @z0mBi3, this approach will work initially but may not be suitable for multiple highlights (especially if they are cleared). The presence of <span> elements within the div forms a hierarchy where the div serves as the parent node for numerous span elements. To address this, you can traverse up through the ancestors of the node until locating one with the id of "foo".

Fortunately, jQuery offers a convenient solution using their .closest() method:

if($(window.getSelection().baseNode).closest("#foo").attr("id") != "foo") return;

Here is a resource detailing a native JS implementation of .closest().

Answer №2

Here is a code snippet for you to try:

function addBold(){
 
if(window.getSelection().focusNode.parentElement.closest("#editor").id != "editor") return;

 





  const selection = window.getSelection().getRangeAt(0);
  
  let selectedParent = selection.commonAncestorContainer.parentElement;
  

  let mainParent = selectedParent;
  
  if(selectedParent.closest("b"))
  {
  //Unbold
    var text = document.createTextNode(selectedParent.textContent);
    mainParent = selectedParent.parentElement;
    mainParent.insertBefore(text, selectedParent);
    mainParent.removeChild(selectedParent);
    mainParent.normalize();
  }
  else
  {
    const span = document.createElement("b");
    span.appendChild(selection.extractContents());
    selection.insertNode(span);
    mainParent.normalize();
  }
  

  if (window.getSelection) {
    if (window.getSelection().empty) {  // Chrome
      window.getSelection().empty();
    } else if (window.getSelection().removeAllRanges) {  // Firefox
      window.getSelection().removeAllRanges();
    }
  } else if (document.selection) {  // IE?
    document.selection.empty();
  }




};
<div id="editor" contenteditable="true">

You are the programmers of the future 

</div>


<button onclick="addBold()">Bold</button>

This code was inspired by the information provided in the following answers:

Solution for bold/unbold selected text using Window.getSelection()

Fix for getSelection().focusNode inside a specific id not working

Answer №3

Are you in search of the following:

  //html
  <body>
     <p id='editor1'>asdf</p>
     <button onclick='red()'>
     RED
     </button>
  </body>

  //JavaScript

    window.red = function(){
        //var getText = document.getElementById("editor1").innerHTML;
        var selection = window.getSelection().getRangeAt(0);
        var selectedText = selection.extractContents();
        var span = document.createElement("span");
        span.style.color = "red";
        span.appendChild(selectedText);
        selection.insertNode(span);
    }

Check out the Plunker example here: https://plnkr.co/edit/FSFBADoh83Pp93z1JI3g?p=preview

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

Issue with Safari not displaying properly when using float:left and float:right (works fine in Firefox and Chrome)

My website has a left side column and a right side column, which display correctly in Firefox and Chrome. However, I am experiencing issues with Safari. Any insights on what could be causing this problem and why it only occurs in Safari? View the code on ...

Tips for setting up a proxy with an enum

I am facing an issue with setting up a Proxy for an enum. Specifically, I have an enum where I want to assign a value to this.status using a Proxy. However, despite my expectations, the output "I have been set" does not appear in the console. Can anyone ex ...

Tips for accessing a child element within a specific div from a selection of divs in Angular

I recently started learning angular and I am working on a project that involves displaying a list of people. Each person's name is displayed along with a button to send a friend request. When the send request button is clicked, it should disappear and ...

Revamping elements according to ordered array. Angular version 4.3

Dealing with an array of data that needs to be sorted for displaying in a component seems to be a challenge. Despite having a functional code sample demonstrating the concept, the sorting is not reflected in the Angular app's DOM. The original data i ...

execute javascript functions upon page load

I am facing a dilemma with my JavaScript functions which are meant to fetch content when the page loads. I attempted using window.onload to trigger the functions but unfortunately, it did not work as expected. Essentially, I require multiple functions to ...

What is the process for transforming a Binary field from type 4 to type 0?

Is there a way to convert a Binary field of type 4 to type 0 using a Shell script? I considered executing a simple script such as the one below: db.places.find({}).forEach(function(data) { // How can I access the data? print(data.id); // db. ...

Filtering GridView Results with Live Search on ASP.net Textbox

I am currently working on implementing a live search feature for my ASP.net project. The goal is to have a description textbox where users can enter their search term, and the GridView below will dynamically filter the results as the user types. While I ...

Unable to obtain the accurate response from a jQuery Ajax request

I'm trying to retrieve a JSON object with a list of picture filenames, but there seems to be an issue. When I use alert(getPicsInFolder("testfolder"));, it returns "error" instead of the expected data. function getPicsInFolder(folder) { return_data ...

Utilize the HTML img tag in conjunction with AngularJS and Ionic to showcase dynamic images

Currently, I am working on a hybrid mobile app using ionic and Angularjs. I am facing an issue with displaying images through the img html tag in my app. The main layout of my page includes a carousel at the top that displays images and a list containing s ...

"Form submission fails to populate _POST when file and text fields are used simultaneously

Looking for a solution... <form action="upload.php" method="get" enctype="multipart/form-data"> Enter a 10 digit mobile number: &nbsp;<input id="imgphno" type="text" maxlength="10" /> <br/><br/> <input id="file" type="file" ...

Troubleshooting problem with Chrome's getRangeAt function following changes to innerHTML of a contenteditable div using code

Here is an example of my HTML code: <button onclick="testfunction()">test</button> <div id="divT" spellcheck="false" contenteditable="true"></div> This is the JavaScript portion: document.get ...

Map Row is unreturned

I am having trouble when attempting to map a JSON response from a MySQL query as I am receiving no response: data: NULL This is the code in question: const audience = rows.map((row) => { db.query(CountAudiences, [row.campaign], function(err, count ...

Delve into the world of tackling catastrophic backtracking with regex in Node

Currently, my node.js script includes this regex: const commentPattern = new RegExp( '(\\/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)', 'g&a ...

Responsive left and right image styling in CSS and HTML

I have designed a landing page with fixed left and right images and content in the middle. It looks fine on desktop view, but on mobile view, the images are overlapping the content. How can I resolve this issue? <div class=" ...

developing a segment within an HTML document

Recently, I came across a fascinating website at . I was particularly intrigued by the way the right and left columns expand and contract dynamically when clicked. As someone new to web development, especially in terms of dynamic websites using jQuery, I ...

Javascript: Understanding Error Handling in the Context of Async Await

I am looking to strengthen my logical reasoning, not diving into abstract concepts. Scenario 1: try { var result = await new IamErrorAlways() if (result && result instanceof Error) return result // Is this the appropriate error handling method? } ca ...

Filtering text for highlighting in Vue.js is a breeze

Struggling to create a text highlight filter using vuejs. The task involves iterating through an array of words, highlighting any matches with a span and class. However, I'm facing difficulty in getting the data to return with proper HTML formatting i ...

Exploring the Use of data- Attributes in SVG Circle Elements

Looking for a way to dynamically update the color of a Circle element in your SVG when it is clicked? You can achieve this by using jQuery's .css() method in conjunction with the data-* attribute. CHECK OUT AN EXAMPLE: STYLING IN CSS svg { height ...

The challenge of aligning widgets in bootstrap panels across different browsers

Incorporating angularjs and bootstrap3, I'm in search of the best way to center widgets within a panel and achieve responsive behavior. Interestingly, the results vary across browsers, particularly in Firefox. Within my code, I have 4 column divs str ...

Steps to turn off fancybox for mobile and show the full image instead

In this scenario... I am seeking a way to deactivate fancybox functionality on mobile devices. I have already discovered one method to disable it... And now I want to directly show the large image in the a href="xxx_large.jpg" instead of using the img src= ...