如何为句子的每个单词获取不同的悬停事件?
How can I get a different hover event for each word of a sentence?
我对 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>";
}
我还没有超出这一点,因为我不想显示数组内容。如果我确实显示数组,它会在数组的每个项目之间显示逗号。我想要的是让句子继续看起来像拆分之前的样子,但每个单词都可以单独访问。
这可能吗?
如果是这样,我怎样才能让每个单词都有一个单独的鼠标悬停事件?例如,我怎样才能做到每次将鼠标悬停在一个词上时,工具提示框都会显示该词在句子中的编号?
编辑:为了清楚起见,必须修复代码。
当您在 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.
您可以通过 class 名称访问它们,或者如果您想要控制每个单词,您可以通过为每个单词添加序列号来实现,然后您可以在类似鼠标上使用任何事件或点击或任何类似的东西
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>";}
也许这会帮助你前进
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,
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>
我对 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>";
}
我还没有超出这一点,因为我不想显示数组内容。如果我确实显示数组,它会在数组的每个项目之间显示逗号。我想要的是让句子继续看起来像拆分之前的样子,但每个单词都可以单独访问。
这可能吗?
如果是这样,我怎样才能让每个单词都有一个单独的鼠标悬停事件?例如,我怎样才能做到每次将鼠标悬停在一个词上时,工具提示框都会显示该词在句子中的编号?
编辑:为了清楚起见,必须修复代码。
当您在 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.
您可以通过 class 名称访问它们,或者如果您想要控制每个单词,您可以通过为每个单词添加序列号来实现,然后您可以在类似鼠标上使用任何事件或点击或任何类似的东西
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>";}
也许这会帮助你前进
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,
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>