【问题标题】:Locking the body scroll, blocks target element scrolling锁定正文滚动,阻止目标元素滚动
【发布时间】:2021-04-09 00:51:45
【问题描述】:

我正在使用以下库来锁定页面主体的滚动,并且只允许在我的模式打开时滚动。

https://www.npmjs.com/package/body-scroll-lock

我的模态AddItemModal 是一个门户,所以在index.html 文件中我有这个。

<body>
  <div id="root"></div>
  <div id="add-item-modal"></div>
</body>

NavigationIcons 组件(打开模式的地方)

const NavigationIcons = (props) => {
  let targetElement = document.getElementById("add-item-modal");

  useEffect(() => {
    ...
    return () => clearAllBodyScrollLocks();
  }, []);

  const renderAddItemModal = () => {
    if (props.addItem) {
      disableBodyScroll(targetElement);
      return <AddItemModal />;
    }
  };

  return (
    <div className="main-4" onClick={() => props.openAddItemModal()}>
      {renderAddItemModal()}
    </div>
  );
}

AddItemModalHeader 组件(模态关闭的地方)

const AddItemModalHeader = (props) => {
  let targetElement = document.getElementById("add-item-modal");

  return (
    <div className="modal-header">
      add item
      <div className="close" onClick={(e) => {
        props.handleModalClose(e);
        enableBodyScroll(targetElement);
      }}>
       close
      </div>
    </div>
  )
}

在文档中写道targetElement 必须是我要显示的模式。但是由于应用程序是在root div 中呈现的,并且模态显示在add-item-modal 中,所以它不应该是root,而是将提供的函数应用于它,例如enableBodyScrolldisableBodyScrollclearAllBodyScrollLocks。我确实尝试了rootadd-item-modal,在这两种情况下,当我从我的 iOS 设备进行测试时,滚动都无法在模式上工作。

那里提供的示例并没有让我清楚这一点。有人可以解释我在这里做错了什么吗?

更新

其他可能在 iOS 设备上遇到此问题的人请参阅以下来自 Github 线程的解释清楚的答案 https://github.com/ionic-team/ionic-v1/issues/155#issuecomment-411110252

【问题讨论】:

    标签: javascript reactjs scroll


    【解决方案1】:

    body-scroll-lock 的一些已知问题是

    • 不适用于 Android 网页视图
    • 不能在带有鼠标滚轮的 PC 上工作
    • 在 iOS 上不起作用,如果您触摸某处而不是 targetElement
    • 必须通过 targetElement,即使没有必要

    输入tua-body-scroll-lock


    请知道我与tua-body-scroll-lock 没有任何联系。


    tua-body-scroll-lockbody-scroll-lock 提供的功能相同。喜欢

    • disableBodyScroll lock 的别名
    • enableBodyScroll unlock 的别名
    • clearAllBodyScrollLocks clearBodyLocks 的别名

    我使用tua-body-scroll-lock 制作了一个example 的小提琴

    你的代码应该是这样的

    import {lock, unlock, clearBodyLocks} from 'tua-body-scroll-lock';
    
    const NavigationIcons = (props) => {
      ...
      useEffect(() => {
        ...
        return () => clearBodyLocks();
      }, []);
    
      const renderAddItemModal = () => {
        if (props.addItem) {
          lock(targetElement);
          return <AddItemModal />;
        }
      };
    
      ...
    }
    
    const AddItemModalHeader = (props) => {
      return (
        <div className="modal-header">
          add item
          <div className="close" onClick={(e) => {
            props.handleModalClose(e);
            unlock(targetElement);
          }}>
           close
          </div>
        </div>
      )
    }
    

    【讨论】:

    • 我正在查看您的示例,想知道您从哪里获取 clearBodyLocks 变量。我认为我的问题是我没有针对正确的节点元素,我想更好地了解您做了什么来了解如何使其工作。
    • clearBodyLocks 函数和你的clearAllBodyScrollLocks 有相同的用途,我将它与lockunlock 函数一起导入了代码的顶部
    • 对不起,我的意思是 bodyScrollLock 来自示例
    • 哦。我在 HTML 中导入了带有script 标记的tua-body-scroll-lock。所以bodyScrollLock 就像拥有lockunlockclearBodyLocks 函数的对象
    • 我编辑了 jsFiddle 以注销 bodyScrollLock 从我编辑的答案中查看新链接
    【解决方案2】:

    如果您查看他们的源代码,disableBodyScroll 在内部所做的唯一事情就是在设备为 IOS 的情况下附加 ontouchstartontouchmove 事件并阻止该事件(通过调用e.preventDefault()) 有条件地如果 targetElement 接近可滚动边界。

    所以如果我理解正确的话,targetElement 必须是一个可滚动的元素,否则它永远不会绕过那些边界检查,它会阻止滚动。

    在您的情况下,我认为 add-item-modal 不是可滚动元素,因此它不起作用。尝试在模式中使用targetElement 的任何可滚动元素。

    【讨论】:

      猜你喜欢
      • 2012-12-30
      • 1970-01-01
      • 2019-08-23
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 2021-08-15
      相关资源
      最近更新 更多