Modify the fixed div's class when the user scrolls past a certain section

My page includes a fixed menu with various sections, each assigned a specific class name using data attributes (e.g. data-menu="black"). I want the fixed menu to change its class based on the section that is currently underneath it as the user scrolls.

You can view my code on jsFiddle here: https://jsfiddle.net/pt3taagp/1/

HTML

<div class="fixed-menu">
  <ul>
  <li>menu 1</li>
  <li>menu 2</li>
  <li>menu 3</li>
  <li>etc.</li>
  </ul>
</div>
<section data-menu="menu-black">
  <img src="http://placehold.it/600x600/ffffff/000000">
</section>
<section data-menu="menu-white">
  <img src="http://placehold.it/600x600/000000/ffffff">
</section>
<div>some other content</div>

CSS

.fixed-menu {
  position: fixed;
  top: 50px;
  left: 50px;
  width: 250px;
  background-color: red;
}
.fixed-menu.menu-black {
  background-color: #000;
}

.fixed-menu.menu-white {
  background-color: #FFF;
}

The default background color of the menu is red, but I want it to change based on the section below it (e.g. to white when the section has data-menu attribute=menu-white).

Answer №1

The JQuery offset() function provides the relative positioning of a specific element. Feel free to check out this fiddle for more information.

However, it's important to note that this method will only be effective if you have a fixed section height.

 window.onscroll = function() {
   myFunction()
 };

 function myFunction() {
   var x = $("#mainmenu").offset();
   if (x.top < 612) {
     document.getElementById("mainmenu").className = "fixed-menu menu-white";
   } else if (x.top > 612) {
     document.getElementById("mainmenu").className = "fixed-menu menu-black";
   }else{
     document.getElementById("mainmenu").className = "fixed-menu";
   }
 }
