Retrieving a compilation of items found within text selected by the user on a website

Imagine a scenario in which a webpage contains the following structure:

 <p>
 <span class="1">Here's some text</span>
 <span class="2">that the user</span>
 <span class="3">could select.</span>
 </p>

If a user decides to select the entire sentence (from "Here's" to "select."), the desired output should be "1" and "3".

In cases where only a portion of the sentence is highlighted (e.g., from "some" in span 1 to "the" in span 2), the expected return values are "1" and "2".

Is there an optimal method or strategy that can be employed for this task?

*Edit - It is worth noting that my goal is to find a solution that supports highlighting multiple non-overlapping sections of text simultaneously.

For instance: "Here's some text that" and "user could select." - If this type of selection is made, the result should be [[1,2],[2,3]].

Answer №1

Edit: Recently discovered the existence of a selection.containsNode method which seems like it could be a great fit for your needs, although it's still considered experimental technology.

Given that there isn't an extensive highlight event in javascript, finding a solution won't be straightforward. The text being split across multiple elements further complicates things. While you could potentially utilize document.selection as suggested by the top response to a similar inquiry, parsing the returned text against the innerHTML of the span elements might prove to be quite challenging.

In this scenario, it might be best to recreate highlight functionality using existing JS events. Below is a basic implementation lacking some features like double-clicking for selection and keyboard selection, but it serves as a starting point.

const hLights = Array.from(document.querySelectorAll('.hlight'));
let active = false;
let hoveredEls = [];

window.addEventListener('mousedown', function() {
  active = true;
});

window.addEventListener('mouseup', function() {
  active = false;
  console.log(hoveredEls);
  hoveredEls = [];
});

hLights.forEach(el => {
  el.addEventListener('mousemove', function() {
    if (active && !hoveredEls.includes(el.id)) hoveredEls.push(el.id);
  });
  el.addEventListener('mouseenter', function() {
    if (active) {
      if(hoveredEls.includes(el.id)) {
        const idx = hoveredEls.findIndex(el => el === el.id);
        hoveredEls.splice(idx, 1);
      } else {
        hoveredEls.push(el.id);
      }
    }
  });
});
<p>
 <span id="1" class="hlight">Here's some text</span>
 <span id="2" class="hlight">that the user</span>
 <span id="3" class="hlight">could select.</span>
</p>

Answer №2

here's the HTML code snippet:

    <span class="class-1" 
    onmousedown="getElementBegin('1')" onmouseup="getElementEnd('1')" >
        some text 1
    </span> <br>
    <span class="class-2" 
    onmousedown="getElementBegin('2')" onmouseup="getElementEnd('2')">
        some text 2
    </span> <br>
    <span class="class-3" 
    onmousedown="getElementBegin('3')" onmouseup="getElementEnd('3')">
        some text 3
    </span> <br>

    <p id="selected"> nothing!</p>

And here is the javascript part:

let beginning
let ending
let selectedText

document.onmouseup = function () {
selectedText = window.getSelection().toString()
console.log(selectedText);

currentSelection = document.getElementById('selected')
currentSelection.innerHTML = `selected range: ${beginning} to ${ending} <br> selection: ${selectedText}`
}

function getElementBegin(begins) {
beginning= begins
console.log(beginning)
}

function getElementEnd(ends) {
ending = ends
console.log(ending)
}

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

What is the reason for the absence of Duplex Stream in the Web Streams API?

I have experience working with the traditional nodejs stream, which makes the need for Duplex streams quite evident. These are streams that can both read and write data, like net.Socket. As mentioned here Examples of Duplex streams include: TCP sockets ...

Is it possible to create a CSS checkbox without using an ID or "for" attribute

Is it possible to create a CSS checkbox with label without using id and for attributes? I have tried the following method, but it doesn't seem to work. I know that I can create a CSS checkbox with id and for attributes like this: <div class="chec ...

Set up a timed event for a .js file to execute

I am currently exploring options for automatically running a JavaScript file multiple times per day, similar to Task Scheduler on Windows. Right now, I manually run the file in VS Code or Command Prompt using the command "node file.js". Is there a way to a ...

Encountered a error 500 while attempting to POST using Postman in Node.js

