Change the color of the menu icon based on the specified HTML class or attribute

I'm trying to create a fixed menu that changes color depending on the background of different sections.

Currently, I am using a data-color attribute but I am struggling with removing and adding the class to #open-button. Adding the class works fine, but removing the correct one is proving to be difficult for me.

If you want to take a look at my code, check out my fiddle.

Here's a snippet of my code:

<div id="top-wrapper">
<div class="menu-button" id="open-button"><span></span></div>
</div>

<section class="section black-bg" data-color="icon-white">
  Section One has a black background
</section>
<section class="section white-bg" data-color="icon-black">
  Section Two has a white background
</section>
<section class="section black-bg" data-color="icon-white">
  Section Three has a black background
</section>
<section class="section white-bg" data-color="icon-black">
  Section Four has a white background
</section>

jQuery snippet:

$(function(){
$(window).on('scroll', function() {
        var scrollTop = $(this).scrollTop();
        $('.section').each(function() {
            var topDistance = $(this).offset().top;
            if ( (topDistance) < scrollTop ) {
                $('#open-button').addClass($(this).attr('data-color'));
            }
        });
    });
})

Answer №1

You can utilize the removeClass() function along with a regex pattern.

The regex pattern in this case will target classes that start with icon-

$(function() {
  $(window).on('scroll', function() {
    var scrollTop = $(this).scrollTop();
    $('.section').each(function() {
      var topDistance = $(this).offset().top;
      if ((topDistance) < scrollTop) {
        //Apply removeClass and addClass
        $("#open-button").removeClass(function(index, className) {
          return (className.match(/(^|\s)icon-\S+/g) || []).join(' ');
        });
        $('#open-button').addClass($(this).attr('data-color'));
      }
    });
  });
})
.section {
  height: 500px;
  width: 100%;
}

.black-bg {
  background: #000000;
  color: #ffffff;
}

.white-bg {
  background: #ffffff;
  color: #000000;
}

#top-wrapper {
  position: fixed;
  z-index: 1005;
  width: 125px;
  top: 40px;
  left: 47px;
}

#open-button {
  z-index: 10005;
  display: block;
  width: 30px;
  height: 40px;
  margin: 20px 0 0 20px;
  float: right;
  position: relative;
  background: #fff;
}

#open-button.icon-black {
  background: #000;
}

#open-button.icon-white {
  background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-wrapper">
  <div class="menu-button" id="open-button"><span></span></div>
</div>

<section class="section black-bg" data-color="icon-white">
  Section One is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Two is white
</section>
<section class="section black-bg" data-color="icon-white">
  Section Three is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Four is White
</section>

Answer №2

You have the ability to include

removeClass()

$(function() {
  $(window).on('scroll', function() {
    var scrollTop = $(this).scrollTop();
    $('.section').each(function() {
      var topDistance = $(this).offset().top;
      if ((topDistance) < scrollTop) {
        $('#open-button').removeClass().addClass($(this).attr('data-color'));
      }
    });
  });
})
.section {
  height: 500px;
  width: 100%;
}

.black-bg {
  background: #000000;
  color: #ffffff;
}

.white-bg {
  background: #ffffff;
  color: #000000;
}

#top-wrapper {
  position: fixed;
  z-index: 1005;
  width: 125px;
  top: 40px;
  left: 47px;
}

#open-button {
  z-index: 10005;
  display: block;
  width: 30px;
  height: 40px;
  margin: 20px 0 0 20px;
  float: right;
  position: relative;
  background: #fff;
}

#open-button.icon-black {
  background: #000;
}

#open-button.icon-white {
  background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-wrapper">
  <div class="menu-button" id="open-button"><span></span></div>
</div>

<section class="section black-bg" data-color="icon-white">
  Section One is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Two is white
</section>
<section class="section black-bg" data-color="icon-white">
  Section Three is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Four is White
</section>

Answer №3

Check out the solution provided here: https://jsfiddle.net/p1dfrzfg/4/

