jQuery Add Remove Class on Scroll

Hi all,

My situation is:

I have added some jQuery code on this page to add and remove classes when the vertical scroll gets to a certain amount of pixels.

What I wanted to do was add a class to a div but remove it when the next div is active but the coding I have doesn’t exactly do that (well it kind of does).

When a user reaches the bottom of the page and scrolls back to the top, the classes are added again. Is there a way I can turn off classes for good?

I hope I explained that clearly.

Code I am currently using:

$(window).scroll(function() {    
    var scroll = $(window).scrollTop();
	if (scroll >= 100 && scroll < 269) {
        $("#left1").addClass("blue1", 1000);
		$("#cLeft1").addClass("blue2", 1000);
    }
	if (scroll >= 270 && scroll <= 439) {
        $("#right1").addClass("blue1", 1000);
		$("#cRight1").addClass("blue2", 1000);
		$("#left1").removeClass("blue1", 1000);
		$("#cLeft1").removeClass("blue2", 1000);
    }
	if (scroll >= 440 && scroll <= 589) {
        $("#left2").addClass("blue1", 1000);
		$("#cLeft2").addClass("blue2", 1000);
		$("#right1").removeClass("blue1", 1000);
		$("#cRight1").removeClass("blue2", 1000);
    }
	if (scroll >= 590 && scroll <= 739) {
        $("#right2").addClass("blue1", 1000);
		$("#cRight2").addClass("blue2", 1000);
		$("#left2").removeClass("blue1", 1000);
		$("#cLeft2").removeClass("blue2", 1000);
    }
	if (scroll >= 740 && scroll <= 889) {
        $("#left3").addClass("blue1", 1000);
		$("#cLeft3").addClass("blue2", 1000);
		$("#right2").removeClass("blue1", 1000);
		$("#cRight2").removeClass("blue2", 1000);
    }
	if (scroll >= 890 && scroll <= 1039) {
        $("#right3").addClass("blue1", 1000);
		$("#cRight3").addClass("blue2", 1000);
		$("#left3").removeClass("blue1", 1000);
		$("#cLeft3").removeClass("blue2", 1000);
    }
	if (scroll >= 1040 && scroll <= 1189) {
        $("#left4").addClass("blue1", 1000);
		$("#cLeft4").addClass("blue2", 1000);
		$("#right3").removeClass("blue1", 1000);
		$("#cRight3").removeClass("blue2", 1000);
    }
	if (scroll >= 1190 && scroll <= 1339) {
        $("#right4").addClass("blue1", 1000);
		$("#cRight4").addClass("blue2", 1000);
		$("#left4").removeClass("blue1", 1000);
		$("#cLeft4").removeClass("blue2", 1000);
    }
});

<div id="left1">
				<h2>Deliver WOW Through Service</h2>
				
				<div id="cLeft1">
					<p>1</p>
				</div>
			</div>
			<div id="right1">
				<h2>Embrace and Drive Change</h2>
				<div id="cRight1">
					<p>2</p>
				</div>
			</div>
			<div id="left2">
				<h2>Create Fun and A Little Weirdness</h2>
				<div id="cLeft2">
					<p>3</p>
				</div>
			</div>
			<div id="right2">
				<h2>Be Adventurous, Creative, and Open-Minded</h2>
				<div id="cRight2">
					<p>4</p>
				</div>
			</div>
			<div id="left3">
				<h2>Pursue Growth and Learning</h2>
				<div id="cLeft3">
					<p>5</p>
				</div>
			</div>
			<div id="right3">
				<h2>Build Open and Honest Relationships With Communication</h2>
				<div id="cRight3">
					<p>6</p>
				</div>
			</div>
			<div id="left4">
				<h2>Build a Positive Team and Family Spirit</h2>
				<div id="cLeft4">
					<p>7</p>
				</div>
			</div>
			<div id="right4">
				<h2>Do More With Less</h2>
				<div id="cRight4">
					<p>8</p>
				</div>
			</div>

