【问题标题】:Change the text of clicked element with 'this' in JavaScript / jQuery callback在 JavaScript / jQuery 回调中使用“this”更改单击元素的文本
【发布时间】:2015-01-24 19:13:18
【问题描述】:

任何人都可以解释回调中的this

示例。 网页。

<html>
<head>
  <script src="https://code.jquery.com/jquery-1.11.2.js"></script>
  <script src="myApp.js"></script>
</head>
<body>
  <button type="button" id="btn001">Show</button><br/>
  <p id="p001" class="article">Some contents...</p>
  <button type="button" id="btn002">Show</button><br/>
  <p id="p002" class="article">Other content...</p>
  <!-- more paragraphs -->
</body>
</html>

首先,我为每个段落编写了一个函数。 myApp.js的源代码。

$(document).ready(function () {
  // hide all articles at the begining
  $(".article").hide();
  // button 1 hides/shows first paragraph
  $("#btn001").click(function () {
    if ($(this).html() === "Show") {
      $(this).html("Hide");
    } else {
      $(this).html("Show");
    }
    $("#p001").toggle();
  });
  // button 2 hides/shows second paragraph
  $("#btn002").click(function () {
    if ($(this).html() === "Show") {
      $(this).html("Hide");
    } else {
      $(this).html("Show");
    }
    $("#p002").toggle();
  });
  // repeat code for next paragraphs
});

我对代码重复很生气,所以我尝试排除代码来运行。

function handleHideShow(par) {
  if ($(this).html() === "Show") {
    $(this).html("Hide");
  } else {
    $(this).html("Show");
  }
  par.toggle();
}

$(document).ready(function () {
  // hide all articles at the begining
  $(".article").hide();
  // button 1 hides/shows first paragraph
  $("#btn001").click(function () {
    handleHideShow($("#p001"));
  });
  // button 2 hides/shows second paragraph
  $("#btn002").click(function () {
    handleHideShow($("#p002"));
  });
});

切换段落有效,但button 上的文本没有改变。谁能解释this 发生了什么?

  • 为什么在第一个示例中$(this) 选择了被点击的元素?
  • 第二个示例中的$(this) 是什么?

以及如何解决这个问题?

