【问题标题】:How to wrap multiple dynamic eventListeners into one?如何将多个动态事件监听器包装成一个?
【发布时间】:2018-06-25 19:29:55
【问题描述】:

刚开始学js,需要一点帮助:我有如下功能:

   //SET CHAT BEHAVIOR
   function chatSettings() {

        console.log('ChatSettings called')         

        function BtnAndScrollBar(texteditor) {     
            console.log('BTNAndScrollBar called');    
            const sendBtn = $('.cl.active').find('.sendBtn');
            const attachBtn = $('.cl.active').find('.attachBtn');
            console.log(sendBtn)          
        }

        function sendAndDeleteMessage(send) {
            console.log(send);
        }   

        var sendBtn = $('.cl.active').find('.sendBtn');
        sendBtn.mousedown(function () {      
            sendAndDeleteMessage(this);
        });               

        var textEditor1 = $('.cl.active').find('.chatTextarea');                  
        textEditor1.on('focus change mousedown mouseout keyup mouseup', function (){
            console.log(this);
            BtnAndScrollBar(this)
        });
   }       

      $('document').ready(function () {
          console.log('hello');
          $('.tabs').tabs();
          chatSettings();        
      });

我准备了一个js.fiddle - 正如您在单击文本区域时从console.log 中看到的那样,即使.cl.active 与相应的TAB 一起切换,事件监听器也总是监听#cl1

如果.cl 处于活动状态,则文本区域中的事件只是相关的。我的目标是将所有三个 eventListener 包装成一个并将事件应用于活动流中的文本区域,但我尝试的所有方法都出错了......有人可以帮忙吗? #Dontrepeatyourself#DRY

【问题讨论】:

  • ID 在给定页面中必须是唯一的。 stackoverflow.com/questions/9454645/… chatTextarea 正在重复
  • 与其单独选择每个,为什么不使用共享的cl 类全部选择它们?
  • 谢谢。这是一个复制粘贴错误...您的建议会产生问题 - 我尝试使用 $('.cl.active'),但它确实适用于第一个元素,并且在第二个元素激活后,它没有工作。可能是因为它只是在加载后启动。
  • 您只希望该功能发生在活动元素上吗?问题中没有表达这一点。

标签: javascript jquery dry jquery-wrap


【解决方案1】:
$(".chatTextarea").on(
'focus change mousedown mouseout keyup mouseup', 
function (this) {
//this.id can contain the unique id
greatFunction(this);
}); 

这将使用 this 关键字找到的唯一 id 单独绑定事件,并将所有事件侦听器包装到一个函数中,但是当您希望使用相同的功能处理每个事件时,这会更好

如果这有帮助,请告诉我。

和平

【讨论】:

  • 请 Nixen85 看看我处理过的解决方案 jsfiddle.net/9oyoh67x/123 如果这对您有帮助,请告诉我。
  • 这很有帮助:$('.cl').find('.chatTextarea').each(function(){ $(this).on('focus change mousedown mouseout keyup mouseup', function (){ console.log($(this).val()); BtnAndScrollBar(this) });
【解决方案2】:
$(".cl textarea").on('focus change mousedown mouseout keyup mouseup', function () {
    greatFunction(this)
});   

多田!

附:在 window.onload 中定义 greatFunction 是否有原因?

【讨论】:

  • 将 $('document') 替换为 $(document)
【解决方案3】:

尝试使用 $(document).ready 函数在页面加载时加载代码。 还可以使用 $('textarea #cl1').on 来获取带有 #cl1 或您要使用的任何 id 的 textarea,然后在使用 .on 后调用该函数。 希望这可以帮助! 让我知道它是否有效!

     $(document).ready(function () {

  function greatFunction(elem) {     
//do stuff
}    
      $('textarea').on('focus change mousedown mouseout keyup mouseup', function () {
            greatFunction(this)
        });  

}

【讨论】:

  • 我已经更新了我的答案,使用 textarea 选择页面上的所有文本区域,只有 1 个 jquery 函数
【解决方案4】:

首先,我将onload 更改为与 jQuery 绑定,因此您的所有逻辑都在执行 jQuery 绑定,而不是在 jQuery 和 vanilla javascript 之间来回交换。此外,执行实际绑定会删除内联绑定。

接下来,绑定已被压缩为单个委托事件侦听器。由于您在 cmets 中回避在移动或添加活动元素后它不适用于活动元素,这反映了您正在处理动态元素。委托事件侦听器是处理此类事情的一种方式。

委托事件侦听器绑定在将更改或创建的元素的父元素上。然后它等待一个事件发生在它的一个孩子身上。当它收到它正在侦听的事件时,它会检查它源自的元素是否与侦听器的子选择器(第二个参数)匹配。如果匹配,它将处理子元素的事件。

最后,我添加了一些按钮来交换活动类,因此您可以在 sn-p 中看到事件处理程序将开始为您激活的任何元素工作,无论它以何种方式开始。

$(window).on('load', function () {
  function greatFunction (elem) {
    console.log(elem.value);
  }
  
  $(document.body).on(
      'focus change mousedown mouseout keyup mouseup',
      '.cl.active .chatTextarea',
      function () {
          greatFunction(this);
      }
  );
  
  $('.makeActive').on('click', function () {
    $('.active').removeClass('active');
    $(this).closest('div').addClass('active');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cl1" class="cl active"><textarea class="chatTextarea">aa</textarea><button class="makeActive">Make Active</button></div>
<div id="cl2" class="cl"><textarea class="chatTextarea">bb</textarea><button class="makeActive">Make Active</button></div>
<div id="cl3" class="cl"><textarea class="chatTextarea">cc</textarea><button class="makeActive">Make Active</button></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多