Need help reading regular expression

I copied a script from the web to add highlights to my paragraph elements and the script contained the following regular expression:

var re = new RegExp('(^|\\s)'+cl+'(\\s|$)');

Now I’m reading up on regular expressions to decipher the code but I wanted to accelerate the process by posting to this forum. Can anyone explain what the regular expression finds in the meantime?

matches start of a line ^ or a single space \\s, followed by whatever the value of ‘cl’ is, followed by either a single space or end of the line $

Thanks, rpg_digital
Here is the entire function:

removeClass = function(el,cl) {
var re = new RegExp('(^|\\s)'+cl+'(\\s|$)');
if (el.className.match(re))
el.className=el.className.replace(re,' ');
};

cl is a parameter of the removeClass function. I don’t know what cl stands for in the function.

This is a very old script to remove a class from an element.

You would be better off using MDN classList

Specifically element.classList.remove(className)

3 Likes

Can you help me re-write it without using the regular expression?

Sure thing but let’s go one further, doing it without the whole removeClass function.

Instead of using the function call of removeClass(someEl, "classname") you do the following instead:

someEl.classList.remove("classname");

It’s highlighting a paragraph with the highlight class so it would be something like this:

var x = document.getElementsByTagName("p");
x.classList.remove('highlight');
1 Like

I tried doing it without the function but it didn’t work. I’m missing something.

Using

var x = document.getElementsByTagName("p");
x.classList.remove('highlight');

removed all of the class names before they were added.

The code to add the class looks like this:

addClass = function(el,cl) {
var re = new RegExp('(^|\\s)'+cl+'(\\s|$)');
if (!el.className.match(re)) el.className += " "+cl;
};

I think that both of the functions need to be re-written.

I’m noticing a possible confusion here. The getElementsByTagName method gives you an array-like object of multiple elements, but classList doesn’t exist on such a list. It’s only for use on single elements instead.

If you wanted to remove highlight from all <p> elements, you would need to loop through those elements, with something like this:

var paras = document.querySelectorAll("p");
paras.forEach(function (para) {
    para.classList.remove('highlight');
});

Here is a test script that demonstrates the technique in action.

function removeHighlightHandler() {
  var paras = document.querySelectorAll("p");
  paras.forEach(function (para) {
      para.classList.remove('highlight');
  });
}
const removeHighlight = document.querySelector("#removeHighlight");
removeHighlight.addEventListener("click", removeHighlightHandler);

Or, if we retain the getElementsByTagName, we can convert it into an array to use forEach:

function removeHighlightHandler() {
  var paras = document.getElementsByTagName("p");
  Array.from(paras).forEach(function (para) {
      para.classList.remove('highlight');
  });
}
const removeHighlight = document.querySelector("#removeHighlight");
removeHighlight.addEventListener("click", removeHighlightHandler);

Or, if we don’t want to use Array.from, we can use Array.prototype.forEach instead:

function removeHighlightHandler() {
  var paras = document.getElementsByTagName("p");
  Array.prototype.forEach.call(paras, function (para) {
      para.classList.remove('highlight');
  });
}
const removeHighlight = document.querySelector("#removeHighlight");
removeHighlight.addEventListener("click", removeHighlightHandler);

I do prefer the first one though, with the querySelectorAll technique.

Thank you, Paul_Wilkins!

This is to highlight the paragraphs as the page is scrolled. The paragraph in the viewport gets highlighted and then the highlight goes away as the page is scrolled away. So I’m not using a button click event; I’m using a scroll event. I don’t know what to use instead of the button with an id of #removeHighlight. Any idea?

With a scroll event that tends to be done on the window instead, but it’s preferred to use a limiter on that scroll event so that it’s not run 100 times per second.

I recommend using the lodash library, because that provides easy access to a throttle command.

window.addEventListener('scroll', _.throttle(removeHighlightHandler, 250));
1 Like

I have the following two functions:


function addHighlightHandler() {
  var paras = document.getElementsByTagName("p");
  Array.from(paras).forEach(function (para) {
      para.classList.add('highlight');
  });
}
window.addEventListener("scroll", addHighlightHandler);


function removeHighlightHandler() {
  var paras = document.getElementsByTagName("p");
  Array.from(paras).forEach(function (para) {
      para.classList.remove('highlight');
  });
} 
window.addEventListener("scroll", removeHighlightHandler);

But this doesn’t work. Only one of the scroll events can execute. How do I write it so that both functions get executed?

You are both adding and removing the highlight whenever the window scrolls. That is of course going to have no beneficial effect.

Instead of getting extremely specific with code right now, let’s try and have you explain in words what you want you code to achieve.

This is to highlight the paragraphs as the page is scrolled. The paragraph in the viewport gets highlighted and then the highlight goes away as the page is scrolled away. There is already a scroll event listener in the code so it wouldn’t be good to add it again with the add and remove handlers.

It’s for an assignment so it can’t be written in jQuery.