Check to see if the menu item exceeds the allotted space, and if so, display the mobile menu

Currently, I am in the process of creating a unique responsive menu for my website that I think will need some JavaScript implementation. My skills with JavaScript are not very strong, so I am looking for guidance, code examples, or resources that can assist me in finding solutions.

Essentially, I have two navigation menus with almost identical content. The first menu displays all the links when viewed on a wide browser, while the containing div has overflow:hidden property. As the browser is resized and no longer wide enough to hold all list items in one line, some items become hidden due to overflow. This first menu is styled as a horizontal navigation bar.

The second menu, however, is a dropdown menu triggered by clicking the "More" link. All list items in the second menu are initially set to display:none.

This is what needs to be accomplished: When a list item from the first menu overflows and becomes hidden, the corresponding item in the second menu should change to display:block. For example,

<li id="desktop_tenth">tenth</li>

is hidden because it doesn't fit the containing div anymore, then

<li id="mobile_tenth">tenth</li>

should become visible upon clicking the "More" link. While this can be achieved using CSS3 media queries, I would prefer a JavaScript solution and hope someone can help me out.

<div style="overflow:hidden; width: 100%;">
    <ul id="desktop">
        <li id="desktop_first">first</li>
        <li id="desktop_second">second</li>
        ...
        <li id="desktop_tenth">tenth</li>
    </ul>
</div>
<div class="dropdown_menu">
    <a id="toggle" href="#">More</a>
    <ul id="mobile">
        <li id="mobile_first">first</li>
        <li id="mobile_second">second</li>
        ...
        <li id="mobile_tenth">tenth</li>
    </ul>
</div>

An alternative approach could involve starting with a

<div class="dropdown_menu">
    <a id="toggle" href="#">More</a>
    <ul id="mobile">
        <!--- no li inside this ul by default --->
    </ul>
</div>

Any list item from the first menu that gets hidden or wrapped will be added as a new item to the

<ul id="mobile">

</ul>

section.

Answer №1

Outlined are the specific ids for the menus' divs (for example, desktopMenu and mobileMenu), as shown below:

<div id="desktopMenu" style="overflow:hidden; width: 100%;">

Additionally:

<div id="mobileMenu" class="dropdown_menu">

The following script should be utilized:

var desktopMenu = document.getElementById('desktopMenu'), mobileMenu = document.getElementById('mobileMenu');

desktopMenu.style.display = 'none';
mobileMenu.style.display = 'none';

if (desktopMenu.offsetHeight < desktopMenu.scrollHeight || desktopMenu.offsetWidth < desktopMenu.scrollWidth) {
    mobileMenu.style.display = 'block';
} else {
    desktopMenu.style.display = 'block';
}

This script initially hides both menus and then assesses if the desktopMenu div is overflowing. If it is, the mobile menu is displayed; otherwise, the desktop menu is shown. A more streamlined solution using jQuery is recommended.

Answer №2

Are you struggling with managing overflowed menu items in your web page? Look no further, as I have a jQuery solution just for you!

To address the issue of overflowing menu items, we compare the top position of the window with the first element in the menu.

function findHiddenPosition() {
  var menuItems = $('ul#desktop > li');
  var length = menuItems.length;
  var position = 0;
  var top = $('ul#desktop > li').first().position().top;
  var nextLine = false;
  var currentTop;
  
  while (!nextLine && position < length) {
    currentTop = $(menuItems[position]).position().top;
    if (currentTop > top) {
      nextLine = true;
    } else {
      position++;
    }
  }
  
  return position;
}

function resetDropdown() {
  var length = $('ul#desktop > li').length;
  var position = findHiddenPosition();
  var mobileItems = $('ul#mobile > li');

  if (position == length) {
    $('.dropdown_menu').addClass('hidden');
  } else {
    $('.dropdown_menu').removeClass('hidden');
    $('ul#mobile > li').removeClass('hidden');
    
    for (var i = 0; i < position; i++) {
      $(mobileItems[i]).addClass('hidden');
    }
  }
}

resetDropdown();

$(window).resize(resetDropdown);
div.dropdown_menu.hidden, div.dropdown_menu li.hidden {
  display: none;
}

div.inline_menu {
  overflow: hidden;
  width: 100%;
  height: 30px;
}

ul#desktop li {
  display: inline-block;
  height: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="inline_menu">
    <ul id="desktop">
        <li>Menu 1</li>
        <li>Menu 2</li>
        <li>Menu 3</li>
        <li>Menu 4</li>
        <li>Menu 5</li>
        <li>Menu 6</li>
        <li>Menu 7</li>
        <li>Menu 8</li>
        <li>Menu 9</li>
        <li>Menu 10</li>
    </ul>
</div>
<div class="dropdown_menu hidden">
    <a id="toggle" href="#">More</a>
    <ul id="mobile">
        <li>Menu 1</li>
        <li>Menu 2</li>
        <li>Menu 3</li>
        <li>Menu 4</li>
        <li>Menu 5</li>
        <li>Menu 6</li>
        <li>Menu 7</li>
        <li>Menu 8</li>
        <li>Menu 9</li>
        <li>Menu 10</li>
    </ul>
</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