After successfully setting up the server, I encountered an issue when attempting to create a user using Postman with the details in Application/JSON format. The server responded with: POST /sign-up 500. Initially, I tried specifying utf-8 without succes ...

Node.js middleware for verifying required parameters

In my current application, I am utilizing node.js and express. I have developed multiple middleware functions, each one created in a similar fashion: function loadUser(req, res, next){ ... } I am interested in creating a middleware that can validate th ...

I am utilizing client-side JS to send a large number of requests. What methods can I implement to enable my server to cache this content

Here's a bit of an unusual question from someone who is new to this - I have client-side JavaScript that is making API calls using the getJSON method. Since the content doesn't change frequently, I would like to store the results on my server an ...

What are the steps to set a 404 status code in next.js when utilizing ISR with a fallback of "blocking"?

When a route does not match, what is the best way to redirect to a 404 error page and ensure that the status code is displayed as 404 in the network tab using ISR with fallback: "blocking"? ...

Setting the state variable value asynchronously using AngularJS UI-If

Is it possible to limit access to the sidebar until the user has completed the login process? The sidebar is located outside the main ui-view section I am assuming that authenticated is a state variable <div ng-controller="MyController" ui-prevent-to ...

The issue with the AngularJS filter seems to be arising specifically when applied to

My AngularJS filter isn't functioning properly when used with an Object. Here's the View: <input type="text" ng-model="searchKeyUser.$" placeholder="Search Keys" class="form-control"><br> <ul class="list-group"> <li cla ...

Rapidly generate VueJS templates for quick display

Is there a way, similar to KnockoutJS, to easily render content from a template using an ID? <script type="text/html" id="template-example"><span>Hello world!</span></script> <div data-bind="template: &a ...

How can you handle undefined values in the query object parameter when using Mongoose's Find function?

Alright: Sound.find({ what: req.query.what, where: req.query.where, date: req.query.date, hour: req.query.hour}, function(err, varToStoreResult, count) { //perform some actions }); Let's consider a scenario where only req.query.what has a ...

Trying to replace all instances of a word in an HTML document with a <span> element, but only for <p>, <span>, and <div> tags. It shouldn't work if the parent node already contains

Here is the HTML code snippet I am working with: <div> hello world <p> the world is round <img src="domain.com/world.jpg"> </p> </div> I am looking to replace the word "world" (or any mixed case variations) with < ...

Is it possible to use jQuery to create a slide-up effect from the

Could I reverse the animation direction of my dropdown menu? Currently, it expands from the top to bottom. Is there a way to make it expand from the bottom to the top? Code snippet: animate({height:'show',opacity:'show'}, ddsmoothmenu ...

Ways to monitor and measure clicks effectively

Within my website, I have a table element with one column and numerous rows. Each row serves as a hyperlink to an external shared drive. <tr><td ><a href="file://xxx">Staff1</a></td></tr> <tr ><td ><a h ...

When the visitor is browsing a particular page and comes across a div element, carry out a specific action

I am trying to determine if I am currently on a specific page and, if so, check if a certain div exists in that page. Here is what I know: To check if a specific page exists, I can use the code if('http://'+location.hostname+location.pathname+& ...

What could be causing my divs to overlap?

I recently started coding and I'm facing an issue with my <header> and <section> divs overlapping each other. I was under the impression that being block elements, <section> should be displayed below <header>. Any suggestions o ...

Converting php array submitted from a form using ajax

I have a form on my website that collects user input and sends it to an email address using php. The form includes a checkbox input where users can select multiple options, which are then stored in an array. However, when the form is submitted, the email r ...

What is the process for loading an HTML form into a specific target using Angular?

Is there a way to load an HTML form into a target in Angular without the use of jQuery? I have a working script, but I am currently stuck on: <html> <head> <script src="components/angular/angular.js"></script> <script&g ...

Retrieve the maximum number of slots from a JSON file and implement them into the

I've encountered an issue with my upload form. After uploading and previewing an image, I want to add it to a list as long as the list still has available slots. Here's an example: If the maximum number of slots is set to 5, then you can add up ...

Activate audio and trigger notification

I'm looking to incorporate a small beep sound into my web application before displaying an alert message. Here's what I currently have: if(_none_valid) { $.playSound('/static/wav/beep_error.wav').delay(300); alert('ERROR: ...