0

I am trying to achieve blinking effect to a single character of an array.

For example, if "text" get load inside paragraph <p> tag or container then first character of text should blink and when user types the blinking character in input area blinking effect must move to blink on next character.

I need assistance in solving this problem. Any instructions or help will be so grateful.

Here what I've tried so far:

let displayElem = document.getElementById("me");
const inputElem = document.getElementById("input");
const text = "Hey It's bad day, not a bad life,you'll be okay...!"

text.split('').forEach(char => {
  const chrspan = document.createElement('span')
  chrspan.innerText = char;
  displayElem.appendChild(chrspan);
});


inputElem.addEventListener('input', () => {
  var vl = document.getElementById("input").value;
  const arrayq = displayElem.querySelectorAll('span')
  const arrayv = inputElem.value
  let correct = true;

  arrayq.forEach((chSpan, index) => {
    const char = arrayv[index];

    if (char == null) {
      correct = false;
    } else if (char === chSpan.innerText) {
      chSpan.classList.add('blink-bg')
    } else {
      chSpan.classList.remove('blink-bg')
      correct = false
    }
  })
})
.blink-bg {
  text-align: center;
  color: #fff;
  display: inline-block;
  border-radius: 3px;
  animation: blinkingBackground 1s infinite;
}

@keyframes blinkingBackground {
  from { background-color: #f1ebeb; }
  to { background-color: #080808; }
}
<p id="me"></p>
<input id="input" type="input" />

let displayElem = document.getElementById("me");
const inputElem = document.getElementById("input");
const text = "Hey It's bad day, not a bad life,you'll be okay...!"

text.split('').forEach(char => {
  const chrspan = document.createElement('span')
  chrspan.innerText = char;
  displayElem.appendChild(chrspan);
});

inputElem.addEventListener('input', () => {
  var vl = document.getElementById("input").value;
  const arrayq = displayElem.querySelectorAll('span')
  const arrayv = inputElem.value
  let correct = true;

  arrayq.forEach((chSpan, index) => {
    const char = arrayv[index];

    if (char == null) {
      correct = false;
    } else if (char === chSpan.innerText) {
      chSpan.classList.add('blink-bg')
      // document.getElementById("p_id").innerHTML = chSpan.innerText;
    } else {
      chSpan.classList.remove('blink-bg')
      correct = false
    }
  })
})
2
  • Are you requiring that when the second character is typed the first character stops having the blinking effect? Commented Oct 27, 2021 at 19:27
  • thanks for your comment and Yes. it must stop in previews character. Commented Oct 28, 2021 at 14:11

1 Answer 1

1

This might be a good starting point for you. I changed a couple things, I made a helper function $ to grab items from the dom as a personal prefrence.

I created an array of all the spans on the document, making it easier to keep track of which element has the blinking class. I created a helper function to grab what the activeText is from the txtArr instead of checking the text content. This way I can avoid using the rendered screen as a storage area for information, and instead have the screen mirror what is happening in my js.

On input I check the last character entered, and if it is the character that is blinking, I increment increment which span is blinking.

This is meant to be a simple demo of how to accomplish this task, you may want to have different functionality, but hopefully this helps as a starting point!

const $ = str => [...document.querySelectorAll(str)];
let displayElem = $("#me")[0];
const inputElem = $("#input")[0];
const text = "Hey! It's a bad day, not a bad life, you'll be okay...!"
const txtArr = [...text];
const txtSpans = txtArr.map(char => {
  const span = document.createElement("span");
  span.innerText = char;
  return span;
});
let activeIndex = -1;
const activeText = () => txtArr[activeIndex];

function renderSpans() {
  displayElem.innerHtml = "";
  txtSpans.forEach(span => displayElem.appendChild(span));
};

function updateActive() {
  const firstRun = activeIndex == -1;
  if (!firstRun) 
    txtSpans[activeIndex].classList.remove("blink-bg");
  activeIndex++;
  if (activeIndex == txtSpans.length) return;
  txtSpans[activeIndex].classList.add("blink-bg");
}
updateActive();
renderSpans();

inputElem.addEventListener('input', e => {
  const val = e.target.value;
  if (val == "") return;
  const lastChar = val[val.length - 1];
  if (lastChar == activeText()) updateActive();
})
.blink-bg {
  text-align: center;
  color: #fff;
  display: inline-block;
  border-radius: 3px;
  animation: blinkingBackground 1s infinite;
}

@keyframes blinkingBackground {
  from { background-color: #f1ebeb; }
  to { background-color: #080808; }
}
<p id="me"></p>
<input id="input" type="input" />

Sign up to request clarification or add additional context in comments.

1 Comment

I've noticed that pressing backspace when making a mistake, if the last char in a string is the target char, it will increment (as told), which may not be intended. Also spaces don't blink as intended.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.