Verify if an item is currently within the user's view

I'm encountering a new issue with a menu I'm working on. My goal is to hide the menu when the user clicks outside of it. The challenge lies in the fact that the menu is always visible but translated to the right of the element, making it not directly visible in the DOM.

The problem persists with the button not functioning as expected and the menu activating even when clicking on the screen. My attempts to verify the visibility of the div are ineffective. I've tried using the getBoundingClientRect() function suggested by many, but I'm currently stuck with

document.body.contains(MyElement)
. Here is my JavaScript:

function myFunction(x) {
        x.classList.toggle("change");
        document.getElementById("dropdown-meniu-content").classList.toggle("show");}
 $(document).click(function(event) { 
    if ( document.body.contains(document.getElementById('dropdown-meniu-content') ) ) {
        if(!$(event.target).closest('#dropdown-meniu-content').length) {
        document.getElementById("dropdown-meniu-content").classList.toggle("show");
                    document.getElementById("buton-meniu").classList.toggle("change");
        }        
}

}

The CSS:

    .logo {
            float: left;
            margin-top: 10px;
            margin-left: 5px;
            width: 200px;
            height: 100px;
        }
        .meniu {
            float: right;
            width: auto;
        }
        .buton-meniu {
            display: block;
            cursor: pointer;
            width: 35px;
            margin-right: 30px;
            margin-top: 40px;
        }
        .bar1, .bar2, .bar3 {
            width: 35px;
            height: 5px;
            background-color: black;
            margin: 6px 0;
            transition: 0.4s;
        }
        .change .bar1 {
            -webkit-transform: rotate(-45deg) translate(-9px, 6px);
            transform: rotate(-45deg) translate(-9px, 6px);
        }
        .change .bar2 {
            opacity: 0;
        }
        .change .bar3 {
            -webkit-transform: rotate(45deg) translate(-8px, -8px);
            transform: rotate(45deg) translate(-8px, -8px);
        }
        .dropdown-meniu {
            position: relative;
            display: inline-block;
        }
        .dropdown-meniu-content {

            top: 110px;
            position: fixed;
            background-color: #d6d6d6;
            width: 30%;
            max-width: 10000px;
            height: 100%;
            box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
            z-index: 1;
            overflow: hidden;
            right: 0;
            transform: translateX(100%);
            transition: transform 0.5s ease;
        }
        .show {
            transform: translateX(0%);
        }

Here's the HTML:

<div class="meniu">
        <div class="dropdown-meniu">
            <div id="buton-meniu" class="buton-meniu" onclick="myFunction(this)">
                <div class="bar1"></div>
                <div class="bar2"></div>
                <div class="bar3"></div>
            </div>
            <div id="dropdown-meniu-content" class="dropdown-meniu-content">
                <div class="dropdown-ferestre">
                    <div id="buton-ferestre" class="buton-ferestre">Ferestre</div>
                    <div id="dropdown-ferestre-content" class="dropdown-ferestre-content">
                        <p id="demo"></p>
                    </div>
                </div>
            </div>
        </div>
    </div>

If you prefer not to go through the code, you can also view the JSFiddle here: https://jsfiddle.net/1qrtb424/18/

Thank you for your assistance!

Answer №1

Verifying the visibility of an element on the screen can be quite challenging, but it may not be necessary to tackle this problem in order to achieve your goal. Unless there is a specific reason for doing so, you could simply check for the presence of the class that controls the visibility of the element instead of directly verifying its visibility on the screen.

I initially intended to make minimal changes to your JavaScript, but I ended up revising it significantly to address the propagation issue (where clicking a button triggers a click event on the document by default unless you use event.stopPropagation). The core concepts in my solution can still be applied to enhance your implementation.

By the way, I must say, the transition effect between the burger bar and 'x' button is very well-executed.

var button = document.querySelector('#buton-meniu');
var content = document.querySelector('#dropdown-meniu-content');

button.addEventListener('click', function(e) {
  e.stopPropagation();
  e.currentTarget.classList.toggle('change');
  content.classList.toggle('show');
}, true)

document.addEventListener('click', function() {
  if (content.classList.contains('show')) {
    content.classList.remove('show');
    button.classList.remove('change');
  }
})

content.addEventListener('click', function(e) {
  e.stopPropagation();
}
.logo {
            float: left;
            margin-top: 10px;
            margin-left: 5px;
            width: 200px;
            height: 100px;
        }
        .meniu {
            float: right;
            width: auto;
        }
        .buton-meniu {
            display: block;
            cursor: pointer;
            width: 35px;
            margin-right: 30px;
            margin-top: 40px;
        }
        .bar1, .bar2, .bar3 {
            width: 35px;
            height: 5px;
            background-color: black;
            margin: 6px 0;
            transition: 0.4s;
        }
        .change .bar1 {
            -webkit-transform: rotate(-45deg) translate(-9px, 6px);
            transform: rotate(-45deg) translate(-9px, 6px);
        }
        .change .bar2 {
            opacity: 0;
        }
        .change .bar3 {
            -webkit-transform: rotate(45deg) translate(-8px, -8px);
            transform: rotate(45deg) translate(-8px, -8px);
        }
        .dropdown-meniu {
            position: relative;
            display: inline-block;
        }
        .dropdown-meniu-content {

            top: 110px;
            position: fixed;
            background-color: #d6d6d6;
            width: 30%;
            max-width: 10000px;
            height: 100%;
            box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
            z-index: 1;
            overflow: hidden;
            right: 0;
            transform: translateX(100%);
            transition: transform 0.5s ease;
        }
        .show {
            transform: translateX(0%);
        }
<div class="meniu">
        <div class="dropdown-meniu">
            <div id="buton-meniu" class="buton-meniu" >
                <div class="bar1"></div>
                <div class="bar2"></div>
                <div class="bar3"></div>
            </div>
            <div id="dropdown-meniu-content" class="dropdown-meniu-content">
                <div class="dropdown-ferestre">
                    <div id="buton-ferestre" class="buton-ferestre">Ferestre</div>
                    <div id="dropdown-ferestre-content" class="dropdown-ferestre-content">
                        <p id="demo"></p>
                    </div>
                </div>
            </div>
        </div>
    </div>

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

Adjust the height of a div using jQuery animate based on the amount of text within

I have created a basic animation feature where users can click on an expanding box. I am looking for a solution that does not involve using a plugin. Currently, the code looks like this: $('#one').css("height", "22"); $('#t1').cli ...

JavaScript Object Instantiation within the Object Prototype

If we consider a scenario where there are 3 chapters of a novel each with its own unique URL structure: Chapter 1 = /1.html Chapter 2 = /2.html Chapter 3 = /3.html Now, to implement object-oriented principles using jQuery, the idea is to create two JS ...

Run a series of functions with arguments to be executed sequentially upon the successful completion of an ajax request

I am currently working on implementing a couple of jQuery functions to assist me in testing some api endpoints that I am developing in php. While I have limited experience with Javascript and jQuery, I am struggling to figure out what additional knowledge ...

Identify a duplicate class name element using Selenium

<ul class="k9GMp "> <li class="Y8-fY "><span class="-nal3 "><span class="g47SY ">2</span> posts</span> </li> <li class="Y8-fY "><a class="-nal3 " href="/username/followers/" tabindex="0"><span ...

When using WYSIWYG editors, be on the lookout for empty paragraphs and incorrect code in CSS, JavaScript, and

I am currently in the process of redesigning a website for a client. The site is already built using Joomla 1.7, but I am facing an issue with the articles section that was created by the client using a WYSIWYG editor. The problem lies in the messy code st ...

How can AJAX be used for form validation prior to submission?

Currently, I am facing an issue with validation on the client side when making an ajax cross-domain request to my PHP server page. I have a standard HTML form that posts input fields such as name, last name, and message. Here is an example of my form on th ...

What is the standard way to write the server-side code for HTTP request and response handling?

I stumbled upon these resources: How to send HTTP request GET/POST in Java and How to SEND HTTP request in JAVA While I understand the client-side aspect, how can this implementation be done on the server side? The goal is to utilize the link on the clie ...

SignalR error: A type conversion issue has occurred where it is not possible to directly convert a task returning an object to a string

I'm encountering an issue with my C# hub class where the JavaScript code is returning a System.Threading.Tasks.Task instead of a string. I need help modifying the JavaScript method to return an actual string. Below is the hub class: public String ge ...

Our system has picked up on the fact that your website is failing to verify reCAPTCHA solutions using Google reCAPTCHA V2

Error Message We have noticed that your website is not validating reCAPTCHA solutions. This validation is necessary for the correct functioning of reCAPTCHA on your site. Please refer to our developer site for further information. I have implemented the re ...

Navigate to a different webpage while employing sweetalert2 and extracting data using the GET method

Is there a way to use sweetalert2 for redirecting to deleting.php with a specific ID parameter? How can I include this dynamic data in the code snippet below, which is used to display options for editing and purging data from an SQL database? echo' &l ...

Generate the maximum capacity 3D box that can be inscribed within a set of points

I am working with a 3D mesh composed of a collection of 3D points (vertices) and a series of faces (connections between points). Q1 Is there a method to determine the largest inscribed box (volume) that can fit inside the mesh? [OP] Greetings everyone, ...

Omit specific object properties within a foreach loop in jQuery AJAX

Check Out This Fiddle Example I am currently working with a PHP file that returns JSON data for main content along with an additional property for pagination. I am looking for a way to exclude the pagination property when iterating over the data in a fore ...

Discover the class name within the AJAX content

I have a unique ajax response generated by a server-sided script: <div class="item-title3">Testname</div> <div class="item-level">120</div> <div class="item-binding">40</div> <div class=& ...

Improving the efficiency of rendering multiple objects on a canvas

I'm currently working on developing a simulation for ants using the basic Javascript canvas renderer. Here is a snippet of the rendering code: render(simulation) { let ctx = this.ctx; // Clearing previous frame ctx.clearRect(0, ...

React allows for items to be exchanged between two lists

I am currently working on a functionality that involves swapping items between two arrays. The user interacts with two lists in the UI by selecting items from the first list, which should then be removed from there and added to the second list where the se ...

Framework designed to be compatible with Internet Explorer 7 for seamless

Is there a CSS framework that provides full support for IE7 without any issues? Specifically, something similar to Twitter Bootstrap but with guaranteed rounded corners and properly functioning tabs. I have experienced problems with the Popover plugin sp ...

What is the process for importing a JavaScript file into a Vue component?

Having trouble importing JSON results into a Vue component? The results are as follows: [{"id":"d023c5e3-ca3c-4d97-933a-1112a8516eee", "score":9001, "updated":"2018-12-07T13:48:33.6366278", "player":Johanna, "category":Funny}, {"id":"398b65fb-e741-4801-b ...

splitting the array elements in JavaScript

I'm having trouble with my code that is supposed to separate the array in customer and customerportals. let j = 0; let k = 0; let myVar = []; $.each(Object.customer, function(index, value) { $.each(value.portal.customerPortal, function(innerIn ...

What is the best way to ensure the search box remains fixed in the top navigation bar while maintaining a fluid and responsive design?

I've been struggling as a novice programmer, and even with the help of more experienced programmers, we haven't been able to figure it out. I'm trying to integrate a search box into the top navigation that adjusts responsively to different ...

Using Three.js to seamlessly transition from one Panorama Cube to another with a smooth zoom-in effect

As a newcomer to Three.js, I am currently experimenting with an example featuring a set of 6 image cubes for a panorama effect. This allows users to pan, zoom in, and zoom out around the cubes. If you're interested, you can check out the example here ...