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

Modify input value using jQuery upon moving to the next step

When you type into an input[text] and press the tab button, it automatically moves to the next input. If you fill out all the inputs and then want to re-fill them, the values will be highlighted in blue. However, I wanted to achieve this without having to ...

Attempting to retrieve the value of a disabled input within a form will prove unsuccessful

Below is the format of the form in use: <form action="sendmail.php" method="get"> <input type="text" name="phone" id="phone" data-clear-btn="true"> <input type="text" name="name" id="name" data-clear-btn="true"> <input dis ...

Numerous Google Gauges featuring varying sets of options

Currently, I am facing a challenge involving the insertion of multiple instances of Google Gauges (or Highchart Gauges) on a single page. The goal is to utilize different option sets and separate their placement accordingly. Unfortunately, the solution pro ...

Establish the editor's starting state

Currently, I am utilizing lexical and aiming to establish initial text for the editor. At the moment, my approach involves hardcoding the initial text, but it seems I cannot simply pass a String as anticipated. Instead, the format required is JSON. Hence ...

Update the image source with jQuery when hovering over it

Check out this code snippet: (view the fiddle here) <img class="changeable" src="http://placehold.it/100x120&text=anniversary"> <ul class="rollover_list"> <li><a href="#" rel="http://placehold.it/100x120&text=anniv ...

Retrieving data with model.fetch in Backbone.js when the server response is null

In my app, we utilize model.fetch() to retrieve JSON from the server. The render function is triggered when the model undergoes a change and looks like this: if(_.isUndefined(this.model.get("id_number"))){ this.template = initialTemplate; } else if(th ...

Multer failing to generate file during request process

My current setup involves a router and multer middleware, but I'm facing an issue where the file requested is not being created. As a result, req.file always remains undefined. const multer = require('multer'); let storage = multe ...

Incorporating React.js into HTML DOM Elements

As a beginner in react js, I'm facing an issue regarding DOM elements. Within my component, there is a table. When hovering over a cell, I want to highlight both the corresponding row and cell. Additionally, I need to obtain the coordinates of the hov ...

Having trouble with routing nesting in react-router v4?

I find myself in the following situation: <Wrapper> <Container> <Route exact path="/" component={UserListing} /> <Route path="/user/:id" component={UserDetails} /> <Route exact path="(/|/user/\d+)" comp ...

When the collapsed navbar is displayed, elements are pushed beyond the boundaries of their parent container (Bootstrap 5)

Introduction Utilizing Bootstrap 5 (included with webpack 5), I am implementing the grid system and collapse function to design the homepage of this website, featuring 2 sidebars that collapse into a top bar. On mobile devices, the navigation collapses a ...

Issue with Bing Maps Infobox mouseout event: Problem arises when attempting to change the htmlContent asynchronously

Can anyone provide assistance? I am currently utilizing the latest Bing Maps version (v8), and I have encountered an issue. When creating a custom Infobox and populating its contents using an async request such as setTimeout/ajax, the mouseout event is tr ...

Are you facing issues with jQuery Ajax failing to respond?

On my webpage, I have a function that is supposed to call an ASP.NET webservice. It seems like the function is executing, but nothing happens on the page. Below is the code for the function: $("#BlogSelectList li a").click(function () { var str = ($(t ...

Handling dynamic routes with React Router 4 and the 404 path

I have been working with the latest version of React Router (4) and have implemented a dynamic route configuration as described in the tutorial. The routes are functioning correctly, except for when I tried to add a 404 path following the tutorial's i ...

Populating lists using AJAX technology

There are four select lists on my page. The first list's content loads upon page load, while the contents of the other lists depend on the selected item in the previous list. I have a function that fetches data from a URL address for each list. This ...

The inclusion of a content editable feature within a carousel is leading to unexpected event propagation

I am dynamically creating an editable div using the code snippet below. <div class='reflection-field' contenteditable="true" data-number="${index}"></div> Expected Outcome: When I click on the generated div, I anticipate that the c ...

Ways to set a background image for two separate components in Angular

Trying to figure out how to integrate this design: The challenge lies in having a background image that spans across the navbar and the content below it. Currently, the code separates the navbar component from the content component, making it tricky to ac ...

Encountering a constructor problem while Jest is mocking a class from an NPM module

I'm currently attempting to create a mock for the Discord.JS module. Within this module, there is a Client class that I am extending in my own "Bot" class. My goal is to mock the module in order to simulate certain methods on other classes such as "Me ...

Cross-Origin Resource Sharing (CORS) Issue: How Angular.JS, Node.JS, and

Encountering problems retrieving data from a http post request to my API. Seeing the following error message: XMLHttpRequest cannot load (URL to API here). No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin &ap ...

Searching for mobile WiFi preferences through a web browserHere are the steps to

Is there a method to access mobile connectivity settings through a website? I am interested in determining the connection type (3G\4G\WiFi) and if it is WiFi, identifying the security method being used. Is this achievable? If so, how? Edit: If ...

Challenges with uploading files using jQuery

Click here to upload a file I'm trying to create a feature where users can choose an image and have it displayed in place of the "trees" image. Feeling stuck, I could really use some guidance. Check out the code below: <div class="user-editab ...