【问题标题】:jQuery Control many duplicate html elements independently with .on('click')jQuery 使用 .on('click') 独立控制许多重复的 html 元素
【发布时间】:2016-04-17 08:27:50
【问题描述】:

我正在动态创建带有附加 div 的 html div,其作用类似于按钮 (OpenMessageButton)。

这些 div 是消息的模板,并且根据查询填充了不同的信息,但 html 元素本身是相同的,包括它们使用的 html 类。

我想显示一个下拉抽屉效果来阅读消息,但我在尝试触发此效果时遇到问题,因为它会触发所有消息而不是我单击按钮的特定消息

我已经搜索过这个问题,我找到的最接近的是: jQuery $(".class").click(); - multiple elements, click event once

div 代码

    <?php
          while($row = mysql_fetch_assoc($myMessages))
          {
          ?>

    <!-- First Div to be clicked -->
    <div class="OpenMessageButton">Click to Open/Close</div>

    <!-- Div to be shown when OpenMessageButton is clicked --> 
    <div class="panel panel-default messageContent" style="display:none;">
      <div class="panel-body">
        <h4 class="card-title">Message: </h4>
        <p class="card-text">Text.</p>
        <div class="OpenMessageButton">Open</div>
      </div>

    </div>

    <!-- Second Div to be clicked -->
    <div class="OpenMessageButton">Click to Open/Close</div>

    <!-- Div to be shown when OpenMessageButton is clicked -->
    <div class="panel panel-default messageContent" style="display:none;">
      <div class="panel-body">
        <h4 class="card-title">Message: </h4>
        <p class="card-text">Text.</p>
        <div class="OpenMessageButton">Open</div>
      </div>

    </div>

    <!-- Third Div to be clicked -->
    <div class="OpenMessageButton">Click to Open/Close</div>

    <!-- Div to be shown when OpenMessageButton is clicked -->
    <div class="panel panel-default messageContent" style="display:none;">
      <div class="panel-body">
        <h4 class="card-title">Message: </h4>
        <p class="card-text">Text.</p>
        <div class="OpenMessageButton">Open</div>
      </div>

</div>

我用来触发的jQuery如下:

$('.OpenMessageButton').on('click',function(){
      var link = $(this);      
      $('.panel.panel-default.messageContent').slideToggle('fast', function(){
        if ($(this).is(':visible')){
          link.text('Close');                    
        }else{
          link.text('Open');                    
        }
      });           
  });

按钮的标识符是 OpenMessageButton,当单击任何一个按钮时触发它,但 jQuery 会触发所有不需要的 div。我想找出一种方法,当单击按钮时,只显示与该顶部 div 相关的 div。

见小提琴https://jsfiddle.net/rasa56j8/

-- 更新-- (我正在努力让建议的答案发挥作用,所以我想我会发布整页以确保完整性)

<?php
require 'core/database/db_connect.php'; //DB Connection
require 'get_inbox_messages.php'; //Retrieves inbox msgs from db
require 'getprofile.php'; //Get Profile
?>

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-   scale=1">

        <title>BlackBook Profile</title>

        <!-- Bootstrap core CSS -->
        <link href="css/bootstrap.min.css" rel="stylesheet">
        <!-- Bootstrap theme -->
        <link href="css/bootstrap-theme.min.css" rel="stylesheet">
        <!-- Custom styles for this template -->
        <link href="css/signin.css" rel="stylesheet">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
      </head>

      <body role="document">

        <!-- Fixed navbar -->
        <nav class="navbar navbar-inverse navbar-fixed-top">
          <div class="container">
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand image" href="profile.php" ><img src="Graphics/topLogo3.png" alt="BookLove"></a>
              <a class="navbar-brand" href="#">LoveBook</a>
            </div>
           <div id="navbar" class="navbar-collapse collapse">
              <ul class="nav navbar-nav navbar-right">
                <li ><a href="profile.php">Profile</a></li>

                <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Messages<span class="caret"></span></a>
                <ul class="dropdown-menu">
                <li><a href="message_inbox.php">Inbox</a></li>
                <li><a href="sent_messages.php">Sent Messages</a></li>            
                </ul>
                </li>

                <li role="presentation"><a href="matched_users_output.php">Matches 
                <?php 
                $result = mysql_fetch_array($NewMatchesResult);

                if ($result[0][0] != 0) {
                  echo '<span class=badge>';
                  echo $result[0][0];    
                  echo '</span>';
                }                                                        
                ?>
                </a></li>
                <li ><a href="browse.php">Browse</a></li>

                <li class="dropdown">
                  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Options <span class="caret"></span></a>
                  <ul class="dropdown-menu">
                    <li><a href="changeprofilepic.html">Change Profile Pic </a></li>
                    <li><a href="payment.html">Payment Details</a></li>
                    <li><a href="populate_questions.php">Update Interests</a></li>
                    <li role="separator" class="divider"></li>
                    <li class="dropdown-header"></li>
                    <li><a href="cancel.html">Cancel Account</a></li>
                    <li><a href="signin.html">Logout</a></li>
                  </ul>
                </li>
              </ul>
            </div><!--/.nav-collapse -->
          </div>
        </nav>

        <div class="container theme-showcase" role="main">

          <div class="page-header" >
            <h1>
            <?php  $username = mysql_fetch_assoc($usernameResult);
            echo $username['username']. '\'s';?> Inbox</h1>                            
          </div>


          <?php
          while($row = mysql_fetch_assoc($myMessages))
          {      
            $subject = $row['subject'];
            $content = $row['content'];
            $recipientID = $row['recipient_id'];
            ?>

            <!-- Message Div -->
          <div class="row">
          <div class="col-md-12"><div class="card card-block messages">      
          <h4 class="card-title"><em>Subject: <?php echo $subject; ?></em></h4>
          <h4 class="card-title">From:      
          <?php
          echo $row['member_id'];       
          $from = mysql_query("SELECT username FROM members WHERE member_id = '$recipientID'");
          while($row = mysql_fetch_assoc($from)) {          
              echo $row['username']; }
          ?></h4>
          <!-- <p class="card-text">MESSAGE CONTENT.</p> -->
          <div class="OpenMessageButton">Open</div>
          <div class="ReplyMessageButton">Reply</div>
          <div class="MarkAsReadButton">Mark as Read</div>
          <div class="DeleteMessageButton">Delete</div>  
        </div>
        </div>
        </div>
        <!-- Opened Message Div  -->
        <div class="panel panel-default messageContent">
      <div class="panel-body">
        <h4 class="card-title">Message: </h4>
        <p class="card-text"><?php echo $content; ?>.</p>
      </div>
    </div>
      <?php
          }
        ?>

      <script>

      $('.OpenMessageButton').on('click',function(){
          var link = $(this);      
          $('.messageContent').slideToggle('fast', function(){
            if ($(this).is(':visible')){
              link.text('Close');                    
            }else{
              link.text('Open');                    
            }
          });           
      });


      //   $('.OpenMessageButton').on('click',function(){
      //     var link = $(this);      
      //     $('.panel').slideToggle('fast', function(){
      //       if ($(this).is(':visible')){
      //         link.text('Close');                    
      //       }else{
      //         link.text('Open');                    
      //       }
      //     });           
      // });
      </script>


        <!-- Bootstrap core JavaScript
        ================================================== -->
        <!-- Placed at the end of the document so the pages load faster -->
        <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> -->
        <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
        <script src="js/bootstrap.min.js"></script>
        <script src="js/docs.min.js"></script>
      </body>
    </html>

【问题讨论】:

  • 为了完整起见,我将发布主要代码块,由于某种原因,到目前为止我无法获得建议的答案

标签: jquery


【解决方案1】:

这行是问题所在:

  $('.panel.panel-default.messageContent') ....

你在这里匹配所有按摩。您必须找到一种仅匹配属于单击按钮的消息的方法。

其中一种解决方案可能是用额外的容器包装每个按钮+消息,例如:

<div class="MessageContainer"> <!--added this container -->
    <!-- First Div to be clicked -->
    <div class="OpenMessageButton">Click to Open/Close</div>

    <!-- Div to be shown when OpenMessageButton is clicked --> 
    <div class="panel panel-default messageContent" style="display:none;">
      <div class="panel-body">
        <h4 class="card-title">Message: </h4>
        <p class="card-text">Text.</p>
        <div class="OpenMessageButton">Open</div>
      </div>

    </div>
</div>

然后你可以改变这个:

$('.panel.panel-default.messageContent')

到这里:

link.closest('.MessageContainer').find('.panel.panel-default.messageContent')

这是工作示例

https://jsfiddle.net/rasa56j8/2/

【讨论】:

  • 我的 OpenMessageButton 在一个 div 中,我将在上面显示评论,但这似乎对我不起作用
  • 我的示例中的 div.MessageContainer 应该包装 both 按钮和消息以使其工作。
  • 你说得对,我不知道为什么它在我第一次尝试时对我不起作用,但现在可以了。非常感谢!
【解决方案2】:

您应该改用 jQuery 方法 next(),因为它只选择下一个元素(在您的情况下是类为“panel”的 div)而不是所有面板。

所以把你的js代码改成:

$('.OpenMessageButton').click(function(){
      var link = $(this);      
      link.next().slideToggle('fast', function(){
        if ($(this).is(':visible')){
          link.text('Close');                    
        }else{
          link.text('Open');                    
        }
      });           
  });

【讨论】:

  • 我不确定 .next() 是否适合我,因为目标 div 在技术上不是列表中的下一个 div,但可能是 .OpenMessageButton 之后的第三或第四个 div
【解决方案3】:

由于您尝试切换 jQuery 事件源,您应该更改:

$('.panel.panel-default.messageContent').slideToggle('fast', function(){

到

$( this ).slideToggle('fast', function(){

jQuery doc 说:

当 jQuery 调用处理程序时,this 关键字是对 传递事件的元素;对于直接绑定的事件 这是附加事件并用于委托的元素 events 这是一个元素匹配选择器。 (请注意,这可能不是 如果事件从后代冒泡,则等于 event.target element.) 从元素创建一个 jQuery 对象,以便它可以 与 jQuery 方法一起使用,使用 $( this )。

我对如何实现该功能采取了不同的观点:

$('.OpenMessageButton').on('click', function() {
  var link = $(this);

  // If sub-text is already visible
  if (link.next().is(':visible')) {
    // Reset the link text
    link.text('Open');
    // Hide the sub-text
    link.next().hide();
  } else {
    // Reset the link text
    link.text('Close');
    // Show the sub-text
    link.next().slideToggle('fast', function(){ } );
  }
});

【讨论】:

  • 我觉得这也应该起作用,因为它是有道理的,但在我的示例中却没有。我更新了上面的代码只是为了提供更多的上下文。
【解决方案4】:

您需要以某种方式将每个打开/关闭链接与其各自的 div 相关联。这是一种方法,使用 div id 和 jQuery 的 .data()

<!-- Third Div to be clicked -->
<div class="OpenMessageButton" data-control="message3">Click to Open/Close</div>

<!-- Div to be shown when OpenMessageButton is clicked -->
<div id="message3" class="panel panel-default messageContent" style="display:none;">
  <div class="panel-body">
    <h4 class="card-title">Message: </h4>
    <p class="card-text">Text.</p>
    <div class="OpenMessageButton">Open</div>
  </div>

然后在JS中:

$(document.body).on('click', '.OpenMessageButton', function(){
      var link = $(this);  
      var div_id = $(this).data('control');      
      $(div_id).slideToggle('fast', function(){
        if ($(this).is(':visible')){
          link.text('Close');                    
        }else{
          link.text('Open');                    
        }
      });           
  });

【讨论】:

  • 这是否仍然存在与我之前遇到的问题类似的问题,因为 data-control="message3" 对于所有动态创建的 div 基本相同?
  • 对,所以无论您是在 php while 循环中创建 div 还是动态创建 div,它们都需要一个唯一的 id 才能工作。另外,我将重写监听器来处理动态添加的 div。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
  • 2014-03-14
  • 1970-01-01
相关资源
最近更新 更多