Javascript 点击、点击和悬停

标签 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>

最佳答案

我想出了下面的方法,它工作得很好——在触摸/笔和鼠标之间切换时。

实际上,对于鼠标导航,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>

如果有人有任何补充/建议,跟进。这让我头疼了好几天!

关于Javascript 点击、点击和悬停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38265641/

相关文章:

JavaScript 代码冲突

javascript - 使用jquery加载外部文件,然后引用它

javascript - 在 UWP 项目中使用 Typescript 或 ES6 javascript

javascript - JS、jQuery 冲突..有帮助吗?

jquery - 如何使用 scroll fixed witin parent..我想要滚动但是 nexbutton 和 prevbuton 是固定移动的..如何使用 jquery

javascript - 使用 npm 终端的 npm 脚本奇怪行为

javascript - _json 函数的作用是什么?它来自哪个库?

javascript - pickadate() 函数不适用于克隆元素

javascript - 将鼠标悬停在 div 内的图像更改为另一个图像

jquery - 动画时取消设置 css 参数