【问题讨论】:

    标签: javascript jquery button click


    【解决方案1】:

    您的第一个函数是事件处理程序。使用事件处理程序$(this) 自动引用被单击、更改、悬停等的元素。jQuery 为您创建$(this),虽然您无法明确看到它传递到函数中,但它可用于所有代码在点击处理程序的回调中。

    您的第二个函数是一个简单的函数,不是事件处理程序,因此 jQuery 不会为您创建 $(this) 引用

    在您的代码中,您可以从您的事件处理程序(如handleHideShow($(this),$("#p002"));)传递$(this),并在您的函数(如function handleHideShow(btn, par))中引用它。然后,在handleHideShow 内部,btn 将引用与单击处理程序中引用的$(this) 相同的元素(请参阅下面的第二个 sn-p)。

    但是,我会通过提供按钮和段落类而不是 id 并这样做来简化代码:

    $(document).ready(function () {
      $('.article').hide();
      $('.myBtn').click(function(){
        $(this).html( $(this).html() == 'Show' ? 'Hide' :'Show' );
        $(this).nextAll('.article').first().toggle();
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
        <html>
        <head>
          <script src="https://code.jquery.com/jquery-1.11.2.js"></script>
          <script src="myApp.js"></script>
        </head>
        <body>
          <button type="button" class="myBtn">Show</button><br/>
          <p class="article">Some contents...</p>
          
          <button type="button" class="myBtn">Show</button><br/>
          <p class="article">Other content...</p>
          <!-- more paragraphs -->
        </body>
        </html>

    现在,有人可能会争辩说这效率较低,因为 jQuery 必须搜索更多元素才能找到段落,但我相信它更健壮,因为您可以添加任意数量的按钮和段落,而无需担心所有顺序ids。老实说,您必须有一个非常大的网页才能查看任何性能问题。

    $(document).ready(function () {
      // hide all articles at the begining
      $(".article").hide();
      // button 1 hides/shows first paragraph
      $("#btn001").click(function () {
        handleHideShow($(this),$("#p001"));
      });
      // button 2 hides/shows second paragraph
      $("#btn002").click(function () {
        handleHideShow($(this),$("#p002"));
      });
    });
    
    function handleHideShow(btn, par) {
      if (btn.html() === "Show") {
        btn.html("Hide");
      } else {
        btn.html("Show");
      }
      par.toggle();
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <html>
    <head>
      <script src="https://code.jquery.com/jquery-1.11.2.js"></script>
      <script src="myApp.js"></script>
    </head>
    <body>
      <button type="button" id="btn001">Show</button><br/>
      <p id="p001" class="article">Some contents...</p>
      
      <button type="button" id="btn002">Show</button><br/>
      <p id="p002" class="article">Other content...</p>
      <!-- more paragraphs -->
    </body>
    </html>

    【讨论】:

    • 两种解决方案都可以正常工作。为每个按钮使用单个类并选择下一个 .article 很棒。并且可以删除br 或放置两个brs 仍然可以正常工作。传递参考更适合我遇到的this 问题。我想它们都对特定情况有用。
    • 你介意告诉 this 问题 jQuery-specific 或 JavaScript-specific。
    • @user2793410 看看这里的 cmets 和函数:jsfiddle.net/417w0df4/2 这应该让您了解如何使用 this
    【解决方案2】:

    需要在函数中传递按钮的对象:

    试试这个:

    function handleHideShow(par,that) {
      if ($(that).html() === "Show") {
        $(that).html("Hide");
      } else {
        $(that).html("Show");
      }
      par.toggle();
    }
    
    $(document).ready(function () {
      // hide all articles at the begining
      $(".article").hide();
      // button 1 hides/shows first paragraph
      $("#btn001").click(function () {
        handleHideShow($("#p001"),this);
      });
      // button 2 hides/shows second paragraph
      $("#btn002").click(function () {
        handleHideShow($("#p002"),this);
      });
    });
    

    或者你也试试这个:

    $(document).ready(function () {
      // hide all articles at the begining
      $(".article").hide();
      // button 1 hides/shows first paragraph
      $("button[id^='btn']").click(function () {
        if ($(this).html() === "Show") {
          $(this).html("Hide");
        } else {
          $(this).html("Show");
        }
        $(this).next().toggle();
      });
    });
    

    上面的代码是最优的,你可以添加任意数量的按钮。

    【讨论】:

    • @CodeLover 第二个解决方案不起作用。 [ 应该不平衡吗?
    • @user2793410 对不起,我忘了添加] 检查更新。
    • @CodeLღver 不会 $(this).next().toggle(); 切换
      标签而不是段落?
    • @DelightedD0D 是对的。在我的文档中,按钮之后的下一个元素是&lt;br&gt;。不得不将其更改为$(this).next().next().toggle();
    【解决方案3】:

    函数在没有特殊上下文的情况下被调用,this 不是元素。
    改为引用函数

    $("#btn001").click(handleHideShow);
    $("#btn002").click(handleHideShow);
    
    function handleHideShow() {
        $(this).html(function (_, html) {
            return html === "Show" ? "Hide" : "Show";
        });
    
        $('#' + this.id.replace('btn', 'p')).toggle();
    }
    

    FIDDLE

    【讨论】:

    • 现在您正在切换按钮而不是段落的可见性。
    • @adaneo 1. 我错过了您的 css(在 FIDDLE 中看到它)以及相反的按钮。 2. 脚本应放在正文之后,否则 2 个作业必须放在 $( document ).ready() 中。
    • @user2793410 - 只要元素可用,脚本的放置位置由您决定。如果您需要切换另一种方式,只需交换文本的顺序,更新答案即可,我只是假设元素将被隐藏,因为您使用的按钮文本是“显示”
    • @adaneo 3. 只有当对应的pbutton 具有相同后缀的ids 时,该脚本才能正常工作。例如 p001 - btn001。当然,在我的情况下,这是 100% 正确的假设。
    • @adaneo 4. 你介意解释一下$(this).html(function (_, html) { 行吗? 5. event 参数会发生什么?
    猜你喜欢
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多