我有两个段落,由 8 行组成,每行包含 12 个字符。这些字符要么是随机符号,要么是位置随机的完整单词。我的代码应该突出显示单个字符(如果它们是符号)或当鼠标悬停在它们上方时突出显示整个单词。
我的计划是用跨度包裹字符并向它们添加侦听器,以便在发生悬停事件时能够突出显示它们。虽然这有效(符号被突出显示,单词被突出显示),但当我在周围移动光标时,字符会随机消失。
这是代码
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();
我很感谢您的帮助。
每次将鼠标悬停在其中一个 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>