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

Ways to access information from doc.data()

<template> <div> {{ id }} {{ title }} </div> </template> <script> import { useRoute } from 'vue-router' import 'firebase/firebase-firestore' import { db } from '@/fdb' export default ...

Looking for assistance with extracting only numerical values from a webpage using Selenium in Python

Website Elements <td style="font-size:20px;font-family:LucidaGrande,tahoma,verdana,arial,sans-serif;padding:10px;background-color:#f2f2f2;border-left:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;border-bottom:1px solid #ccc; ...

Issue with jquery.validate.js in an MVC 4 Project using jQuery 1.9

Recently, I set up a new ASP.Net MVC 4 project using the default template in Visual Studio 2012. However, I encountered an issue after updating to jQuery 1.9 where the login functionality stopped working. The specific error message that appears is: 0x80 ...

What exactly does the term "entry point" refer to within the context of npm init?

Starting a new project can be overwhelming, especially when faced with a list of questions during the npm init process. One question that often stumps developers is "entry point." The options provided, like name, version, and description, may seem straig ...

Form_Open will automatically submit - Ajax Submission in CodeIgniter

I am facing an issue with submitting my form via Ajax. Despite setting up a function to prevent the page from refreshing upon submission, it seems like the form still refreshes the page every time I click submit. I even tried creating a test function to lo ...

Ways to resolve the error message "TypeError: 'setOption' is not a function on type 'MutableRefObject' in React"

CODE export default function EChart({ option, config, resize }) { let chart = useRef(null) let [chartEl, setChartEl] = useState(chart) useEffect(() => { if (resize) { chartEl.resize() } if (!chartEl.cu ...

Error message appearing when attempting to add a product to the cart in Magento using AJAX

Encountering an error with the magento 1.8 ajax cart, stating "product not found" The javascript code I implemented: function setLocationAjax(url,id){ var data = jQuery('#product_addtocart_form').serialize(); data += '& ...

Result of a callback function

Having trouble returning a value for form validation using a callback function. It's not working for me... <form action="loggedin.php" onsubmit="return test(valid)" method="post"> function test(callback) { var k = ""; var httpRequest = ...

Tips for managing @ManyToMany relationships in TypeORM

In this scenario, there are two distinct entities known as Article and Classification, linked together by a relationship of @ManyToMany. The main inquiry here is: How can one persist this relationship effectively? The provided code snippets showcase the ...

Format specific words or characters in a text input

In HTML, when I want to display strings in a Text Input or TextArea, I am looking for a way to have specific substrings render with a box around them. I envision these boxed substrings as being treated as a single entity, similar to how highlighting or tex ...

How can I make a layer visible in OpenLayers?

I can't figure out what I'm doing wrong. I believe everything is written correctly: The HTML code I have looks like this: <b>&nbspSelect Area</b> <select id="mySelect_1" onchange="showSelectedArea();" > <op ...

By increasing the background-color to 100%, the list item obstructs the background image of its parent div

In cases where an element is set to display:block, the background-color of that element typically extends to 100% of the width of its parent element. However, I am seeking a solution where the background-color only reaches the edge of the text, allowing th ...

Encountering a Blank Area at the Top of a Printed AngularJS Screen

Currently, I am tackling an issue in AngularJS while working on the Print Invoice Page. The problem I am encountering is a blank space at the top of the printed screen. Check out the image here Below is my code: HTML <div id="invoice" class="compact ...

I am facing an issue where my Javascript hide and show function is not working properly when clicked. Despite not giving

I am currently working on a Javascript onClick function to toggle the visibility of content in a lengthy table. I initially set part of the table's class to display: "none" and added a button to show the hidden content when clicked. However, nothing i ...

The Battle of Naming Styles in HTML and CSS: CamelCase versus Underscores

After reading numerous articles discussing the pros and cons of camelCase and Underscore naming conventions, I have always leaned towards camelCase due to its byte-saving nature. However, upon discovering BEM, I must admit that I am now in a state of conf ...

Ensure that a synchronous action is performed prior to each Backbone HTTP request

For each authenticated request (GET, POST, etc) in my Backbone/Marionette application, it is necessary to include an accessToken. The accessToken and expireDate are stored in the localStorage. To verify if the accessToken has expired, I utilize the metho ...

PHP handling AJAX request during execution of lengthy script

I recently posted a question on Stack Overflow where I received a satisfactory response that is working perfectly. However, I seem to be facing an issue where all AJAX requests stop functioning when the script runs for more than 4 to 5 seconds until the en ...

Is there a way to send a multi-dimensional array using jQuery ajax?

I am encountering an issue with posting an array as a JavaScript variable {{0,0},{1,1},{2,2}} using JSON.Stringify. Whenever I try to post it, I receive an internal server error 500. Can someone please advise on how I can successfully post and utilize this ...

Adjusting the line-height in CSS dynamically based on the length of characters using jQuery

I am facing an issue with the Twitter widget on my website where our company's latest tweet sometimes gets cut off if it exceeds a certain length. I want to dynamically adjust the line-height CSS property of the element based on the tweet's chara ...

What is the best way to send a POST request with parameters to a PHP backend using AJAX?

This is an updated version of a previous question that was identified as a duplicate (How can I send an AJAX POST request to PHP with parameters?) I am currently sending an AJAX request to a PHP backend. Here are the JavaScript functions used to make and ...