Embedding content within various ng-template elements

I'm currently working on developing a button component (app-button) that can utilize multiple templates based on the parent component using it. <div class="ds-u-margin-left--1 ds-u-float--left"> <ng-container *ngTemplateOutlet="icon">< ...

What is the best way for Protractor to effectively wait for a popover to be displayed and verify that it does not contain an empty string?

Whenever you hover over it, this appears - my popup: This is what the html looks like before we add the popover to the DOM: <span tariff-popover="popover.car2go.airport" class="ng-isolate-scope"> <span ng-transclude=""> ...

django, the X-CSRFToken in the request header is improperly configured

Essentially, I have managed to successfully send a CSRF token to the frontend and store it in the cookie section of the application tab within the developer console of the browser with this code: @method_decorator(ensure_csrf_cookie) def get(self, ...

Align component within material-ui grid

Looking to center align the same cards but not just the grid component, I need the content itself to be equally distant from the borders and each other. I've searched and tried different solutions without luck. https://i.stack.imgur.com/aZj7H.png htt ...

How to stop a checkbox from being selected in Angular 2

I have a table with checkboxes in each row. The table header contains a Check All checkbox that can toggle all the checkboxes in the table rows. I want to implement a feature where, if the number of checkboxes exceeds a certain limit, an error message is ...

Issue with transition on the second attempt

In this code snippet, I have managed to achieve my desired outcome but it seems to only work on the first run. I am not sure why this is happening, so if anyone can help me out that would be greatly appreciated. Here is a demo of the code in action: HTML ...

What is the proper way to display the complete result of aggregating each outcome from the previous iteration within two nested queries in an array using NodeJS and Mongoose?

As a newcomer to both Stackoverflow and NodeJS/Mongoose, I apologize if I make any mistakes or break any rules. Thank you in advance. I'm looking for a function that can return all nearby products based on my current location, which is provided by th ...

Struggling with the adaptability of my website's footer section

I'm facing a dilemma... No matter what I do, I can't seem to position my contact form over my Google iframe perfectly. It works fine if I don't mind sacrificing responsiveness, but as soon as I try to make it responsive, the absolute assign ...

AngularJS, the element being referenced by the directive is empty

Currently, I am in the process of transferring a jQuery plugin to AngularJS simply for the enjoyment of it. Previously, when working with jQuery, my focus was on manipulating the DOM using jQuery functions within the plugin loading function. Now that I am ...

Determining the file path in HTML5

Can anyone help me with retrieving the file path using html5 javascript once a user selects a file? I require the file path for a specific scenario: In this case, the user uploads a file and pauses it (currently only supported by Mozilla browsers), then c ...

Tips for choosing a class using ng-if

Looking for a solution regarding my use of ng-repeat: HTML: <td class="border" data-ng-repeat="price in goHead.prices track by $index"> In the context of my <td>, I want to apply the class border if data-ng-if="price.isMinPrice" is true, oth ...

Error message: The function .datepicker('getDate') caused an Uncaught TypeError: Data[option] error

Encountering an issue with the code data[option] is not a function when attempting to utilize .datepicker('getDate'). The datepicker was initialized using this code: <h4>Transaction Date:</h4> From: <input id="sta ...

The Ajax Form disappears from the page

After racking my brain for a while, I've come to the conclusion that it's time to seek some assistance. I have work tomorrow and I don't want to spend all night on this. The issue lies in my form which is located inside a modal, here is my ...

Ways to minimize renders while toggling a checkbox

I'm currently working on developing a high-performance checkbox tree component. To manage the checked checkboxes, I am utilizing a parent level state that contains an array of selected checkbox IDs => const [selected, setSelected] = useState([]); ...

How can I achieve a letter-spacing of 0.5 pixels in CSS?

Encountering an issue, I set out to enhance readability by adjusting letter-spacing to 1px. Displeased with the result, I attempted a half pixel spacing of 0.5px but found it ineffective. Subsequently, I experimented with em attributes but failed to accomp ...

I'm encountering an error when trying to use makeStyles

Something seems off with MUI. I was working on my project yesterday and makeStyles was functioning properly, but now it's suddenly stopped working. I'm encountering an error when calling it here: I suspect the issue lies in the import statement ...

Identifying tick markers in the event loop of JavaScript and Node.js

Is there a way to determine if a function is called in the current tick or if it will be called in the next tick of Node.js event loop? For instance: function exampleFunction(callback){ // we can call callback synchronously callback(); // or we c ...

Troubleshooting a Vue 2 component's prop receiving an incorrect value

I'm currently working on creating a menu that navigates between categories. When a category has a sub-category, it should return a boolean value indicating whether it has a sub-category or not. <template> <select><slot></slot ...

In Javascript, where are declared classes stored?

When working in a browser environment like Firefox 60+, I've encountered an issue while attempting to retrieve a class from the global window object: class c{}; console.log(window.c); // undefined This is peculiar, as for any other declaration, it w ...

The bottom portion of my page vanishes without a

My footer has the following CSS class: .footer{ border-top:solid 2px #BBB; background : url('../images/footer.png'); font-family : helvetica; font-style : italic; height:9em; clear: both; color: black; wid ...