将鼠标悬停在段落元素上后会从段落元素中删除随机字符

问题描述 投票:0回答:1

我有两个段落,由 8 行组成,每行包含 12 个字符。这些字符要么是随机符号,要么是位置随机的完整单词。我的代码应该突出显示单个字符(如果它们是符号)或当鼠标悬停在它们上方时突出显示整个单词。

我的计划是用跨度包裹字符并向它们添加侦听器,以便在发生悬停事件时能够突出显示它们。虽然这有效(符号被突出显示,单词被突出显示),但当我在周围移动光标时,字符会随机消失。

Here is what it is supposed to look like Here is what happens after I move my cursor around the right paragraph

这是代码

const garbage = ["`", "~", "!", "@", "#", "$", "%", "^", "&", "*", "-", "_", "=", "+"];
const wordBank = ["jujube", "muzzle", "puzzle", "whizzo", " jimply", "jinxed", " fezzes", "queazy"];
const numOfRows = 8;

const password = wordBank[randomNum(0, wordBank.length)];

function fillText() {
    fillParagraph("left-p");
    fillParagraph("right-p");
}

function fillParagraph(pId) {
    let string = "";
    let wordPos = [];
    let counter = 0;

    //find valid word positions
    for (let i = 0; i < (wordBank.length); i++) {
        let validPos = false;
        while (!validPos) {
            validPos = true;
            const randomNumber = randomNum(0, (12 * numOfRows) - 6);
            for (let j = 0; j < wordPos.length; j++) {
                if ((randomNumber >= (wordPos[j] - 6)) && (randomNumber <= (wordPos[j] + 6))) {
                    validPos = false;
                    break;
                }
            }
            if (validPos) {
                wordPos.push(randomNumber);
            }
        }
        if (counter === 3) {
            break;
        }
        counter++;
    }

    //add the words to the random locations and make sure they do not go over 12 characters per row
    for (let i = 0; i < (numOfRows * 12); i++) {
        if (i % 12 === 0 && i !== 0) {
            string += "\n";
        }

        let counter = 0;

        if (wordPos.includes(i)) {
            for (let j = 0; j < wordBank[0].length; j++) {
                if (i % 12 === 0 && i !== 0 && j !== 0) {
                    string += "\n";
                }

                string += wordBank[0].charAt(j);
                i++;
            }
            wordBank.shift()
            if (i % 12 === 0 && i !== 0) {
                string += "\n";
            }
            counter++;
        }
        string += garbage[randomNum(0, garbage.length - 1)];
    }

    const paragraph = document.getElementById(pId);
    paragraph.setAttribute('style', 'white-space: pre;')
    paragraph.textContent = string;
}

function randomNum(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function highlight(event) {
    const text = event.target.textContent;
    const regex = /^[a-zA-Z]$/;
    const tempArray = [];
    const characters = text.split("");

    //surround individual characters or words with spans
    for (let i = 0; i < characters.length; i++) {
        const char = characters[i];
        //wrap whole word
        if(regex.test(char)) {
            let word = "";
            for(let j = 0; j < 6; j++) {
                word += characters[i];
                i++;
            }
            tempArray.push(`<span class='chars'>${word}</span>`);
            continue;
        }
        //wrap individual character
        tempArray.push(`<span class='chars'>${char}</span>`);
    }

    event.target.innerHTML = tempArray.join("");

    let spans = event.target.querySelectorAll(`.chars`);
    console.log(spans)
    spans.forEach((span) => {
        span.addEventListener("mouseover", function () {
            // Add the yellow background color to the currently hovered character
            span.style.backgroundColor = "yellow";
        });

        span.addEventListener("mouseout", function () {
            // Remove the background color when the mouse leaves
            span.style.backgroundColor = "";
        });
    });
}

function functionality() {
    const elementL = document.getElementById("left-p");
    elementL.addEventListener("mouseover", highlight);
    const elementR = document.getElementById("right-p");
    elementR.addEventListener("mouseover", highlight);
}

fillText()
functionality();

我很感谢您的帮助。

javascript hover event-listener
1个回答
0
投票

每次将鼠标悬停在其中一个 div 上时,都会触发 Hightlight 函数,当突出显示发生时,它基本上会遍历文本,如果它与正则表达式(第一个 aplha 字符)匹配,则会将几个字符放在一个跨度中并更新仅包含那些跨度元素的页面。基本上,由于正则表达式的匹配方式以及您如何遍历各个字符(即使第一个匹配),每次将鼠标悬停时都会丢失特殊字符。请注意,将鼠标悬停在一堆之后,它最终只会是 a-zA-Z 字符。

我认为,如果您在构建初始显示时将事情整理好,然后由 css 处理悬停,而不是尝试通过悬停事件来完成所有操作,那么这会简单得多。

const wordBank = ["jujube", "muzzle", "puzzle", "whizzo", " jimply", "jinxed", " fezzes", "queazy"];
const garbage = ["`", "~", "!", "@", "#", "$", "%", "^", "&", "*", "-", "_", "=", "+"];
let txtOutput = '';

function fillText() {
  let temp = wordBank.concat(garbage);
  for( let i = 0; i < temp.length; i++) {
    txtOutput += '<span class="char">' + temp[Math.floor(Math.random() * temp.length)] + '</span>';
  }
  document.querySelector("#myDiv").innerHTML = txtOutput;
}

fillText();
.char:hover {
  background-color: yellow;
}
<div id="myDiv"></div>

© www.soinside.com 2019 - 2024. All rights reserved.