【问题标题】:Assign .on('click') in a for loop to each array element individually在 for 循环中将 .on('click') 分别分配给每个数组元素
【发布时间】:2021-05-28 07:34:01
【问题描述】:

是否有可能为数组的每个元素单独切换文本()?

现在,当单击时,每个元素的值都会同时更改,我想在单击时一个一个地检查它们。

$(function() {
    var jap = ["kau", "matsu", "shiru"];
    var eng = ["to buy", "to wait", "to know"];
    var tds = [$('#td1'), $('#td2'), $('#td3')]
    
    for (i = 0; i < tds.length; i++) {
        $(tds[i]).on('click', function(){
            for(i = 0; i < tds.length; i++) {
            $(tds[i]).toggleText(jap[i], eng[i]);
            }
        });
     }
});

理想情况下,我想在每次单击每个数组元素时更改表格单元格内的文本。

--编辑:

这是带有表格的 HTML:

<table>
    <tbody id="tb">
         <tr>
            <td>Godan Verbs</td>
            <td>V2</td>
            <td>Ichidan Verbs</td>
            <td>V2</td>
            <td>Irregular Verbs</td>
            <td>V2</td>
          </tr>
          <tr>
             <td>kau</td>
             <td>kai-</td>
             <td>taberu</td>
             <td>tabe-</td>
             <td>kuru</td>
             <td>ki-</td>
           <tr>
              <td>matsu</td>
              <td>machi-</td>
              <td>miru</td>
              <td>mi-</td>
              <td>suru</td>
              <td>shi-</td>
          </tr>
          <tr>
              <td>shiru</td>
              <td>shiri-</td>
              <td>oshieru</td>
              <td>oshie-</td>
          </tr>
          <tr>
              <td>kaku</td>
              <td>kaki-</td>
              <td>neru</td>
              <td>ne-</td>
           </tr>
           <tr>
               <td>oyogu</td>
               <td>oyogi-</td>
               <td>kangaeru</td>
               <td>kangae-</td>
            </tr>
            <tr>
                <td>hanasu</td>
                <td>hanashi-</td>
                <td>okiru</td>
                <td>oki-</td>
             </tr>
             <tr>
                 <td>shinu</td>
                 <td>shini-</td>
                 <td>sakeru</td>
                 <td>sake-</td>
              </tr>
              <tr>
                  <td>yomu</td>
                  <td>yomi-</td>
                  <td>kotaeru</td>
                  <td>kotae-</td>
               </tr>
               <tr>
                   <td>asobu</td>
                   <td>asobi-</td>
                   <td>iru</td>
                   <td>i-</td>
                </tr>
        </tbody>                
 </table>

这是我想显示的单词的其他含义:

const jap2en = {"kau":"to buy", "matsu":"to wait", "shiru":"to know", "kaku":"to write", "oyogu":"to swim", "hanasu":"to talk", "shinu":"to die", "yomu":"to read", "asobu":"to play", "taberu": "to eat", "miru": "to look", "oshieru": "to teach", "neru": "to sleep", "kangaeru": "to think", "okiru": "to get up", "sakeru": "to avoid", "kotaeru": "to answer", "iru": "to be/exist", "kuru": "to come", "suru": "to do"};

我还在 td 中添加了 id,它们应该为每个单独的 td 显示如下含义:

<td id="td1">kau</td>
<td>kai-</td>
<td id="td2">taberu</td>
// and so on

把js代码改成这样:

