Is there a way to modify the appearance of all <mark>clips</mark> in an HTML document using JavaScript?

Within my static html file filled with text, numerous snippets are highlighted using the <mark> tag. I am looking to incorporate a button that can toggle the weight of these marked text sections between bold and normal. This would create an effect where the highlighting can be turned on or off.

Is there a special method to achieve this by directly adjusting the style of the mark css class?

For instance:

  • HTML:
    ... Here is an <mark>key piece of information</mark> ...
  • CSS class BEFORE pressing the button: mark { font-weight: bold; }
  • CSS class AFTER pressing the button: mark { font-weight: normal; }

The purpose behind this feature is to give users the choice of viewing highlighted text or not. While I understand I could manually change the styling for each marked section, I am curious if there is a more direct approach available.

Answer №1

Strategy 1 - Changing the Style of Parent Element

An efficient approach involves adding a class to a parent element. By doing so, you can target all child mark elements using CSS without the need to loop through each mark element in JavaScript. This class can be applied to a wrapping div or even the main html element if desired.

The use of classList.toggle is widely supported across major browsers: https://caniuse.com/?search=classlist.toggle

function toggleMarkup() {
  document.querySelector("#content").classList.toggle("markup-shown");
}
p.markup-shown mark {
  font-weight: bold;
}
<p id="content">
Hello! This is some <mark>marked up</mark> text! And this is some more <mark>marked</mark> text.
</p>

<button onclick="toggleMarkup()">
Click me to toggle markup.
</button>

Strategy 2 - Leveraging CSSOM

https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model

You can also access and modify existing CSS classes directly from JavaScript:

const rules = document.styleSheets.map(sheet => sheet.cssRules);
const rule = rules.find(r => r.selectorText == 'mark');
rule.style.fontWeight = 'bold'; // or normal, based on your toggle logic

It's important to note that you would need to have a CSS rule defined beforehand like:

mark { font-weight: normal; }

Answer №2

Retrieve all mark elements in the document and toggle a highlight class to change their font-weight style. Use '.closest()' to find the parent elements of the mark elements and add a button to each parent element.

const marks = document.querySelectorAll('mark')

// Use event target to get the parent element and subsequent 
// mark element, then toggle a class for normal font weight
function toggleHighlight(e) {
  e.target.closest('li').querySelectorAll('mark').forEach(el => {
    el.classList.toggle('normal')
  })
}

marks.forEach(mark => {
  // Create a new button element
  const button = document.createElement('button')
  // Set text content for the button
  button.textContent = 'Toggle Highlight'
  // Find the parent element containing the mark and append the button to it
  // Make sure only one button is added per parent if there are multiple mark elements
  !mark.parentNode.innerHTML.includes('button') ? mark.parentNode.appendChild(button) : null  
  // Add event listener for button click event
  button.addEventListener('click', toggleHighlight)
})
mark {
  font-weight: bold;
}

.normal {
  font-weight: normal;
}

li {
  clear: left;
}

button {
  float: right;
}
<ul>
  <li>This is not important text</li><hr>
  <li><mark>This text here important text.</mark> But this is not. <mark>We have more important text here as well.</mark> Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Tristique et egestas quis ipsum suspendisse ultrices gravida dictum. Ac turpis egestas integer eget. </li><hr>
  <li>This is text not important text. <mark>But this is</mark></li><hr>
  <li><mark>This text here important text.</mark> But this is not</li><hr>
</ul>

Answer №3

At times, I implement the following function:

function modifyStyleRule(sheetIndex, selectorText, propertyName, propertyValue) {
    const cssRules = document.styleSheets[sheetIndex].cssRules;
    for (let i = 0; i < cssRules.length; i++) {
        if (cssRules[i].selectorText === selectorText) {
            cssRules[i].style.setProperty(propertyName, propertyValue);
        }
    }
}

You can utilize

modifyStyleRule(sheetIndex, 'mark', 'font-weight', 'bold')
to make text bold, and then
modifyStyleRule(sheetIndex, 'mark', 'font-weight', 'normal')
to revert it back.

(If you only have one stylesheet / style block, simply use sheetIndex=0. Otherwise, you may need to inspect [maybe using

console.log(document.styleSheets);
] to determine which stylesheet contains your mark rule.)

Answer №4

Have you considered implementing something like this?

<html>
    <head>
        <style>
            span {
                text-decoration: underline;
                color: red;
            }
        </style>
    </head>
<body>

Here is a <span>highlighted text section</span> and another <span>one</span>.

<button onclick = "changeSpanStyle()">Change Span Style</button>

<script>
    function changeSpanStyle() {
        document.querySelectorAll("span").forEach(e => e.style.textDecoration = "none");
    }
</script>

</body>
</html>

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

It appears that the Client Collection in Meteor JS is currently devoid of any data

It's been a while since I last delved into Meteor or the UI realm, so please bear with me if this is not articulated well. api/main.js: export const Nodes = new Meteor.Collection("nodes"); export const Links = new Meteor.Collection("links"); server ...

