在网页上,如何使元素受到点击(并跳转到链接),但不受到点击?

问题描述 投票:0回答:1

这其实可以是一个高级话题,或者说不定可以用简单的方法解决。

问题:

  1. 假设有 5 或 25 张小图片,用户可以将鼠标移到(鼠标悬停)查看图片的稍微放大版本(或者在某些情况下,图片实际上会变成一个小视频并播放)几秒钟作为预览)。

  2. 目前,用户无法单击该图像或视频来跳转到链接。下面有一个单独的按钮,上面写着“Go”以跳转到链接。

  3. 程序管理员希望点击图片能让用户跳转到链接。

  4. 因此,为了解决这个问题,我可以使用

    <a href="... ">. </a>
    来包裹这个元素来实现这一点。

  5. 然而,在iPad或iPhone,或任何“触摸屏”PC上,用户可能点击它,立即跳转到该链接,而没有机会看到放大的图片或正在播放的小视频

  6. 所以 PM(程序经理)不喜欢这种行为,并说:“好吧,只有在桌面情况下才跳转到该链接。”所以PM的意思是,当是iPad或iPhone或触摸屏时,当用户点击那个小图片时,不要跳转到链接。

  7. PM只是希望在PC上“点击”图片可以让用户跳转到链接,但在iPad或iPhone或触摸屏上却会产生不良效果,如上面(5)所述:点击也会跳跃,没有悬停效果看放大的图片或微小的视频预览。

那么问题来了,如何才能让点击跳转只在桌面上起作用,而在iPad、iPhone或触摸屏上不起作用呢?

经过一番思考,我最初的尝试是:当有

mouseenter
事件时,向元素添加一个类,称为
mouse-entered
(并在
mouseleave
事件上,删除该类)。那么,如果元素没有这个
mouse-entered
类,则调用
ev.preventDefault()
来防止跳转到链接。

代码是:


      elContent.addEventListener("mouseenter", (ev) => {
        console.log("MOUSE_ENTER", ev, new Date());
        elContent.classList.add("mouse-entered");
      });

      elContent.addEventListener("mouseleave", (ev) => {
        console.log("MOUSE_LEAVE", ev, new Date());
        elContent.classList.remove("mouse-entered");
      });

      elContent.addEventListener("click", (ev) => {
        console.log("CLICK", ev, new Date(), performance.now(), Date.now());

        if (!elContent.classList.contains("mouse-entered")) {
          ev.preventDefault();
        }
      });

你可以在codesandbox上尝试一下:

代码已开启: https://codesandbox.io/p/devbox/blissful-hugle-xszzzh

页面位于: https://xszzzh-5000.csb.app/

因此,如果你将其视为网页,或者如果你使用 Google Chrome 的开发工具来模拟 iPhone 或 iPad,如果你点击该块,你仍然会跳转到该链接(我将其设置为跳转到 google.com)。

原因是:在点击时触发

click
事件(在 iPhone 上)之前,也会触发
mousenenter
事件。 因此实际上添加了
mouse-entered
类(并且没有触发
mouseleave
事件来删除该类),因此它不起作用。

我的第二个想法是:如果我加一个类呢,比如

tapped
,有
ev.preventDefault()
类的时候用
tapped
,这样我就知道是iPhone还是iPad,那就不用跳到了链接。 但是,有些计算机带有触摸屏,所以如果用户点击它,然后使用触控板将鼠标移到上面并单击它,它仍然应该跳转到该链接,所以它也不起作用。

事件的顺序是:

  1. touchstart
  2. touchend
  3. mouseneter
  4. click

所以我不能说,“如果有

touchend
,让它返回到非触摸屏外壳”,因为在 iPhone 或 iPad 上,它也会触发
touchend
事件,就像触摸一样屏幕电脑。

所以我的第三次尝试非常hacky。我只是用

dataset
设置
touchend
时间,这样如果
click
事件在 touchend 时间后小于 0.3 秒或 0.5 秒,那么就不会跳转到链接。目标是说:如果这次点击实际上是点击,那么就不要跳转到链接。 它有效,但确实很hacky。

dataset
就像,它会添加一个
data-some-name
作为元素的属性)

代码如下:

      const elContent = document.querySelector("#content");
      console.log("elContent", elContent);

      elContent.addEventListener("click", (ev) => {
        console.log("CLICK", ev, new Date(), performance.now(), Date.now());

        if (
          elContent.dataset.touchEndedAt &&
          Date.now() - +elContent.dataset.touchEndedAt < 500
        ) {
          ev.preventDefault();
        }
      });

      elContent.addEventListener("touchend", (ev) => {
        console.log("TOUCH_END", ev, new Date(), performance.now(), Date.now());
        elContent.dataset.touchEndedAt = Date.now();
      });

你可以尝试一下。代码是https://codesandbox.io/p/sandbox/jovial-dirac-rm8h7w 该应用程序是https://rm8h7w.csb.app/

因此,如果您使用 Google Chrome 像在 PC 或 Mac 上一样查看页面,则单击该块,它将跳转到链接 (google.com),但如果您使用开发工具模拟 iPhone 并点击它,那么它就不会跳了。

但它非常hacky。 有更好的办法吗?

javascript iphone ipad dom-events
1个回答
0
投票

你把事情搞得太复杂了。只需检测用户是否使用触摸设备并据此调整行为即可。

这是我的建议:

  1. 检测设备类型:使用JavaScript判断用户是否是 在触摸设备上。

  2. 条件行为:如果是触摸设备,则阻止第一次点击时的默认链接行为,并允许用户看到放大的图像或视频。如果是桌面,让点击立即触发链接。

const elContent = document.querySelector("#content");   
let isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
elContent.addEventListener("click", (ev) => {
  if (isTouchDevice) {
    ev.preventDefault();
    // Handle showing the enlarged image or video on touch devices here.
  } else {
    // Allow the link to work normally on non-touch devices.
    window.location.href = ev.currentTarget.dataset.link;
  }
});

© www.soinside.com 2019 - 2024. All rights reserved.