Home > OS >  Is it possible that if a span is a certain color do something?
Is it possible that if a span is a certain color do something?

Time:04-20

I want to make sure that when the span element turns lime, an alert box shows up, however, I tried using both hasAttribute() and getAttribute() to try to make the if statement function properly, but both did not work for me, the error may be occurring because the innerHTML is because configured in a forEach() function.

So far, when I click enter with the word "Absolute" put in the div boxes, the div boxes turn green, but no alert shows up.

Please help! Thank you in advance. Link to all lines of code just in case, sorry it may be a bit messy, I have a lot of code for a sololearn: https://code.sololearn.com/WX59M6HHngc5

const pText = document.querySelector("#p123").innerText.toUpperCase()
const button = document.querySelector("#ENTER")

Array.from(document.querySelectorAll(".amot")).forEach(function(element) {

button.addEventListener("click", () => {
  const text = element.textContent.toUpperCase()

  if (text.match(/\d/gi) || text.length < 1 || text.match(/[^a-z]/gi)) {
    element.innerText = text
    return
  }

  element.innerHTML = ""
  text.split("").forEach((letter, i) => {
    if (pText.includes(letter) && pText[i] === letter) {
      element.innerHTML  = `<span id = "span1" style="color: lime">${letter}</span>`
    } else if (pText.includes(letter)){
      element.innerHTML  = `<span style="color: orange">${letter}</span>`
    } else {
      element.innerHTML  = `<span style="color: lightgrey">${letter}</span>`
    }
  })
})

let sp1 = document.getElementById("span1");

if(sp1.hasAttribute('style') == "color: lime") {

alert("Test");

};

CodePudding user response:

From the above comment ...

"The first question I have is, whether the OP is in control of the code. If so there is no need to make an additional action dependent on an UI change. Instead the state change should trigger the UI change and the additional change. Thus a possible clean approach was to dispatch a custom event on statechange. In case of dealing with closed (third party) code there is still the possibility of utilizing a MutationObserver"

The CustomEvent approach for code one does own and is allowed to change, and where decoupling makes sense ...

const elmNode = document.querySelector('p')

elmNode
  // listen to an own custom event.
  .addEventListener('uiapprovalchange', evt => {
    if (evt.detail.isApproved) {

      console.log('text color should have changed into an approval state');
      // console.log({ evt: { detail: evt.detail } });
    } else {
      // console.clear();
    }
    console.log({ evt: { detail: evt.detail } });
  });

elmNode
  .addEventListener('click', ({ currentTarget }) => {
    const { dataset } = currentTarget;
    const doApprove = (dataset.approved !== 'true');

    dataset.approved = String(doApprove);
    currentTarget.style.cssText = doApprove ? "color: lime" : '';

    // create and dispatch an own custom event.
    currentTarget.dispatchEvent(
      new CustomEvent('uiapprovalchange', {
        detail: {
          isApproved: doApprove,
        },
      }),
    );
  });
<p>click in order to toggle the <em>approved</em> color change</p>

The MutationObserver approach for code one does not own and thus can not change/adapt to ones needs ...

function handleMutation(recordList, observer) {
  recordList.forEach(({ type, target, attributeName }) => {
    if (
      // assure correct mutation.
      type === 'attributes' &&
      attributeName === 'style' &&
      target.matches('body > p')
    ) {
      // normalize css text value.
      const text = target.style.cssText.replace((/\s /g), '');

      if (text.includes('color:lime')) {
        console.log('text color should have changed into an approval state');
      } else {
        console.clear();
      }
    }
  });
}
const targetNode = document.querySelector('p');
const options = { attributes: true };

const observer = new MutationObserver(handleMutation);
observer.observe(targetNode, options);

targetNode
  .addEventListener('click', ({ currentTarget }) => {
    const { dataset } = currentTarget;
    const doApprove = (dataset.approved !== 'true');

    dataset.approved = String(doApprove);
    currentTarget.style.cssText = doApprove ? "color: lime" : '';
  });
<p>click in order to toggle the <em>approved</em> color change</p>

CodePudding user response:

There isn't a native CSS event in JavaScript. The only option here is to periodically check the color.

For example:


const targetColor = '#ff0000';
const elementId = 'my-elem';

const checkColor = () => {
  const myElem = document.getElementById(elementId);
  const color = getComputedStyle(myElem).color;
  if (color && color.toLowerCase() === targetColor) {
    alert('Color has been changed.');
  }
}

setInterval(checkColor, 500);

Pitfalls

However, for this to work, you must know the exact color you're looking for, and specify it in the right format. You'll also need to add your own checks to ensure the element is found, and the CSS property is found, to prevent an error. Don't forget to also clear the setInterval when you're finished with it. Also keep in mind, that the user can manually change the color of the element, and then trigger your event.

Alternative

Using a frontend framework, like React or Vue would make the exercise significantly easier. You could manage the element's color with a data attribute, then just watch that attribute for changes without the need for setInterval.

Another option would be restructuring the app, so that events are triggered based on a user interaction, and those same events set the class (or color) of a given element.

  • Related