Is there a way to access the HTML and CSS source code without using the inspect feature

I'm working on a project that involves an "edit box" where users can write text, add emojis, change the background color, insert images, and more. After users finish creating their content, I want them to be able to send it via email. This means I ne ...

Show the message "Server is now active on port 5000" in the console but unfortunately cannot retrieve it

The backend API has a specific template that can be viewed here. Below is the code snippet for the backend: index.js import express from 'express'; import bodyParser from 'body-parser'; import mongoose from 'mongoose'; import ...

Refresh the dataTable following the form submission within the colorbox

On my page test.php, I am using jQuery DataTables to fetch data. There is a button labeled "Add Note" that opens an ajax form inside colorbox. The form submission process is functioning correctly, but I am looking for a way to refresh the DataTables when a ...

The JQuery Tooltip fails to function properly following an ajax load operation

I've inserted the following code into my website: $(document).ready(function() { $('.tooltip-game').jBox('Tooltip', { closeOnMouseleave: true, ajax: { url: 'tooltips/tooltip-game-html.jsp', reload: ...

How to transfer data using props through the ":to" attribute of a router link in Vue.js

I am facing an issue with creating a router-link in Vue and passing a route name as a prop. What I am trying to achieve is the following: <template> <div> <router-link :to="myProps">Login</router-link> </div> </tem ...

Unable to use OrbitControls with Node 12's ES6 import functionality

Currently, I am working with Node 12 (experimental-modules) and using npm for three.js. However, I'm facing issues with Imports when trying to include OrbitControls.js in my project. My index.js file is set as "script: module". Unfortunately, none of ...

What steps are needed to fetch aggregated data from mongodb and present it in ejs?

I am currently developing a forum application with two collections: User _id:60ccb13a21d65f0c7c4c0690 username: testuser name: test And Createpost _id:60d80b1305dcc535c4bf111a postTitle: "test post" postText: "aaaaa" postUsername: &qu ...

Is it possible to configure the jQuery datepicker to function without displaying the year?

I am looking to incorporate a datepicker into a project centered around historical events on specific dates. The concept is for users to select a day, such as "Nov. 20," and have the project display historical events from various years on that same day. ...

Node.js server continues running after attempting to stop with ctrl + C following starting the server using the command "npm start"

Whenever I initiate my server by typing node app.js in the command line on Git Bash, I can stop it simply by using ctrl + C. In my package.json file, I have configured a start script that allows me to use the command npm start to kickstart the server: "s ...

Ways to embed an HTML file into another HTML document

I have been attempting to include a footer.htm file in my index.htm document without success. Below is the code I am using. index.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.d ...

Tips for effectively managing asynchronous tasks

I keep getting different numbers every time my code runs. Can you tell me if I'm doing this the right way? Here's the code: export class GetPlanetsService { url='https://swapi.co/api/planets/?page='; planets:Planet[]=[]; headers: ...

Crafting an iframe that dynamically adjusts with Tailwind CSS

I'm having trouble ensuring that an iframe fits properly within a div while using tailwind CSS. I'm struggling to make the iframe responsive, no matter what class I try. Can anyone suggest a class that would help me achieve responsiveness for an ...

Is your $http request causing an XML parsing issue?

I'm attempting to utilize the $HTTP method from angularJS to access my restful web service. On entering my web service URL in the browser, I receive a result of APPLICATION/JSON type. {"id":20418,"content":"Hello, World!"} The URL for my web servic ...

What does the concept of hydration entail when working with React?

Recently, I've been delving into the world of React and stumbled upon the concept of hydration. Unfortunately, I'm a bit confused about how it operates. Can anyone provide some insights? Thank you in advance. While working on my React app, I enc ...

Tips for showcasing the chosen radio button onclick in Angular within ngFor

script.js //imports are all set ngOnInit() { this.list = { 'eatList': [{ 'type': 'Fruits', 'color': ['Red', 'White', 'Black'], ...

Is it possible to load a webpage in a WebBrowser control without displaying certain HTML elements by their IDs

Is there a way to load a specific page using the WebBrowser control without displaying unwanted advertisement banners in the 'tb' DIV element? I've searched online and came across an example that uses the mshtml reference, but I can't ...

Issue with rollover button function in Firefox and Internet Explorer when attempting to submit

I have created a rollover submit button using HTML and JavaScript: <input type="image" id="join" name="join" src="images/join.png" value="join"> My JS code implements the rollover/hover effect: <script type="text/javascript" charset="utf-8"> ...

Unexpected issue encountered when working with JSON in Node.js

I've searched through countless solutions on stackoverflow, but none of them seem to work for me. It's really frustrating not understanding what's going wrong. Below is the code I'm having trouble with: var data = ""; req.on('dat ...

Using Material UI's ProgressBar to create a countdown feature in a React

I am working on a feature where pressing a lock button changes the isReserved status of an item to true. This action also creates two new states in Firebase Firestore, namely startDate and expiryDate. The expiryDate is set to be 72 hours after the startDat ...