首次触摸时为preventDefault(),但仍允许滚动/触摸移动

时间:2019-07-11 13:42:52

标签: javascript jquery html css

我的网站上有一些元素,其中只有当您将鼠标悬停在元素上时才会显示内容。一个完美的例子是Instagram feed网格。我正在使用它们的API从Instagram帐户中提取最后8张图像,并使用flexbox在网格中显示它们。当您用鼠标在其中一张图像上:hover上移动时,一个半透明的黑色叠加层会淡入,其中包含Instagram帖子的标题。

在桌面上,您可以单击图像/悬停的字幕叠加层上的任意位置,因为它们都包裹在<a>元素中,因此可以将您带到Instagram网站上的帖子。这在台式机上可以完美运行,但在触摸屏上则不能。

因为您无法在触摸设备上:hover,所以我决定在touchstart事件上实现一些JavaScript,该事件使用e.preventDefault()来阻止点击Instagram时单击链接图片,然后将CSS opacity: 1visibility: visible添加到overlay元素(当您在元素上:hover时会发生这种情况)。由于叠加元素在制作为visible之后位于图像的“顶部”,因此可以单击链接,因为仅在图像上监听了touchstart事件。

这一切都很好,这意味着我可以点击图像上的一次,该图像会淡出叠加层,并且不会带我进入Instagram上的图像,然后我可以点击{ 1}}在叠加层上花费时间,将我带到Instagram上的图片。

问题

因为我在second事件中使用了e.preventDefault(),所以如果您触摸图像然后开始拖动手指进行滚动,则该页面根本不会滚动,从而导致糟糕的用户体验

所以...

如何仅在单个touchstart事件上preventDefault(),或者如何防止在元素的第一次触摸时单击链接,而在第二次单击时却不单击链接,同时仍然允许用户滚动/拖动页面?

我的代码的简化版本

touch
function toggleHoveredStateOn(e) {
    
    e.preventDefault();
    
    let hoverElem = this.querySelector('.js-touch-hover');
    
    // remove all 'visible' classes from other "hovered" items first
    document.querySelectorAll('.js-touch-trigger').forEach(touchTrigger => {
        
        let hoverElem = touchTrigger.querySelector('.js-touch-hover');
        
        Object.assign(hoverElem.style, {
            visibility: 'hidden',
            opacity: '0',
            pointerEvents: 'none'
        });
        
    });
    
    // add visible to the touched element's hover element
    Object.assign(hoverElem.style, {
        visibility: 'visible',
        opacity: '1',
        pointerEvents: 'all'
    });
    
}

function initMobileTouchFunctionality() {
    
    let touchTriggers = [...document.querySelectorAll('.js-touch-trigger')];
    
    touchTriggers.forEach(touchTrigger => {
        touchTrigger.addEventListener('touchstart', toggleHoveredStateOn, false);
        touchTrigger.querySelector('.js-touch-hover').addEventListener('touchstart', function(e) {
            e.stopPropagation();
        }, false);
    });
    
}

initMobileTouchFunctionality();
.flex-grid__item {
  position: relative;
  height: 263px;
  border: 1px solid #FFF;

  &:hover {

    .flex-grid--social__hover {
      opacity: 1;
      visibility: visible;
      pointer-events: auto;
    }
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

.flex-grid--social__hover {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  text-align: center;
  background-color: rgba(0, 0, 0, 0.8);
  padding: 20px;
  transition: opacity 0.2s ease-in-out;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
  pointer-events: none;
  cursor: pointer;
}

1 个答案:

答案 0 :(得分:0)

您可以决定是否使用-include linux/kconfig.h e.preventDefault来查看用户是否点击了图像或叠加层。 您可以在https://developer.mozilla.org/en-US/docs/Web/API/Event/target

了解更多信息