如何为句子的每个单词获取不同的悬停事件?

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 :beforedata 属性执行相同操作:

(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>