14

Please tell me how can I make this in the most right way.

HTML:

<div id="fixed-red" class="fixed-red"></div>
<div id="fixed-green" class="fixed-green"></div>
<div id="fixed-blue" class="fixed-blue"></div>
<div id="red" class="red"></div>
<div id="green" class="green"></div>
<div id="blue" class="blue"></div>

CSS:

html,body{
  height:100%;
}
.fixed-red,.fixed-green,.fixed-blue{
  width:30px;
  height:30px;
  position:fixed;
  top:10px;
  left:10px;
  background:#333;
}
.fixed-green{
  top:50px;
}
.fixed-blue{
  top:90px;
}
.red-active{
  background:#f00;
}
.green-active{
  background:#0f0;
}
.blue-active{
  background:#00f;
}
.red,.green,.blue{
  width:100%;
  height:100%;
}
.red{
  background:#900;
}
.green{
  background:#090;
}
.blue{
  background:#009;
}

I want to add/remove red/green/blue-active class to the fixed-red/green/blue divs when the user is on/off the red, green, or blue divs(when they are visible), so the small divs would be respectively highlighted with the color of the big, display divs when the user is on them.

Thanks!

user7362793
  • 161
  • 1
  • 4
  • I thought of adding event `on`, on the `red`, `green`, and `blue` big divs, but I don't know how to check if they are visible – user7362793 Jan 01 '17 at 16:26
  • For modern browsers, see - https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport – user305883 Sep 16 '18 at 18:43

1 Answers1

21

I had to tweak the code a little so the code could be more D.R.Y. The classes are now replaced by color class.

$.fn.isInViewport = function() {
  var elementTop = $(this).offset().top;
  var elementBottom = elementTop + $(this).outerHeight();

  var viewportTop = $(window).scrollTop();
  var viewportBottom = viewportTop + $(window).height();

  return elementBottom > viewportTop && elementTop < viewportBottom;
};

$(window).on('resize scroll', function() {
  $('.color').each(function() {
      var activeColor = $(this).attr('id');
    if ($(this).isInViewport()) {
      $('#fixed-' + activeColor).addClass(activeColor + '-active');
    } else {
      $('#fixed-' + activeColor).removeClass(activeColor + '-active');
    }
  });
});
html,
body {
  height: 100%;
}

.fixed-red,
.fixed-green,
.fixed-blue {
  width: 30px;
  height: 30px;
  position: fixed;
  top: 10px;
  left: 10px;
  background: #333;
}

.fixed-green {
  top: 50px;
}

.fixed-blue {
  top: 90px;
}

.red-active {
  background: #f00;
}

.green-active {
  background: #0f0;
}

.blue-active {
  background: #00f;
}

.color {
  width: 100%;
  height: 100%;
}

#red {
  background: #900;
}

#green {
  background: #090;
}

#blue {
  background: #009;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fixed-red" class="fixed-red red-active"></div>
<div id="fixed-green" class="fixed-green"></div>
<div id="fixed-blue" class="fixed-blue"></div>
<div id="red" class="color"></div>
<div id="green" class="color"></div>
<div id="blue" class="color"></div>

Here is a working fiddle of that

https://jsfiddle.net/BoyWithSilverWings/ds9x55z7/

Agney
  • 18,522
  • 7
  • 57
  • 75
  • Thank you for your answer, but I doubt people use `hover` for this kind of things – user7362793 Jan 01 '17 at 16:49
  • I guess you can use `mouseenter mouseleave` events. U can see a sample of that https://jsfiddle.net/BoyWithSilverWings/ds9x55z7/1/ (But that is indeed the hover function) – Agney Jan 01 '17 at 16:57
  • Thanks, but again, I don't think this is done this way(using mouse). I can think of `scrollTop`, to check the height of the elements, but not sure if this is right approach and how to make this – user7362793 Jan 01 '17 at 17:14
  • I think you might be referring to http://stackoverflow.com/a/33979503/4374566 – Agney Jan 01 '17 at 17:29
  • If I were to borrow some code, your case might look like https://jsfiddle.net/BoyWithSilverWings/ds9x55z7/ – Agney Jan 01 '17 at 17:43
  • Thanks a lot, Boy with silver wings! – user7362793 Jan 01 '17 at 18:06
  • Happy to Help @user7362793 :) – Agney Jan 01 '17 at 18:07