【问题标题】:Abstracting the adding of click events to elements selected by class using jQuery使用jQuery抽象将单击事件添加到由类选择的元素
【发布时间】:2014-05-12 02:51:46
【问题描述】:

我正在慢慢熟悉 jQuery,并开始想要抽象我的代码。我在尝试在页面加载时定义点击事件时遇到了问题。

在下面的代码中,我尝试使用 'block' 类遍历每个 div,并通过按类选择它们来将事件添加到它的一些子元素:

<script language="javascript" type="text/javascript">
$(document).ready(function (){

$('HTML').addClass('JS'); // if JS enabled, hide answers

 $(".block").each(function() { 
  problem = $(this).children('.problem');
  button = $(this).children('.showButton');

  problem.data('currentState', 'off');

  button.click(function() {
   if ((problem.data('currentState')) == 'off'){
    button.children('.btn').html('Hide');
    problem.data('currentState', 'on');
    problem.fadeIn('slow');
   } else if ((problem.data('currentState')) == 'on'){
    button.children('.btn').html('Solve');
    problem.data('currentState', 'off');
    problem.fadeOut('fast');
   }
   return false;

  });
 });
});
</script>

<style media="all" type="text/css">
.JS div.problem{display:none;}
</style>


<div class="block">
    <div class="showButton">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem">
      <p>Answer 1</p>
    </div>
</div>

<div class="block">
    <div class="showButton">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem">
      <p>Answer 2</p>
    </div>
</div>

不幸的是,只有最后一个 div 按钮才有效。该事件不是“本地化”的(如果这是正确的词?),即该事件仅适用于每个方法中的最后一个 $(".block")。

所以我不得不费力地为每个元素添加 id 并一一定义我的点击事件。肯定有更好的办法!谁能告诉我我做错了什么?以及如何摆脱对这些 ID 的需求(我希望它可以在动态生成的页面上工作,我可能不知道有多少“块”......)

<script language="javascript" type="text/javascript">
$(document).ready(function (){

$('HTML').addClass('JS'); // if JS enabled, hide answers

 // Preferred version DOESN'T' WORK  
 // So have to add ids to each element and laboriously set-up each one in turn...

 $('#problem1').data('currentState', 'off');

 $('#showButton1').click(function() {
  if (($('#problem1').data('currentState')) == 'off'){
   $('#showButton1 > a').html('Hide');
   $('#problem1').data('currentState', 'on');
     $('#problem1').fadeIn('slow');
  } else if (($('#problem1').data('currentState')) == 'on'){
   $('#showButton1 > a').html('Solve');
   $('#problem1').data('currentState', 'off');
     $('#problem1').fadeOut('fast');
  }
  return false;

 });


 $('#problem2').data('currentState', 'off');

 $('#showButton2').click(function() {
  if (($('#problem2').data('currentState')) == 'off'){
   $('#showButton2 > a').html('Hide');
   $('#problem2').data('currentState', 'on');
     $('#problem2').fadeIn('slow');
  } else if (($('#problem2').data('currentState')) == 'on'){
   $('#showButton2 > a').html('Solve');
   $('#problem2').data('currentState', 'off');
     $('#problem2').fadeOut('fast');
  }
  return false;

 });

});
</script>

<style media="all" type="text/css">
.JS div.problem{display:none;}
</style>



<div class="block">
    <div class="showButton" id="showButton1">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem" id="problem1">
      <p>Answer 1</p>
    </div>
</div>

<div class="block">
    <div class="showButton" id="showButton2">
        <a href="#" title="Show solution" class="btn">Solve</a>
    </div>

    <div class="problem" id="problem2">
      <p>Answer 2</p>
    </div>
</div>

【问题讨论】:

    标签: javascript jquery jquery-selectors


    【解决方案1】:

    已编辑,因为我找到了 HTML :)

    首先:你需要用var关键字声明“按钮”和“问题”。

    接下来,点击处理程序将在目标元素的上下文中调用,因此您不应在其中引用“按钮”,而是引用“$(this)”。

    接下来,您需要想出一种方法来将每个按钮与其对应的“问题”元素相关联。处理程序可以使用 jQuery DOM 遍历例程找到伴随的“问题”:

    button.click(function() {
      var $button = $(this), $problem = $button.closest('div.block').find('.problem');
      if (($problem.data('currentState')) == 'off'){
        $button.children('.btn').html('Hide');
        $problem.data('currentState', 'on');
        $problem.fadeIn('slow');
      } else if (($problem.data('currentState')) == 'on'){
        $button.children('.btn').html('Solve');
        $problem.data('currentState', 'off');
        $problem.fadeOut('fast');
      }
      return false;
    });
    

    现在另一种选择是使用live 机制,它只允许您创建一个处理函数。它与此非常相似,但不是将处理程序绑定到每个“按钮”&lt;div&gt;,您只需设置它并引用选择器:

    $('.button').live('click', function() {
      // as above
    });
    

    【讨论】:

    • 您需要在第一个代码示例中向下滚动才能看到 HTML。
    【解决方案2】:

    对不起,没有足够的声望投票给以上任何有用的东西,他们绝对是!

    答案实际上很简单——正如@patrick 和@Pointy 正确指出的那样,我需要做的就是添加 var 关键字来声明我的两个变量。呵呵!

    我实际上无法让代码建议正常工作,但我的工作正常,因为它已在您的帮助下得到修复。谢谢!

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script language="javascript" type="text/javascript">
        $(document).ready(function (){
    
        $('HTML').addClass('JS'); // if JS enabled, hide answers
    
         $(".block").each(function() { 
          var problem = $(this).children('.problem');
          var button = $(this).children('.showButton');
    
          problem.data('currentState', 'off');
    
          button.click(function() {
           if ((problem.data('currentState')) == 'off'){
            button.children('.btn').html('Hide');
            problem.data('currentState', 'on');
            problem.fadeIn('slow');
           } else if ((problem.data('currentState')) == 'on'){
            button.children('.btn').html('Solve');
            problem.data('currentState', 'off');
            problem.fadeOut('fast');
           }
           return false;
    
          });
         });
        });
        </script>
    
    <style media="all" type="text/css">
    .JS div.problem{display:none;}
    </style>
    
    </head>
    
    <body>
    
    <div class="block">
        <div class="showButton">
            <a href="#" title="Show solution" class="btn">Solve</a>
        </div>
    
        <div class="problem">
          <p>Answer 1</p>
        </div>
    </div>
    
    <div class="block">
        <div class="showButton">
            <a href="#" title="Show solution" class="btn">Solve</a>
        </div>
    
        <div class="problem">
          <p>Answer 2</p>
        </div>
    </div>
    
    <div class="block">
        <div class="showButton">
            <a href="#" title="Show solution" class="btn">Solve</a>
        </div>
    
        <div class="problem">
          <p>Answer 3</p>
        </div>
    </div>
    
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-03
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      相关资源
      最近更新 更多