【问题标题】:Property 'msHidden' does not exist on type 'Document'“文档”类型上不存在属性“msHidden”
【发布时间】:2021-05-29 09:09:12
【问题描述】:

我在使用 tab visibility 时遇到此错误。其中“文档”类型上不存在“msHidden”和“webkitHidden”

const TabVisibilityComponent = () => {
let hidden = null;
let visibilityChange = '';
const [action, setAction] = useState('show');
if (typeof document.hidden !== 'undefined') {
  hidden = 'hidden';
  visibilityChange = 'visibilitychange';
} else if (typeof document.msHidden !== 'undefined') {
  hidden = 'msHidden';
  visibilityChange = 'msvisibilitychange';
} else if (typeof document.webkitHidden !== 'undefined') {
  hidden = 'webkitHidden';
  visibilityChange = 'webkitvisibilitychange';
}

const handleVisibilityChange = () => {
  if (document.hidden) {
    setAction('hide');
  } else {
    setAction('show');
  }
};


useEffect(() => {
  document.addEventListener('visibilitychange', handleVisibilityChange, false);
  window.addEventListener(
    'focus',
    function() {
      setAction('show');
    },
    false,
  );
  window.addEventListener('blur', function() {
    setAction('hide');
  }, false);
}, [visibilityChange]);
return <p></p>;
};

export default TabVisibilityComponent;

我尝试在 'lib.dom.d.ts' 文件的 Document 界面中添加 'readonly msHidden: boolean',因为 hidden 工作正常,而且它是在该文件中声明为只读布尔值,因此对 msHidden 和 webkitHidden 进行了相同的尝试,但它不起作用。我见过很多人使用这个代码,但不知道我的错误是什么。如果有人对此有解决方案会非常高兴!

【问题讨论】:

    标签: javascript html reactjs typescript interface


    【解决方案1】:

    代码直接来自MDN docs,所以您说得对,代码本身没问题。问题是:


    1. lib.dom 定义确实包含特定于浏览器的属性。

    解决此问题的一种方法是将文档作为参数传递给将这些属性定义为可选的函数。

    const hiddenPropName = (document: Document & {msHidden?: boolean; webkitHidden?: boolean}) => {
      if (typeof document.hidden !== "undefined" ) {
        return "hidden";
      } else if (typeof document.msHidden !== "undefined") {
        return "msHidden";
      } else if (typeof document.webkitHidden !== "undefined") {
        return "webkitHidden";
      }
      // not sure how to handle when none exist
    }
    

    但就 Typescript 而言,document.hidden 始终存在。

    看起来caniuse 上的前缀和非前缀支持的数字几乎没有任何区别。所以你可以放弃msHiddenwebkitHidden


    1. 您忽略了您设置的hiddenvisibilityChange 变量。

    示例中代码的第一部分只是将变量hiddenvisibilityChange 设置为属性的名称,以便它们以后可以访问正确的属性。该示例使用document[hidden],其中hidden 是一个变量,但您使用的document.hidden 始终获取属性“hidden”而不是“msHidden”或“webkitHidden”。

    他们还在document.addEventListener 中为事件使用变量。

    如果您想支持前缀,那么您需要使用变量属性和事件名称。如果没有,只需删除整个第一个代码块。


    1. 您没有正确调整代码以适应 React。

    您要确保您的 useEffect 挂钩具有正确的依赖关系,并且理想情况下您应该在您的 useEffect 中使用清理函数来删除卸载时的事件侦听器。

    这里最困难的部分是确保您没有创建任何陈旧的闭包,这些闭包会在评估时使用过时的 document 值。如果这是正确的,我实际上不确定不玩它:

    const TabVisibilityComponent = () => {
      const [action, setAction] = useState("show");
    
      useEffect(() => {
        const hide = () => setAction("hide");
    
        const show = () => setAction("show");
    
        const handleVisibilityChange = () => {
          document.hidden ? hide() : show();
        };
    
        document.addEventListener(
          "visibilitychange",
          handleVisibilityChange,
          false
        );
        window.addEventListener("focus", show, false);
        window.addEventListener("blur", hide, false);
    
        return () => {
          document.removeEventListener("visibilitychange", handleVisibilityChange);
          window.removeEventListener("focus", show);
          window.removeEventListener("blur", hide);
        };
      }, [setAction]);
    
      return <p></p>;
    };
    

    【讨论】:

      猜你喜欢
      • 2019-09-07
      • 2020-03-06
      • 2020-08-13
      • 2019-05-07
      • 2021-05-04
      • 2017-07-05
      • 2021-01-09
      • 2021-02-12
      • 2021-07-10
      相关资源
      最近更新 更多