$(function(){
   var prevClass = "";
   $(window).on('scroll', function() {
      var scrollTop = $(this).scrollTop();
      $('.section').each(function() {
         var topDistance = $(this).offset().top;
         if ( (topDistance) < scrollTop ) {
            $('#open-button').removeClass(prevClass).addClass($(this).attr('data-color'));
            prevClass = $(this).attr('data-color');
         }
      });
   });
})
.section {
  height:500px;
  width:100%;
}

.black-bg {
  background:#000000;
  color:#ffffff;
}

.white-bg {
  background:#ffffff;
  color:#000000;
}

#top-wrapper {
    position:fixed;
    z-index: 1005;
    width:125px;
    top:40px;
    left:47px;
}
#open-button {
    z-index: 10005;
    display: block;
    width: 30px;
    height: 40px;
    margin: 20px 0 0 20px;
    float:right;
    position:relative;
    background:#fff;
}

#open-button.icon-black{
  background:#000;
}

#open-button.icon-white{
  background:#fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top-wrapper">
<div class="menu-button" id="open-button"><span></span></div>
</div>

<section class="section black-bg" data-color="icon-white">
  Section One is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Two is white
</section>
<section class="section black-bg" data-color="icon-white">
  Section Three is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Four is White
</section>

Maintain the existing class and switch it upon scrolling down, updating the menu with a new class.

I trust this will be beneficial to you.

Answer №4

Use this Pure CSS solution that utilizes the mix-blend-mode: exclusion property:

.section {
  height:500px;
  width:100%;
}

.black-bg {
  background:#000000;
  color:#ffffff;
}

.white-bg {
  background:#ffffff;
  color:#000000;
}

#top-wrapper {
  position:fixed;
  z-index: 1005;
  width:125px;
  top:40px;
  left:47px;
  mix-blend-mode: exclusion;
}
#open-button {
  z-index: 10005;
  display: block;
  width: 30px;
  height: 40px;
  margin: 20px 0 0 20px;
  float:right;
  position:relative;
  background:#fff;
}

#open-button.icon-black{
  background:#000;
}

#open-button.icon-white{
  background:#fff;
}
<div id="top-wrapper">
  <div class="menu-button" id="open-button"><span></span></div>
</div>

<section class="section black-bg" data-color="icon-white">
  Section One is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Two is white
</section>
<section class="section black-bg" data-color="icon-white">
  Section Three is black
</section>
<section class="section white-bg" data-color="icon-black">
  Section Four is White
</section>

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

Strategies for preventing the appearance of empty rows associated with unused <tr> elements

I currently have multiple asp.net panel controls that I am displaying using an html table. These panels are initially set to visible = false, but depending on the data retrieved from the database, some of the panels will be made visible. The issue arises w ...

Fade out the notification div using jQuery in MVC4

I'm a beginner in the world of JavaScript and JQuery and I could really use some assistance with resolving a simple issue that I've encountered. As part of my application's functionality, I am dynamically loading the following div based on ...

navigating up and down html elements using css selectors

Within my code, I have this odd repetitive HTML structure (with no classes) and I'm looking to extract all links along with the accompanying text below each link. While it's simple enough to grab all the links using a basic CSS query selector li ...

Using jQuery: When the API has loaded successfully, execute the specified function

