【问题标题】:add multiple event types to an event listener in a function向函数中的事件侦听器添加多种事件类型
【发布时间】:2019-01-10 04:11:47
【问题描述】:

我正在尝试了解如何最好地做到这一点。

我有一个幻灯片,其中有一个 div 来跟踪它所在的幻灯片。

我需要对上一个和下一个箭头的点击次数保持一致,并在桌面和移动设备上拖动。

这个问题与桌面移动设备上的拖动有关。因为 mousedown 不能转换为移动设备,所以我需要弄清楚如何在事件侦听器中使用触摸事件,尽管进行了 3 次尝试和研究,但我还是不明白。

我最初的尝试如下:

function nextSlideHandler(){
            slideCounter = (slideCounter+1)%{$slides_size};
            $('#slide-text').replaceWith({$slide_text});
            $('#slide-top-section').replaceWith({$slide_top_section});
       }

       function previousSlideHandler(){
            slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
            $('#slide-text').replaceWith({$slide_text});
            $('#slide-top-section').replaceWith({$slide_top_section});
       }

var swipeElement = $('.n2-ss-swipe-element')[0];
        var isDown = false;
       var direction = '';
        swipeElement.addEventListener('mousedown, touchend', function(e) {
            isDown = true;
        }, true);

        document.addEventListener('mouseup, touchstart', function(e) {
          isDown = false;
          if(direction == 'left'){
            nextSlideHandler();
            }
           if(direction == 'right'){
              previousSlideHandler();
            }
            direction='';
        }, true);

        document.addEventListener('mousemove, touchmove', function(event) {
           event.preventDefault();
           if (isDown) {
           var deltaX = event.movementX;
           var deltaY = event.movementY;
           if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
           if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
         }
        }, true);

思考过程 - mousedown 等适用于桌面,而触摸事件适用于移动设备,如果其中一种事件类型发生则触发。

但这不起作用。幻灯片计数未更新。

我发现 https://gomakethings.com/listening-to-multiple-events-in-vanilla-js/ 建议使用多个事件侦听器

虽然迂腐和重复,但我尝试拆分为多个事件监听器

function nextSlideHandler(){
            slideCounter = (slideCounter+1)%{$slides_size};
            $('#slide-text').replaceWith({$slide_text});
            $('#slide-top-section').replaceWith({$slide_top_section});
       }

       function previousSlideHandler(){
            slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
            $('#slide-text').replaceWith({$slide_text});
            $('#slide-top-section').replaceWith({$slide_top_section});
       }

   var swipeElement = $('.n2-ss-swipe-element')[0];
    var isDown = false;
   var direction = '';

    swipeElement.addEventListener('mousedown', function(e) {
        isDown = true;
    }, true);

    swipeElement.addEventListener('touchstart', function(e) {
        isDown = true;
    }, true);

    document.addEventListener('mouseup', function(e) {
      isDown = false;
      if(direction == 'left'){
        nextSlideHandler();
        }
       if(direction == 'right'){
          previousSlideHandler();
        }
        direction='';
    }, true);

    document.addEventListener('touchend', function(e) {
      isDown = false;
      if(direction == 'left'){
        nextSlideHandler();
        }
       if(direction == 'right'){
          previousSlideHandler();
        }
        direction='';
    }, true);

    document.addEventListener('mousemove', function(event) {
       event.preventDefault();
       if (isDown) {
       var deltaX = event.movementX;
       var deltaY = event.movementY;
       if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
       if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
     }
    }, true);

    document.addEventListener('touchmove', function(event) {
       event.preventDefault();
       if (isDown) {
       var deltaX = event.movementX;
       var deltaY = event.movementY;
       if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
       if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
     }
    }, true);

这也不行。

我找到了这些答案:

does mousedown /mouseup in jquery work for the ipad?

Does jQuery mouseup event work on touch devices?

Using mousedown event on mobile without jQuery mobile?

到目前为止,通过这项研究,我似乎在使用触摸事件的正确轨道上。

这个答案是最有希望的:Binding multiple events to a listener (without JQuery)? 所以我在这里接受了这个想法并付诸实践:

函数 nextSlideHandler(){ slideCounter = (slideCounter+1)%{$slides_size}; $('#slide-text').replaceWith({$slide_text}); $('#slide-top-section').replaceWith({$slide_top_section}); }

   function previousSlideHandler(){
        slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
        $('#slide-text').replaceWith({$slide_text});
        $('#slide-top-section').replaceWith({$slide_top_section});
   }

   function addListenerMulti(element, eventNames, listener) {
        var events = eventNames.split(' ');
        for (var i=0, iLen=events.length; i<iLen; i++) {
        element.addEventListener(events[i], listener, false);
      }
   }

   $('.entry-content').append({$slide_top_section}).append({$slide_text});

   $('#n2-ss-{$id}-arrow-previous').on('click', $.proxy(function(e){
        e.stopPropagation();
       previousSlideHandler()}, this));

   $('#n2-ss-{$id}-arrow-next').on('click', $.proxy(function(e){
        e.stopPropagation();
       nextSlideHandler()}, this))

   var swipeElement = $('.n2-ss-swipe-element')[0];
    var isDown = false;
   var direction = '';
    swipeElement.addListenerMulti('mousedown touchstart', function(e) {
        isDown = true;
    }, true);

    document.addListenerMulti('mouseup touchend', function(e) {
      isDown = false;
      if(direction == 'left'){
        nextSlideHandler();
        }
       if(direction == 'right'){
          previousSlideHandler();
        }
        direction='';
    }, true);

    document.addListenerMulti('mousemove touchmove', function(event) {
       event.preventDefault();
       if (isDown) {
       var deltaX = event.movementX;
       var deltaY = event.movementY;
       if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
       if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
     }
    }, true);

在此之后,幻灯片计数仍然没有更新。

如何在一个事件监听器中组合多种事件类型?

更新另一个尝试:

   function nextSlideHandler(){
        slideCounter = (slideCounter+1)%{$slides_size};
        $('#slide-text').replaceWith({$slide_text});
        $('#slide-top-section').replaceWith({$slide_top_section});
   }

   function previousSlideHandler(){
        slideCounter = (slideCounter+{$slides_size}-1)%{$slides_size};
        $('#slide-text').replaceWith({$slide_text});
        $('#slide-top-section').replaceWith({$slide_top_section});
   }

   function addListenerMulti(element, eventNames, listener) {
        var events = eventNames.split(' ');
        for (var i=0, iLen=events.length; i<iLen; i++) {
          element.addEventListener(events[i], listener, false);
        }
   }

   $('.entry-content').append({$slide_top_section}).append({$slide_text});

   $('#n2-ss-{$id}-arrow-previous').on('click', $.proxy(function(e){
        e.stopPropagation();
       previousSlideHandler()}, this));

   $('#n2-ss-{$id}-arrow-next').on('click', $.proxy(function(e){
        e.stopPropagation();
       nextSlideHandler()}, this))

   var swipeElement = $('.n2-ss-swipe-element')[0];
   var isDown = false;
   var direction = '';
    addListenerMulti(swipeElement, 'mousedown touchstart', function(e) {
        isDown = true;
    }, true);

    addListenerMulti(swipeElement, 'mouseup touchend', function(e) {
      isDown = false;
      if(direction == 'left'){
        nextSlideHandler();
        }
       if(direction == 'right'){
          previousSlideHandler();
        }
        direction='';
    }, true);

    addListenerMulti(swipeElement, 'mousemove touchmove', function(event) {
       event.preventDefault();
       if (isDown) {
       var deltaX = event.movementX;
       var deltaY = event.movementY;
       if(deltaX>0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'right';
       if(deltaX<0 && Math.abs(deltaX)>Math.abs(deltaY) && Math.abs(deltaX)>=10) direction = 'left';
       console.log(direction);
     }
    }, true);

【问题讨论】:

  • 最后一个解决方案没有出错吗? addListenerMulti(element, eventNames, listener)element 作为其第一个参数。但是你正在通过.addListenerMulti('mouseup touchend',你是不是打算这样做addListenerMulti(document, 'my event'
  • 你能添加HTML吗?那可能吗。对 addListenerMulti 的调用仍然是错误的,你有一个额外的参数true。但这不应该受到伤害。在您传递的函数中添加console.log('in event'); 以测试它是否被触发。然后在您尝试触摸之前在 PC/Mac 上进行测试。

标签: javascript jquery


【解决方案1】:

当我们正确调用元素时,它似乎工作正常。

 const mySampleListener = (event) => {
  console.log(`Event occured: ${event.target.innerHTML}`);
 }
 
 
 function addListenerMulti(element, eventNames, listener) {
      var events = eventNames.split(' ');
      for (var i=0, iLen=events.length; i<iLen; i++) {
      element.addEventListener(events[i], listener, false);
    }
 }
 
 let events = "click keyup";
 let divs = document.querySelectorAll('.track');
 
 divs.forEach(d => {
  addListenerMulti(d, events, mySampleListener);
 })
 
 
 
<div class="track">Div 1</div>
<div  class="track">Div 2</div>
<input type="text"  class="track" />

【讨论】:

  • 好的,但这适用于多个 div,我只有一个。它不起作用,它说swipeElement.addListenerMulti is not a function,但我定义了这个函数,所以我不知道它为什么这么说
  • 不能这样称呼,要叫addListenerMulti(swipeElement, 'click keydown etc', myFunction);
  • 您的函数要求您将element 作为第一个参数传入。我的示例代码只是为了展示您应该如何使用该方法
  • 我实现了您的概念,但仍然无法正常工作,抱歉。我会更新我的答案。
猜你喜欢
  • 2010-11-26
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
相关资源
最近更新 更多