const $tds = $("#tb td[id]");
$("#tb").on("click", "td[id]", function() { ... }

然而,正如我在评论中提到的,一个片段改变了表格的结构,使 tds 出现在错误的位置。这个片段具体来说:

$tds.each(function(i) {
    $(this).text(jpArr[i])
    $(this).data("lang","ja")
 })

如果删除,代码可以工作,但单元格需要单击两次才能显示含义。

【问题讨论】:

  • 您可能想看看jQuery Learning Center,因为您的设置过于复杂。如果你采用 jQuery 方式,你的问题也将得到解决。

标签: jquery loops foreach


【解决方案1】:

你有 jQuery - 使用它的力量

不建议在 JavaScript 中循环添加 eventListeners,jQuery 与否。

const jap2en = {"kau":"to buy", "matsu":"to wait", "shiru":"to know", "kaku":"to write", "oyogu":"to swim", "hanasu":"to talk", "shinu":"to die", "yomu":"to read", "asobu":"to play", "taberu": "to eat", "miru": "to look", "oshieru": "to teach", "neru": "to sleep", "kangaeru": "to think", "okiru": "to get up", "sakeru": "to avoid", "kotaeru": "to answer", "iru": "to be/exist", "kuru": "to come", "suru": "to do"};
const jpArr = Object.keys(jap2en); // just the Japanese keys
const en2jap = Object.fromEntries(Object.entries(jap2en).map(a => a.reverse())); // makes a reverse lookup

$(function() {
  const $tds = $("#tb td");
  $("#tb").on("click", "td", function() { // delegation
    const text = $(this).text();
    const lang = $(this).data("lang");
    const langArr = lang === "ja" ? jap2en : en2jap;
    const langText = langArr[text];
//    console.log(text,lang,langText,langArr[text])
    if (langText) {
      $(this).text(langText);
      $(this).data("lang",lang === "ja" ? "en" :"ja" );
    }  
  });
  $tds.each(function(i) {
    $(this).data("lang","ja")
  }) 
});
td {
  border: 1px solid black;
  padding: 3px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <thead>
        <tr>
          <th>Godan Verbs</th>
          <th>V2</th>
          <th>Ichidan Verbs</th>
          <th>V2</th>
          <th>Irregular Verbs</th>
          <th>V2</th>
        </tr>
      </thead>
      <tbody id="tb">
        <tr>
          <td>kau</td>
          <td>kai-</td>
          <td>taberu</td>
          <td>tabe-</td>
          <td>kuru</td>
          <td>ki-</td>
        </tr>
        <tr>
          <td>matsu</td>
          <td>machi-</td>
          <td>miru</td>
          <td>mi-</td>
          <td>suru</td>
          <td>shi-</td>
        </tr>
        <tr>
          <td>shiru</td>
          <td>shiri-</td>
          <td>oshieru</td>
          <td>oshie-</td>
        </tr>
        <tr>
          <td>kaku</td>
          <td>kaki-</td>
          <td>neru</td>
          <td>ne-</td>
        </tr>
        <tr>
          <td>oyogu</td>
          <td>oyogi-</td>
          <td>kangaeru</td>
          <td>kangae-</td>
        </tr>
        <tr>
          <td>hanasu</td>
          <td>hanashi-</td>
          <td>okiru</td>
          <td>oki-</td>
        </tr>
        <tr>
          <td>shinu</td>
          <td>shini-</td>
          <td>sakeru</td>
          <td>sake-</td>
        </tr>
        <tr>
          <td>yomu</td>
          <td>yomi-</td>
          <td>kotaeru</td>
          <td>kotae-</td>
        </tr>
        <tr>
          <td>asobu</td>
          <td>asobi-</td>
          <td>iru</td>
          <td>i-</td>
        </tr>
      </tbody>
    </table>

更简单的版本

const jap = ["kau", "matsu", "shiru"];
const eng = ["to buy", "to wait", "to know"];

$.fn.extend({ // extending jQuery to have a toggleText
  toggleText: function(a, b) {
    return this.text(this.text() == b ? a : b)
  }
});

$(function() {
  $("#tb").on("click", "tr", function() { // delegation
    const idx = $(this).index();
    $(this).find("td").eq(0).toggleText(jap[idx], eng[idx]);
  });
});
td {
  border: 1px solid black;
  padding: 3px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>Godan Verbs</th>
      <th>V2</th>
      <th>Ichidan Verbs</th>
      <th>V2</th>
      <th>Irregular Verbs</th>
      <th>V2</th>
    </tr>
  </thead>
  <tbody id="tb">
    <tr>
      <td>kau</td>
      <td>kai-</td>
      <td>taberu</td>
      <td>tabe-</td>
      <td>kuru</td>
      <td>ki-</td>
    </tr>
    <tr>
      <td>matsu</td>
      <td>machi-</td>
      <td>miru</td>
      <td>mi-</td>
      <td>suru</td>
      <td>shi-</td>
    </tr>
    <tr>
      <td>shiru</td>
      <td>shiri-</td>
      <td>oshieru</td>
      <td>oshie-</td>
    </tr>
    <tr>
      <td>kaku</td>
      <td>kaki-</td>
      <td>neru</td>
      <td>ne-</td>
    </tr>
    <tr>
      <td>oyogu</td>
      <td>oyogi-</td>
      <td>kangaeru</td>
      <td>kangae-</td>
    </tr>
    <tr>
      <td>hanasu</td>
      <td>hanashi-</td>
      <td>okiru</td>
      <td>oki-</td>
    </tr>
    <tr>
      <td>shinu</td>
      <td>shini-</td>
      <td>sakeru</td>
      <td>sake-</td>
    </tr>
    <tr>
      <td>yomu</td>
      <td>yomi-</td>
      <td>kotaeru</td>
      <td>kotae-</td>
    </tr>
    <tr>
      <td>asobu</td>
      <td>asobi-</td>
      <td>iru</td>
      <td>i-</td>
    </tr>
  </tbody>
</table>

【讨论】:

  • 太好了。感谢您的时间和帮助。
  • 你可能知道为什么这个片段:` $tds.each(function(i) { $(this).text(jpArr[i]) $(this).data("lang ","ja") }) ` 破坏了表格的结构?当我应用此代码时,tds 都混在一起了。当我删除提到的片段时,它的结构符合预期,但需要单击两次才能显示单词的含义。
  • 我将文本设置为查找表的值,然后将数据属性设置为单元格中的当前语言
  • 循环是设置单元格的值开始,所以我们不必手动填充表格。如果您希望我的代码与您的 html 一起使用,请显示您的 html
  • 让我编辑我最初的问题并包含 html
【解决方案2】:

试试这个

如果您想在每次单击时根据数组索引实现相应的文本进行切换,那么我相信您必须摆脱您使用的内部 for 循环。

你也只需要保存没有 $ 和 () 的 id

它是这样的

$(function() {
    var jap = ["kau", "matsu", "shiru"];
    var eng = ["to buy", "to wait", "to know"];
    var tds = ['#td1', '#td2', '#td3'];
    
    for (i = 0; i < tds.length; i++) {
        $(tds[i]).on('click', function(){                
            $(this).toggleText(jap[i], eng[i]);                
        });
     }
});

编辑

我只是让它像这样工作(虽然我猜是循环事件监听器):

$(function() {
  var jap = ["kau", "matsu", "shiru"];
  var eng = ["to buy", "to wait", "to know"];
  var tds = ['#td1', '#td2', '#td3'];

  $("td").each(function(index, value) {
    $(this).on('click', function() {
      var textToToggle = $(this).text() == jap[index] ? eng[index] : jap[index];
      $(this).text(textToToggle);
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td id="td1">kau</td>
    <td id="td2">matsu</td>
    <td id="td3">shiru</td>
  </tr>
</table>

【讨论】:

  • 请测试您的代码。单击edit,然后单击[&lt;&gt;] 并创建一个stacksn-p。你会看到你缺少对 i 的闭包,而 i 现在是一个全局变量
  • 不建议循环添加事件监听器——尤其是现在在普通 JS 中不像在 jQuery 中那样容易
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
相关资源
最近更新 更多