As I dive into working with a search flight API, my goal is to configure some settings when the API loads. Below is the code snippet for loading the API: skyscanner.load('snippets', '1'); function main(){ var snippet=new skysc ...

Pressing the escape key on the keyboard will act as a shortcut to go

Is there a way to use Javascript in a browser to make the escape key on the keyboard go back? For instance, when visiting this page and clicking the "Fullscreen" link, it would be great to simply press the escape key and return to the previous page. What ...

Retrieve the element that is currently being hovered over within the same nested selector

I am facing a challenge in selecting the currently hovered element with a nested selector. The ".frmElement" class is used as the selector. When I hover over the ".frmElement" element at a certain level, all the previous selector elements display the hover ...

Mistakenly appearing at the top of the window instead of the bottom of the window

Utilizing Vue.js to fetch resources from a Laravel API periodically and paginate(), after retrieving the initial 10 instances, I aim to get the next 10. Here's how my method looks: scroll () { window.onscroll = () => { let bottomOf ...

Arranging hierarchical data in JavaScript

After populating the hierarchy data, it is structured as follows: Here is a screenshot: I am looking to sort this data. Currently, I have a flat data object for rendering purposes. For example, my rendering object looks like this: renderedobjects=[ {1,. ...

Retrieving the Href attribute from a designated div class with JQuery

I'm currently developing a Google Chrome extension where I need to extract the source code of a webpage using a jQuery get function. Here is how I implemented it: $.get(link,function(data){ // The entire source code of the link will be stored in the ...

Adjust the width of a div element to a specific size, center the div horizontally, and justify

My issue may be small, but I am struggling to find a solution. I have a content header that is 864px wide with a background image repeated vertically and a footer image. I now have a <div> positioned over the background image and I want it to be 855p ...

The TypeError thrown by Mongo .updateMany() indicates that the property 'updateMany' of the object is not a valid function

Currently, I have a collection named users, which contains the following documents: Document 1: { "_id": { "$oid": "5934fd84d6ba4c241259bed1" }, "first_name": "Joe", "last_name": "Smith", "username": "jsmith", "email": "&l ...

Choosing a value in the second dropdown menu based on the selection made in the first dropdown menu can be achieved by retrieving both values from the database using a common list

I have a scenario where I am utilizing two drop-down menus with the same data sourced from a database. When a particular item is selected in the first drop-down, it should not be available in the second drop-down. For instance, the values in the first dro ...

Exploring JSON with JavaScript

[ {"lastName":"Noyce","gender":"Male","patientID":19389,"firstName":"Scott","age":"53Y,"}, {"lastName":"noyce724","gender":"Male","patientID":24607,"firstName":"rita","age":"0Y,"} ] The data above represents a JSON object. var searchBarInput = TextInput. ...

Is there a way to customize the pagination dots in react-native-swiper-flatlist?

Is it possible to customize the pagination dots style for react-native-swiper-flatlist? <View style={styles.container}> <SwiperFlatList autoplay={false} autoplayLoop={false} index={0} showPagination ...

What is preventing HTML from triggering JavaScript when loaded inside a <div> with a script?

I'm working on creating a collapsible menu that I can easily customize on any page without the use of iframes. As someone new to web design, I have knowledge of CSS and HTML but I am currently learning JavaScript with limited experience in jQuery or A ...

Central alignment of div with cursor

I'm experimenting with creating a unique custom cursor using a <div> that trails the movement of the mouse pointer. While the current setup works smoothly, I've noticed that when scrolling down the page, the div lags behind until the scrol ...

Creating a customized navigation bar with a unique menu list underline feature using JavaScript

I recently created a customized navbar using a script to add a hover effect to the menu links. You can find the script I used here: https://github.com/shadeed/underliner. Although I was able to get it partially working, there are still some issues. The we ...

Reducing an array group using index in JavaScript: A beginner's guide

Do you have coding questions? Check out this sample array group: myArray = { tab1 : [], tab2 : [], tab3 : [], tab4 : [] } I'm looking to always retain the first tab (tab1) and an additional tab based on an index (ranging from 2 to 4) For instance, ...

Using threejs to pass multiple secondary geometries into vertex shaders

Suppose I have a geometry that I am using to create points or an InstancedMesh by utilizing the vertices. However, if I want to change this underlying geometry to something else - such as from a cone to a sphere - that has the same number of vertices, how ...

Strange CSS Problem: Button dysfunction in displays sized 13 inches or 15 inches

I have made a landing page using the latest version of bootstrap. However, I am encountering an odd issue where the success button is not clickable on certain devices such as 13-inch and 15-inch laptops and desktops. You can find the URL for the landing p ...