【问题标题】:onClick event on element on Mobile device hover state is still applied移动设备悬停状态上的元素上的 onClick 事件仍然适用
【发布时间】:2019-09-16 00:28:57
【问题描述】:

除非我一直在寻找错误的东西,否则我似乎无法在 React 网上找到任何遇到同样问题的人?

我有一个带有onClick 事件的按钮(锚标记)。当onClick 事件被触发时,它会调用loadMore() 函数,该函数会进行API 调用并更新一些状态。

但是在移动设备上(不是桌面上的移动分辨率!)当我单击按钮时,onClick 事件会起作用并返回预期的结果,然而它应用了 hover 按钮上的状态。对于按钮悬停状态,我应用了背景颜色

悬停状态会一直保持,直到我点击屏幕上的其他任何位置。所以背景颜色会一直存在,直到我点击离开。

现在,这并不完全可取。为什么会发生这种情况,我是如何预防的?

这是我的Button 组件

const Button = props => {
  const buttonDisabledClass = props.disabled ? "Button--disabled " : "";
  const hiddenClass = props.hidden ? "Button--hidden " : "";
  const modifierClass = props.modifier ? props.modifier : "";

  return (
    <>
      <a
        onClick={!props.disabled ? props.onClick : undefined}
        className={
          "Button " + buttonDisabledClass + hiddenClass + modifierClass
        }
      >
        {props.children}
        {props.buttonText ? (
          <span
            className={`Button-text ${
              props.buttonMobileText ? "Button-desktopText" : ""
            }`}
          >
            {props.buttonText}
          </span>
        ) : null}
        {props.buttonMobileText ? (
          <span className="Button-mobileText">{props.buttonMobileText}</span>
        ) : null}
      </a>
    </>
  );
};

这里是父组件

父组件导入Button组件,并具有发出API请求的功能(这里以模拟为例)

function App() {
  const [number, setNumber] = useState(0);

  /*simulate http request*/
  const ttl = 500;
  const loadMore = () => {
    const timeout = setTimeout(() => {
      setNumber(number + 1);
    }, ttl);
    return () => {
      clearTimeout(timeout);
    };
  };

  return (
    <div className="App">
      {number}
      <Button
        key={"loadMoreBtn"}
        modifier="Button--loadMore Button--Inline"
        onClick={() => loadMore()}
      >
        Load More
      </Button>
    </div>
  );
}

那么,我怎样才能使点击移动设备时不会注册悬停,但仍然让悬停在桌面设备上像当前一样工作?

如果您想自己测试一下,我有一个CODESANDBOX

这是一个link,供您在移动设备上进行测试。

该按钮默认为橙色,悬停时为灰色。在移动设备上,当您单击时会发生这种情况...

任何帮助将不胜感激!

【问题讨论】:

  • 听起来更像是焦点状态而不是悬停状态..
  • @Keith 打开开发工具,可以看到.Button:hover被应用了,不是焦点
  • 这是大多数移动浏览器的正常行为。看看this questionthis article
  • @Wendelin 可能是正常行为,但在这种情况下并不理想,我正在寻找一种方法来防止这种情况发生。由于配色方案,我们需要使用,灰色按钮使它看起来被禁用,这会使最终用户感到困惑
  • 我建议您禁用移动设备的悬停状态,无论如何在移动设备上并没有多大意义。

标签: javascript css reactjs hover mousehover


【解决方案1】:

您可以使用 CSS 中的媒体查询覆盖移动设备上的悬停效果:

@media only screen and (min-resolution: 117dpi) and (max-resolution: 119dpi), only screen and (min-resolution: 131dpi) and (max-resolution: 133dpi), only screen and (min-resolution: 145dpi) and (max-resolution: 154dpi), only screen and (min-resolution: 162dpi) and (max-resolution: 164dpi), only screen and (min-resolution: 169dpi) {
  .Button:hover {
    background-color: #ee4900 !important;
  }
}

或者

@media (hover: none) {
  .Button:hover {
    background-color: #ee4900 !important;
  }
}

【讨论】:

  • 这仍然会出现在大型平板电脑上,尤其是在横向上。然后有些人会拥有与此宽度相同的小分辨率显示器,我希望他们仍然能够悬停。
  • @mcclosa 您可以将(max-width: 480px) 替换为(hover: none) 以仅针对触摸设备(例如,没有悬停的设备)。见:css-tricks.com/touch-devices-not-judged-size
  • 我更新了我的答案以使用我发现的一些 dpi 技巧,但@elveti 也提到了另一种选择。
  • @elveti 我实际上曾尝试(hover: hover) 仅在桌面设备上应用悬停但在 IE 上不起作用(不幸的是,我们有 18% 的用户正在使用 IE,因此必须至少支持 IE9 ) 但使用 (hover: none) 并应用默认背景颜色实际上是有效的。谢谢!
  • @mcclosa 很有趣,就在一个小时前,另一位用户遇到了同样的问题,他找到了解决方案 stackoverflow.com/a/55867559/1498053 因此,对于将来的参考,您可以使用 @media (hover: hover), (-ms-high-contrast:none) 至少支持到 IE11
猜你喜欢
  • 1970-01-01
  • 2016-03-01
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2011-08-05
  • 1970-01-01
相关资源
最近更新 更多