Scroll-triggered closing of modals in Next Js

I have integrated a Modal component into my Next.JS application, and I have implemented a functionality to close the modal when the user scrolls outside of it. However, this effect is also triggering when the user scrolls inside the modal. How can I modify it to only close when scrolled outside but not inside?

function HomeFilterModal({ visible, onClose }) {
  const toggle = useSelector(selectModal);
  const dispatch = useDispatch();

  const handleOnClose = (e) => {
    if (e.target.id === "container") onClose();
  };

  useEffect(() => {
    const handleScroll = () => {
      if (window.scrollY >= 10) {
        onClose();
      }
    };

    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);
  if (!visible) return null;

  return (
    <div
      id="container"
      onClick={handleOnClose}
      className="fixed top-24 bottom-0 left-0 right-0 bg-black bg-opacity-30 backdrop-blur-sm h-screen z-50 hidden sm:flex justify-center "
    >
      <div
        id="nonscroll"
        className="h-[28rem] w-2/3 bg-[#fafaf9] drop-shadow-md rounded-3xl flex flex-col items-center overflow-hidden overflow-y-scroll scrollbar-none snap-y
        "
      >
        <div className="flex items-center justify-between w-full px-4 py-4 border-b">
          <div
            onClick={() => dispatch(setModal(!toggle))}
            className="rounded-full border h-8 w-8 border-gray-600 hover grid place-items-center hover:border-0 hover:drop-shadow-2xl hover:shadow-black"
          >
            <XMarkIcon className="h-4 w-4" />
          </div>
          <p className="text-2xl tracking-wider">Filter</p>

          <p
            onClick={() => dispatch(resetFunc())}
            className="text-sm hover:underline pr-2 cursor-pointer"
          >
            Clear All
          </p>
        </div>

        <HomePriceFilter />
        <HomeLocationFilter />
        <HomeTypeFilter />
        {/* <div className="py-6 h-48 bg-white w-full text-transparent">hey</div> */}
      </div>
    </div>
  );
}

export default HomeFilterModal;

Answer №1

If you want to improve performance, consider utilizing the Intersection Observer API. This API is highly effective and efficient: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

While I haven't delved deeply into your code, creating an observer (as outlined in the documentation) can be done as follows:

let observer = new IntersectionObserver(callback, options);

By observing your parent view (the background element) like so:

let target = document.querySelector('#yourParentSelector');
observer.observe(target);

You can then trigger the close() function only when the observed background moves.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Uncovering the characteristics of a GeoJSON data layer within Google Maps V3

Is there a way to access the properties of the data layer itself when loading a geoJSON file into a Google Map? I understand how to access the individual properties like posts_here, but I'm interested in obtaining the properties for the layer as a wh ...

utilize the flex index.html layout

Upon reviewing the template, I noticed that there is code implemented to check if the client has the necessary version. This code performs certain actions based on whether or not the required version is available. Additionally, there seems to be an <obj ...

Encountered a permission denial error (101) while attempting to upload a file to an SFTP server using SSH2 in

Encountering a permission denied error when attempting to upload a file to an SFTP server, whereas the same operation succeeds when using FileZilla. const UploadFiletoFTP = () => { let Client = require('ssh2').Client; var connSetti ...

Ways to Ensure a Property of an Object Remains Synced with Another

I'm dealing with the following Object structure: { a: "123" b: "$a" } In this setup, b should always be equal to the value of a. Any suggestions on how I can achieve this using JavaScript? ...

Access the angular controller using the radio button option

I am looking to showcase data in an HTML table retrieved from an Angular controller. I have the controller set up but I am unsure about how to display the data when a radio button is selected. <div class="radio"> <label class="radio-inline" ...

What strategies can be used to effectively perform a mongo db search that accommodates misspelled terms?

If I search for "wolrd," I would like documents containing "world" to be included in the results. ...

When accessing my express backend with passport.js, it seems to be giving a different response on the client side compared to when I access it directly through the server

I have set up my express backend with a '/check-auth' API endpoint that returns authenticated: true on the server. However, when I use the React client, it returns authenticated: false. const express = require("express"); const mongoose = requir ...

Issue with Material UI grid not rendering properly in TypeScript environment

I've been trying to replicate a grid from material-ui using React and Typescript. You can see a live demo here. I modified the example to work with Typescript, so my demo.tsx file looks like this: Code goes here... If you check out the live demo, y ...

Using a Do/While loop in combination with the setTimeout function to create an infinite loop

Having trouble with this script. The opacity transition works fine, but there seems to be an issue with the loop causing it to run indefinitely. My goal is to change the z-index once the opacity reaches 0. HTML <div class="ribbon_services_body" id="ri ...

Passing context to provider constructors in React Native: A comprehensive guide

I recently integrated ui-kitten into my react native project and have been referring to the documentation on how to modify the theme at runtime. In my App.js file, I have set up the navigator and providers. How can I ensure that the value of theme in <A ...

The correct reading of JavaScript in HTML is a common source of confusion

After creating a basic application using the code provided in a forum thread and testing it on the worker sandbox MTurk site, I noticed a peculiar issue. The application runs smoothly when following the code from the forum answer directly. However, when at ...

Guide to creating intricate animations using a CSS/JS user interface editor

Is there an easy way to create complex animations without blindly tweaking keyframes? I'm searching for a tool or editor that can generate the necessary animation code, similar to this example: https://codepen.io/kilianso/pen/NaLzVW /* STATE 2 */ .scr ...

Local error when attempting to export a node module

As a novice in node.js, I'm looking to parse an XML file into JSON. To achieve this, I decided to use the bluebutton library available at https://github.com/blue-button/bluebutton.js. After installing the module using npm install bluebutton, a node_m ...

Is there a way to reset the canvas with just a click of a button?

How do I reset the canvas upon button click? I attempted: cx.fillRect() However, the above method did not work as expected. I simply want to refresh the canvas without reloading the entire page. Below is my current code snippet: var canvas = docum ...

Retrieving a channel using its unique ID and then sending a message directly into it

I am attempting to retrieve a channel by its ID and then send a message to it, but I keep encountering an error when running the code. ERROR: Error sending message to welcome channel.: TypeError: Cannot read properties of undefined (reading 'send&apos ...

Challenges faced when using jQuery UI autocomplete

My code utilizes jQuery UI's autocomplete method on a text box: $(function() { $('#project').autocomplete({ source: function(request, response){response(Object.getOwnPropertyNames(projects))}, minLength: 0, ...

Tips for integrating Tornado authentication with AngularJS

I have been experimenting with the authentication system outlined in the tornado documentation, and I am encountering a Cross-Origin Request issue when trying to integrate it with AngularJS. Is there a way to successfully combine Tornado's authentica ...

steps to determine if a page is being refreshed

Is there a way to prevent the page from reloading when the user clicks the reload button in the browser? I attempted to use this code, but my break point is not triggering. ngOnInit() { this.router .events .subscribe((e: RouterEvent) = ...

The wrapper.find function is malfunctioning as a result of a connection issue

There seems to be an issue with the following test case using jest and enzyme: it('Displays Trade component', () => { console.log("Testing Shallow", wrapper) expect(wrapper.find('Trade').length).toEqual(1); }); To debug, ...

Exploring the new features of NextJS 13/14 with Server Components and the integration of Install

As a newcomer to the NextJS and React world, migrating from backend/server-rendered HTML web development, I find myself puzzled about the relationship between PWAs (Progressive Web Apps) and NextJS server components versus client components. Initially, I a ...