I don’t know too much about jQuery so let me know if there is a better / short way to code this up.

Cheers.

Al.

Hi there,

I approached this from a different angle.
I defined a vertical area on the screen (say from 100px to 300px) and said that when a user scrolls the page, any div that is within area has the appropriate class applied to it.
Conversely, any div outside that area has the appropriate class removed (if present).

It is actually quite a tricky thing you are trying to do, especially as you are animating the application of the class (the blue fade-in / fade-out effect).
This means that the animation can still be being applied when the element is outside of the appropriate area on the screen.

Anyway, this is my attempt. I hope it helps:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Core Values | webmakers</title>
    <meta charset=utf-8>
    <base href="http://webmakers.ie/" />
    <link href="/css/main.css" rel="stylesheet" />
  </head>
  
  <body id="coreValuesTest">
    <div id="wrapper">
      <header>
        <div id="headerContent">
          <div id="logo">
            <a href="/index.php" title="webmakers Home"><img src="/img/logos/webmakers-logo.png" alt="webmakers Logo" /></a>
          </div><!-- /logo -->
          <nav>
            <ul>
              <li class="on"><a href="/core-values/index.php" title="webmakers Core Values">Core Values</a></li>
              <li><a href="/clients/index.php" title="webmakers Clients">Clients</a></li>
              <li><a href="/services/index.php" title="webmakers Services">Services</a></li>
              <li><a href="/contact/index.php" title="Contact webmakers">Contact</a></li>
            </ul>
          </nav><!-- /nav -->
        </div><!-- /headerContent -->
      </header><!-- /header -->
      <div id="subIntro">
        <div id="subIntroContent">
          <h1 class="left">Core Values</h1>
          <p>Our clients have a vision they are passionate about. They require inspiring responsive design, a rewarding end-user experience, robust development and engaging content. The 4 supporting pillars of our work are communication, design, development and implementation.</p>
        </div><!-- /subIntroContent -->
      </div><!-- /subIntro -->
      <div id="mainCoreValues">
          <div id="mainContent">
          <div id="left1">
            <h2>Deliver WOW Through Service</h2>
            
            <div id="cLeft1">
              <p>1</p>
            </div>
          </div>
          <div id="right1">
            <h2>Embrace and Drive Change</h2>
            <div id="cRight1">
              <p>2</p>
            </div>
          </div>
          <div id="left2">
            <h2>Create Fun and A Little Weirdness</h2>
            <div id="cLeft2">
              <p>3</p>
            </div>
          </div>
          <div id="right2">
            <h2>Be Adventurous, Creative, and Open-Minded</h2>
            <div id="cRight2">
              <p>4</p>
            </div>
          </div>
          <div id="left3">
            <h2>Pursue Growth and Learning</h2>
            <div id="cLeft3">
              <p>5</p>
            </div>
          </div>
          <div id="right3">
            <h2>Build Open and Honest Relationships With Communication</h2>
            <div id="cRight3">
              <p>6</p>
            </div>
          </div>
          <div id="left4">
            <h2>Build a Positive Team and Family Spirit</h2>
            <div id="cLeft4">
              <p>7</p>
            </div>
          </div>
          <div id="right4">
            <h2>Do More With Less</h2>
            <div id="cRight4">
              <p>8</p>
            </div>
          </div>
        </div><!-- /mainContent -->
      </div><!-- /mainCoreValues -->
      <div id="workWithUs">
        <div id="workWithUsContent">
          <h1>We'd Love To Work With You</h1>
          <p class="button"><a href="/contact/index.php">Tell Us About Your Project</a></p>
        </div><!-- /workWithUsContent -->
      </div><!-- /workWithUs -->  <div id="contactDetails">
        <div id="contactDetailsContent">
          <h1>Contact Details</h1>
          <div id="mapCanvas">
          </div><!-- /mapCanvas -->
          <div id="details">
            <p><span>Call us on:</span><br /> +353 (0)46 902 1723</p>
            <p><span>Or email us at:</span><br /> <a href="mailto:hello@webmakers.ie?Subject=Enquiry%20From%20Webmakers%20Site">hello@webmakers.ie</a></p>
            <p><span>Address:</span><br /> Unit 38 Navan Enterprise Centre,<br /> Trim Road,<br /> Navan,<br /> Co. Meath,<br /> Ireland.</p>
            <ul>
              <li class="facebook"><a href="https://www.facebook.com/wearewebmakers" title="Like webmakers on Facebook" target="_blank"></a></li>
              <li class="twitter"><a href="https://twitter.com/wearewebmakers" title="Follow webmakers on Twitter" target="_blank"></a></li>
              <li class="googlePlus"><a href="#" title="Plus1 webmakers on Google+" target="_blank"></a></li>
              <li class="linkedIn"><a href="#" title="Join webmakers on LinkedIn" target="_blank"></a></li>
              <li class="email"><a href="mailto:hello@webmakers.ie?Subject=Enquiry%20From%20webmakers%20Website" title="Send webmakers an email" target="_blank"></a></li>
            </ul>    
          </div>
        </div><!-- /contactDetailsContent -->
      </div><!-- /contactDetails -->
      <footer>
        <div id="footerContent">
        </div><!-- /footerContent -->
      </footer><!-- /footer -->
    </div><!-- /wrapper -->
       
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
    <script>
      (function(){
        var $elements = $("div").filter(function() {
                return this.id.match(/right|left/);
            }),
            HIGHLIGHT_AREA_TOP = 100,
            HIGHLIGHT_AREA_BOTTOM = 300,
            timer;
            
        String.prototype.capitalize = function() {
          return this.charAt(0).toUpperCase() + this.slice(1);
        }  
                
        function getAssosciatedElement(el){
          var id = el.get(0).id
          return $("#c" + id.capitalize());
        }
            
        function addHighlight(el){
          el.addClass("blue1", 250);
          getAssosciatedElement(el).addClass("blue2", 250);
        }
        
        function removeHighlight(el){
          el.removeClass("blue1", 250);
          getAssosciatedElement(el).removeClass("blue2", 250);
        }
            
        function checkElementsToHighlight(){
          $elements.each(function(){
            var pos = $(this).offset().top - $(window).scrollTop();
             if(pos > HIGHLIGHT_AREA_TOP && pos < HIGHLIGHT_AREA_BOTTOM){
               // Element top is within highlight area
               if(!$(this).hasClass("blue1")){
                 addHighlight($(this));
               }
             } else {
               if ($(this).hasClass("blue1")){
                 removeHighlight($(this)); 
               }
             }
          });
        }
        
        $(window).on("scroll", function(){
          clearTimeout(timer);
          checkElementsToHighlight();
          timer = setTimeout(checkElementsToHighlight, 350);
        });
      })();
    </script>
  </body>
