Javascript点击,点击和悬停

时间:2016-07-08 11:36:03

标签: javascript jquery

我想要实现的目标是:

在桌面上:1)悬停以显示叠加层2)单击以激活

触摸:1)点击以显示叠加2)再次点按以激活

到目前为止,我想出的是以下内容。但是,当使用触摸设备时,它会同时触发touchend事件和click事件,这会导致不必要地触发叠加点击事件。如果有的话,最好的方法是什么?

$(".container > .item").on("mouseenter mouseleave", function(e) {
  $(this).toggleClass("hover");
  console.log("hover: " + e.type);
});

$(".container > .item > .overlay").on("mouseup touchend", function(e) {
  console.log("click: " + e.type);
})
.item {
  width: 200px;
  height: 200px;
  background: red;
  display: inline-block;
  
  position: relative;
}
  
.item.hover > .overlay {
  display: block;
}

.overlay {
  display: none;
  position: aboslute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="item">
    <div class="overlay">
    </div>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

我想出了下面的内容,效果非常好 - 在触摸/笔和鼠标之间切换时。

实际上,对于鼠标导航,mouseover'唤醒'元素,并准备好听众,然后由监听器处理click。对于触摸导航,首先点击'唤醒'元素,第二个点击由听众处理。

var hoverCapture = (function() {
  var TOUCH_STATE = {
    'initial': 0,
    'over': 1,
    'click': 2
  };
  
  var eventTargetDefault = '.hover-layer';
  
  function hoverCapture(selectorScope, eventTarget) {
    var eventTarget = typeof eventTarget !== 'undefined' ?  eventTarget : eventTargetDefault;
    
    var $eventTarget = $(selectorScope).find(eventTarget);
    
    var touchState = TOUCH_STATE.initial;
    var previousEventType = '';
    
    $eventTarget.on('mouseenter', function(e) {
      $(this).addClass("hover");
      
      previousEventType = e.type;
    });

    $eventTarget.on('mouseleave', function(e) {
      $(this).removeClass("hover");
      // Order of events is:
      //
      // outside -> .image
      //  touchend, mousenter
      //
      // .image -> .image
      //  touchend, mouseleave, mouseenter
      //
      // .image -> outside
      //  mouseleave
      //
      // When tapping out, we don't receive a touchend
      //  event, since the touchend happens outside of
      //  our scoped listeners
      if (previousEventType === 'touchend') {
        touchState = TOUCH_STATE.over;
      } else {
        touchState = TOUCH_STATE.initial;
      }

      previousEventType = e.type;
    });

    $eventTarget.on('touchend', function(e) {
      if (touchState === TOUCH_STATE.initial) {
        touchState = TOUCH_STATE.over;
      } else {
        touchState = TOUCH_STATE.click;
      }

      previousEventType = e.type;
    });


    $eventTarget.each(function() {
      this.addEventListener("click", function(e){
        if (touchState === TOUCH_STATE.over) {
          e.stopPropagation();
        }

        previousEventType = e.type;
      }, true);
    });
  }
  
  return hoverCapture;
}());


hoverCapture("#gallery1", ".image");
hoverCapture("#gallery2", ".image");

$(".test").on("click", function(e) {
  alert("Ouch!");
});
.gallery {
  margin: 5px;
}

.image {
  width: 100px;
  height: 100px;
  background: grey;
  margin: 0 -4px -4px 0;
  
  display: inline-block;
}

.image .overlay {
  height: 100%;
  width: 100%;
  background: red;
  display: none;
  position: relative;
}

.image.hover .overlay {
  display: block;
}

.test {
  width: 25%;
  height: 25%;
  position: absolute;
  right: 0;
  background: purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="gallery" id="gallery1">
  <div class="image">
    <div class="overlay">
      <div class="test"></div>
    </div>
  </div>

  <div class="image">
    <div class="overlay">
    </div>
  </div>
  
  <div class="image">
    <div class="overlay">
    </div>
  </div>

  <div class="image">
    <div class="overlay">
    </div>
  </div>
</div>


<div class="gallery" id="gallery2">
  <div class="image">
    <div class="overlay">
      <div class="test">
      </div>
    </div>
  </div>

  <div class="image">
    <div class="overlay">
    </div>
  </div>
  
  <div class="image">
    <div class="overlay">
      <div class="test">
      </div>
    </div>
  </div>

  <div class="image">
    <div class="overlay">
    </div>
  </div>
</div>

如果有人有任何补充/建议进行跟进..这几天让我头疼!