.fixed-menu {
  position: fixed;
  top: 50px;
  left: 50px;
  width: 250px;
  background-color: red
}
.menu-black {
  background-color: #000;
  color: white;
}
.menu-white {
  background-color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
  <div id="mainmenu" class="fixed-menu">
    <ul>
      <li>menu 1</li>
      <li>menu 2</li>
      <li>menu 3</li>
      <li>etc.</li>
    </ul>
  </div>
  <div class="black">
    <section data-menu="menu-black">
      <img src="http://placehold.it/600x600/ffffff/000000">
    </section>
  </div>
  <div id="white">
    <section data-menu="menu-white">
      <img src="http://placehold.it/600x600/000000/ffffff">
    </section>
  </div>
  <div class="some-other-content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>
      ... [Text continues with Lorem Ipsum content]
    </p>
  </div>

</div>

Answer №2

Shoutout to this post about getting the current mouse position on scroll and identifying all elements present at a specified position, which led me to this solution:

  • Obtain the mouse position under any circumstance
  • Handle the window scroll event
  • While scrolling, if the element under the current mouse position is a section: alter the class based on the data-menu attribute. In all other scenarios, remove the added class.

var xMousePos = 0;
var yMousePos = 0;
var lastScrolledLeft = 0;
var lastScrolledTop = 0;

function GetSectionElementsAt(x, y) {
  var elements = $('section').map(function() {
    var thisObj = $(this);
    var offset = thisObj.offset();
    var l = offset.left;
    var t = offset.top;
    var h = thisObj.height();
    var w = thisObj.width();

    var maxx = l + w;
    var maxy = t + h;

    return (y <= maxy && y >= t) && (x <= maxx && x >= l) ? thisObj : null;
  });

  return elements;
}

$(document).mousemove(function(e) {
  xMousePos = e.pageX;
  yMousePos = e.pageY;
});

$(window).on('scroll', function (e) {
  if(lastScrolledLeft != $(document).scrollLeft()){
    xMousePos -= lastScrolledLeft;
    lastScrolledLeft = $(document).scrollLeft();
    xMousePos += lastScrolledLeft;
  }
  if(lastScrolledTop != $(document).scrollTop()){
    yMousePos -= lastScrolledTop;
    lastScrolledTop = $(document).scrollTop();
    yMousePos += lastScrolledTop;
  }
  var eleAtCurrentMousePos = GetSectionElementsAt(xMousePos, yMousePos);
  if (eleAtCurrentMousePos.length > 0) {
    var classToSet = eleAtCurrentMousePos[0].data('menu');
    if (!$('div.fixed-menu').hasClass(classToSet)) {
      $('div.fixed-menu').removeClass('menu-white menu-black').addClass(classToSet);
    }
  } else {
    $('div.fixed-menu').removeClass('menu-white menu-black');
  }
});
.fixed-menu {
  position: fixed;
  top: 50px;
  left: 50px;
  width: 250px;
  background-color: red
}

.fixed-menu.menu-black {
  background-color: #000;
}

.fixed-menu.menu-white {
  background-color: #FFF;
}
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>

<div class="fixed-menu">
    <ul>
        <li>menu 1</li>
        <li>menu 2</li>
        <li>menu 3</li>
        <li>etc.</li>
    </ul>
</div>
<section data-menu="menu-black">
    <img src="http://placehold.it/600x600/ffffff/000000">
</section>
<section data-menu="menu-white">
    <img src="http://placehold.it/600x600/000000/ffffff">
</section>

<div class="some-other-content">
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
        pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
        laborum.
    </p>

    <p>
        ... [content repeated for brevity]
    </p>

    <p>
        ... [content repeated for brevity]
    </p>
</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

Achieving record creation using jQuery ajax with Rails default :resources routing

When working on my Ruby on Rails application, I'm attempting to utilize jQuery ajax for creating a new item using the default create method in my controller. In my routes.rb file, I have defined the resources like this: resources :items The server- ...

When does the ng-disable function become activated?

Here's an example: <button ng-disabled="!isSomethingValid() || loading || disabled" ... class="btn btn-primary"> What determines the condition for the ng-disable attribute to evaluate its expression? ...

Creating a customized bundle with Bootstrap using the Rollup tool

In the official Bootstrap 5 documentation, it mentions that we can import pre-compiled js files from bootstrap/js/dist and create a custom bundle using tools like Webpack or rollup. https://getbootstrap.com/docs/5.0/getting-started/javascript/#individual- ...

Looking to display an alert message upon scrolling down a specific division element in HTML

In the midst of the body tag, I have a div element. <div id="place"> </div> I'm trying to achieve a scenario where upon scrolling down and encountering the div with the ID "place", an alert is displayed. My current approach involves che ...

Secure your React TypeScript applications with GraphQL authentication

When users try to log in on my website, I need to verify their authentication using data from a GraphQL API. I referred to this tutorial for guidance: https://www.apollographql.com/docs/react/networking/authentication/ In my GraphQL playground, I execute ...

having trouble with my lambda function reading the basic json object

I recently joined Lambda and have been attempting to create a simple JSON object. However, I keep encountering an error that says "parsing error, unexpected token." Here is my code, which I have verified to be valid JSON: { "metadata": { ...

Guide on retrieving JSON information within an array utilizing a loop function

Hey everyone, I'm facing an issue and I could really use some help. I'm new to working with ajax processing and I'm stuck on a problem. I have successfully retrieved ajax data and now I need to store it in an array. My goal is to populate a ...

Tips for applying CSS conditionally to content at varying nesting levels

Currently, I am working with sass and finding it challenging to modify the structure of the page easily. The layout I have in place is due to my header having varying sizes depending on the specific page users are browsing: <div class="container"> ...

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) = ...

Monitoring and recording user's browsing activities while excluding server-side scripting

Currently, I am working on creating a registration form which will direct users to a "Thank you" page once completed. However, I want to include a button on this confirmation page that will take users back to the previous page they were on before registeri ...

Tips for customizing elements using Wordpress

Is there a way to easily make my four divs containing icon images and descriptive text editable in WordPress? I have some experience setting up basics and using widgets in my footer and sidebar, but I'm not sure if that's the best approach for th ...

I'm caught in a never-ending cycle as I navigate through sending information to my Python API and subsequently utilizing that information in the Next.js application to execute the Python script

I am encountering an issue with the response message, getting "Error sending data." The problem seems to arise when trying to retrieve data in server.py that is already specified in the code. For example, instead of using "msg_user", I should use ...

CSS border alignment techniques

I am attempting to achieve the effect of having an orange border on top of a blue border, with only the orange border moving. I have noticed this design feature on various websites but have been unable to replicate it without removing the padding of the pa ...

A guide on incorporating a method using ES6 Rest into a JavaScript object

My goal is to enhance my Person constructor by adding a method that allows users to add friends. I wanted to utilize the "rest" feature of ES6 to pass a variable number of friends, but I seem to be stuck. My initial attempt resulted in an error ("Uncaught ...

Second attempt at loading Jquery was unsuccessful

I have a question regarding the code snippet below that I am using to reload a PHP file after 20 seconds within a div. However, the issue I am facing is that after the initial load in my target div, it does not display anything. Do you have any suggestion ...

Version 1.0 and higher of Ionic do not display the side menu when using tabs

I have developed an app using Ionic that includes a side menu with tabs feature. The side menu displays correctly when using Ionic version 0.9.27, but it does not show up when the version is 1.0 or higher. What could be causing this issue? HTML Layout & ...

Differences between CookieParser and req.cookies in ExpressJS

As I was reading the documentation on req.cookies in expressjs docs, I learned that when the cookieParser() middleware is used, this object defaults to {} but otherwise contains the cookies sent by the user-agent. Then, exploring the details of the Coo ...

A stateless component in React must always return a valid React element or null

I am a beginner with ReactJS and I am facing an issue. My goal is to showcase Hello world using the code snippet provided below, however, I keep encountering this error message: Can someone guide me on what I might be overlooking? The following is the c ...

Having challenges retrieving information from MySQL in AngularJS

As a beginner in angularJS, I am trying to display all customers from MySQL. Here is the code I have written in the controller and service: app.controller('CustomersController', function ($scope, customersService, $http) { init(); function ini ...

Leveraging jQuery functions with dynamically generated DOM elements in JavaScript

On my website, I have a button that dynamically generates a dropdown menu, a textfield, and two buttons when clicked. The purpose of the textfield is to track the quantity selected, while the two buttons allow users to increase or decrease the value by 1. ...