</html>

Also, here’s a demo.

Thanks very much for the reply - Looking at your demo it seems to be much better than what I have in place and pretty much what I am looking for - thanks for your help!

Hey Pullo, wonder if you could help me with this issue I am having.

I get an undefined variable error when I add your code to my php file.

I can post the error is it helps?

Cheers,
Al.

Hi Al, is it the same site you link to above?

Hi Pullo, yes it is - here is the link

You might need to see more code, as I am pulling in the sections (eg head, nav, footer…) of the site from a single php file.

Thanks.
When I visit that page, the first thing I see is:

Notice: Undefined variable: elements in /usr/local/pem/vhosts/236304/webspace/httpdocs/webmakers.ie/core-values/index.php on line 56 Notice: Undefined variable: elements in /usr/local/pem/vhosts/236304/webspace/httpdocs/webmakers.ie/core-values/index.php on line 80

You might want to sort that out.

Then in the console I see:

Uncaught SyntaxError: Unexpected token = index.php:94

This is being caused by this line:

var  = $("div").filter(function() {

which should be:

var  $elements = $("div").filter(function() {

Not really, as PHP is interpreted on the server. We are only interested in what is delivered to the browser here.

Hope that helps.

Thanks for the reply Pullo.

I have display errors set to on - usually have it on until the site goes live - which is why the error message is displayed at the top.

I had a look in the code (in Dreamweaver) and that line looks fine, but when I look at the source it’s how you pointed out above. Any ideas on this?

Attached is a screenshot of what I am seeing in Dreamweaver.

Very baffling.
The only thing I can suggest is deleting the offending file from the server (clearing your browser’s cache for good measure), then re-uploading the file in question.

I’ve just deleted that file from the server, cleared my cache and cookies and have re-uploaded the file again.

Still no luck.

I forgot to mention that I had tried it out on an html page, like you had done with your demo and it is working fine - LINK

So that’s what got me thinking it might have something to do with PHP I am using. I will have a look and see if I can see anything.

Really appreciate all your help Pullo.

Hi,

No problem :slight_smile:

So, you’re telling me that you have a file on your PC. It works on your PC, but when you upload it to your server, part of it is missing / gets stripped out?
That’s weird!

You might need to see more code, as I am pulling in the sections (eg head, nav, footer…) of the site from a single php file.

Maybe this is a good after all.

That kind of seems to be the case alright.

I had copied your demo page, saved it as a .html file and it worked locally. Then saved it as a .php file and uploaded it to the server, it also worked, but then when I extracted the jQuery code and added it to the development page it doesn’t work and I get those errors.

I have sent you a PM with the code from the 2 main files involved.

Hi Allan,

Did you get to the bottom of this?
I looked at the PHP file you sent me by PM and it didn’t include my script.
However, if you are including it in the same way that you are including the Google Maps script, then there is no reason it should behave this way and there must be another reason.

Hi Pullo,

Still haven’t found out why it’s not working yet. I must not have included the the file with your code in, but it would have been added just below the Google Maps code within <script> tags.
I have been quite busy over the last week and working on other parts of the site, so I will concentrate more now on trying to solve this.

Cheers.

Hey Pullo,

I was messing around with the code last night, as in moving code around the page and from it trying to eliminate what was causing the issue - I still don’t know why it wasn’t working but currently I have a test page with my php include file added and all is working. It was a quick solution so I need to clean up the code a bit, so I’ll let you know when I have done that.

Thanks for your help!

Hey Pullo,

I was looking at that page again today and found that this is the reason why it is not working:

When I wrap
PHP Code:

<?php ?>

around the jquery code it’s fine but if I change it to
PHP Code:

echo <<<HTML HTML; 

it doesn’t work.

I don’t know a whole lot about PHP so I wouldn’t have a clue why this would be.

Oh and also, would you be able to tell me how to change the speed of the jQuery animation?

Cheers.
Al.

The echo <<<HTML HTML; is a heredoc.
It could be the case that it is objecting to the dollar sign at the front of the variable $elements, mistaking it for a PHP variable and stripping it out.

In PHP (AFAIK) all variables are prefixed with a dollar sign, whereas in JavaScript the leading dollar denotes a collection of jQuery objects.
Just out of interest try changing:

var  $elements = $("div").filter(function() { .. }

to

var  elements = $("div").filter(function() { .. }

and seeing if that makes a difference.
You’ll have to change the offending variable it elsewhere in the script, too.

Sure, it’s the second parameter here (250), measured in milliseconds:

function addHighlight(el){
  el.addClass("blue1", 250);
  getAssosciatedElement(el).addClass("blue2", 250);
}
        
function removeHighlight(el){
  el.removeClass("blue1", 250);
  getAssosciatedElement(el).removeClass("blue2", 250);
}

HTH

Hey Pullo,

I have added the heredoc tags back in and removed the dollar signs from the beginning of ‘elements’ (in 2 places) and it’s working now. I really thought I had tried that before…

Thanks for all your help, much appreciated!