admin管理员组

文章数量:1391934

I am using the following library for locking scrolling of the body of page and only allow scrolling on my modal if it is open.

My modal AddItemModal is a portal so inside index.html file I have this.

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

NavigationIcons ponent (where modal is opened)

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 ponent (where modal is closed)

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>
  )
}

In documentation it is written that targetElement must be the the modal that I want to display. But since the application is rendered inside root div and modal displayed in add-item-modal, shouldn't it be the root instead and apply to it the provided functions such as enableBodyScroll, disableBodyScroll, clearAllBodyScrollLocks. I did try with both root and add-item-modal and in both cases the scrolling does not work on the modal when I test from my iOS device.

The example provided there does not make this clear to me. Could someone explain what am I doing wrong here?

UPDATE

Others that might have this issue on iOS devices please see the following well-explained answer from Github thread

I am using the following library for locking scrolling of the body of page and only allow scrolling on my modal if it is open.

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

My modal AddItemModal is a portal so inside index.html file I have this.

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

NavigationIcons ponent (where modal is opened)

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 ponent (where modal is closed)

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>
  )
}

In documentation it is written that targetElement must be the the modal that I want to display. But since the application is rendered inside root div and modal displayed in add-item-modal, shouldn't it be the root instead and apply to it the provided functions such as enableBodyScroll, disableBodyScroll, clearAllBodyScrollLocks. I did try with both root and add-item-modal and in both cases the scrolling does not work on the modal when I test from my iOS device.

The example provided there does not make this clear to me. Could someone explain what am I doing wrong here?

UPDATE

Others that might have this issue on iOS devices please see the following well-explained answer from Github thread https://github./ionic-team/ionic-v1/issues/155#issuement-411110252

Share Improve this question edited Apr 12, 2021 at 20:38 user12051965 asked Apr 9, 2021 at 0:51 user12051965user12051965 15712 silver badges39 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

If you look at their source code, the only thing that disableBodyScroll does internally is attaching ontouchstart and ontouchmove events if the device is IOS and just preventing the event (by calling e.preventDefault()) conditionally if the targetElement is near to the scrollable boundaries.

So if I understood it correctly, the targetElement must be a scrollable element otherwise it'll never bypass those boundary check and it'll block the scroll.

In your case, I think add-item-modal is not a scrollable element thus it's not working. Try with any scrollable element with in the modal as targetElement.

Some know issues with body-scroll-lock are

  • Doesn't work on Android webview
  • Doesn't work on PC with mouse wheel
  • Doesn't work on iOS, if you touch somewhere instead of targetElement
  • Must pass targetElement, even if it's not necessary

Enter tua-body-scroll-lock


Please know I don't have any connection with tua-body-scroll-lock.


tua-body-scroll-lock has the same functions that body-scroll-lock provides. Like

  • disableBodyScroll alias for lock
  • enableBodyScroll alias for unlock
  • clearAllBodyScrollLocks alias for clearBodyLocks

I made a fiddle with an example using tua-body-scroll-lock

Your code should then be like

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>
  )
}

本文标签: javascriptLocking the body scrollblocks target element scrollingStack Overflow