问题描述
我对 JavaScript 非常缺乏经验,所以可能有一种我不知道的方法,如果是这样,请告诉我。我正在尝试为句子中的每个单词获取单独的悬停事件。
我目前正在网站上显示数组中的句子。
for (i=0; i<sentences.length; i++){
var sent = sentences[i].sentence_text;
display_list += "<li class='text_sent'>" + sent + "</li>";
}
我希望能够为每个句子中的每个单词设置一个单独的悬停事件,因此我将句子拆分为一个数组。
for (i=0; i<sentences.length; i++){
var sent = sentences[i].sentence_text;
var text_array = sentence_text.split(" ");
display_list += "<li class='text_sent'>" + text_array + "</li>";
}
我没有超出这一点,因为我不想显示数组内容。如果我确实显示数组,它会在数组的每个项目之间显示逗号。我想要的是让句子继续看起来像拆分之前一样,但是每个单词都可以单独访问。
这可能吗?
如果是这样,我怎样才能让每个单词都有一个单独的鼠标悬停事件?例如,我怎样才能做到每次将鼠标悬停在一个单词上时,工具提示框都会显示该单词在句子中的编号?
编辑:为了清晰起见,必须修复代码。
解决方法
也许这会帮助你前进
const statements = [{
glossHand: "this is a test"
},{
glossHand: "this is another test"
}];
const display_list = statements.map(statement => {
return `<li class="text_sent">` +
statement.glossHand.split(" ").map((word,i) => `<span class="word" pos="${i + 1}" statement="${statement.glossHand}">${word}</span>`).join(" ") +
"</li>";
});
const message = document.getElementById("message");
const words = document.getElementById("words");
words.innerHTML = display_list.join("");
words.querySelectorAll(".word").forEach(word => {
word.addEventListener("mouseover",() => {
const span = event.target;
const pos = span.getAttribute("pos");
const statement = span.getAttribute("statement");
message.innerText = `""${span.innerText}" is the (${pos}) word of "${statement}"`;
});
word.addEventListener("mouseout",() => {
message.innerText = "";
});
});
<ul id="words">
</ul>
<p>
<div id="message">
</div>
</p>
你的分词方法很笼统,如果词之间有几个空格会失败。
我建议你改用这个:
sentence_text.trim().split(/\s+/)
只要每个“词”都被标签包围,您就可以为每个“词”使用标题属性。
在我这里的例子中,我只使用了一个 span 标签
css是另外的,我把函数(IIEF)允许对初始文本进行转换
(function()
{
let count = 0
document.querySelectorAll('article p').forEach(paragraph=>
{
let wordsArray = paragraph.textContent.trim().split(/\s+/) // separate words
.map(w=>`<span title="${++count}">${w}</span>`)
paragraph.innerHTML = wordsArray.join(' ')
})
}
)()
article p span {
cursor : help;
}
article p span:hover {
background-color : yellow;
}
<article>
<p>I haven't gotten beyond this point because I don't want to display the array contents.
If I do display the array it displays commas between each item of the array.
What I want is for the sentence to continue looking like it did before it was split,but for each word to be separately accessible.</p>
<p>Is this possible?</p>
<p>If so,how can I get each word to have a separate mouse-over event? For example,how can
I make it so that every time you hover over a word,a tool-tip box displays what number the word is in the sentence?</p>
</article>
您也可以对 css :before
和 data
属性执行相同的操作:
(function()
{
let count = 0
document.querySelectorAll('article p').forEach(paragraph=>
{
let wordsArray = paragraph.textContent.trim().split(/\s+/) // separate words
.map(w=>`<span data-count="${++count}">${w}</span>`)
paragraph.innerHTML = wordsArray.join(' ')
})
}
)()
article p span {
cursor:crosshair;
position : relative;
}
article p span:hover {
background-color : yellow;
}
article p span:hover:before {
position : absolute;
font-size : .8em;
top : 1.6em;
border-radius : .8em;
content : 'word number is ' attr(data-count);
background-color : darkblue;
color : whitesmoke;
white-space : nowrap;
z-index : 1000;
padding : .4em .6em;
}
<article>
<p>I haven't gotten beyond this point because I don't want to display the array contents.
If I do display the array it displays commas between each item of the array.
What I want is for the sentence to continue looking like it did before it was split,a tool-tip box displays what number the word is in the sentence?</p>
</article>
当您在 JS 中向字符串添加值时,它也会自动将其转换为字符串。数组的默认字符串表示只是由逗号分隔的元素,这就是为什么你会得到你所得到的。为了使每个都不同,您可能需要映射数组,其语法如下:
[1,2,3].map((n) => 2*n) // gives [2,4,6]
如果映射数组,则可以格式化它以在每个单词周围添加 HTML 标记,例如:
text_array.map((word) => "<span>" + word + "</span>").join(" ")
要让它们中的每一个都有一个单独的鼠标悬停事件,您可以将其直接放入您创建的元素中,如下所示:
text_array.map((word,i) =>
"<span onmouseover='console.log(" + i + ")'>" + word + "</span>"
).join(" ")
或者,您可能希望使用 document.createElement
以更加面向对象的方式创建元素。然后您可以使用他们的 addEventListener
方法向它们添加侦听器,并且您的代码将更易于阅读。特别是对于工具提示,您最好只遵循明确关注如何制作它们的教程。 Javascript 为您提供了一个非常干净的 API 来修改 html 和 css,因此如果您可以对其进行硬编码,那么就可以通过编程方式进行操作。
作为旁注,您问题中的代码应该不起作用,因为您从未在循环中定义过glossTxt。另一方面,js 中的大写方案是小写的驼峰式,所以 display_list 应该是 displayList。
,您可以通过类名访问它们,或者如果您想控制每个单词,您可以通过为每个单词添加序列号来实现,然后您可以使用鼠标悬停或点击等任何事件所以
for (i=0; i<sentences.length; i++){
var sent = sentences[i].glossHand;
var text_array = glossTxt.split(" ");
display_list += "<li id='"+i+"' class='text_sent'>" + text_array + "</li>";}