Aram Mkrtchyan
Aram Mkrtchyan

Reputation: 2700

Jquery detect which block is visible on screen when scroll

Hi all I have some questions, if it's not hard please help.

If i have some count of div blocks

<div class="main">
      <div class="box block1"></div>
      <div class="box block2"></div>
      <div class="box block3"></div>
      <div class="box block4"></div>
</div> 

Ok now when you scroll and block visible on screen I need do something in that block I can do this with jquery every time when I scroll detect scroll top and check it with block offset-top but it bad solution because i need write many "if" to check it and it works when I have fixed count of block but i need that it will work dynamic. I find some plugins but I don't want use plugin. I was some basic easy script that i can change something or add or modify in other web sites

please help if you have some time to do that

it's my html

example

I do something in my portfolio page but it not dynamic and I write bad code :)

you can see it on menu when you scroll i add active class to menu if visible the block

portfolio

Upvotes: 0

Views: 5030

Answers (2)

Manoz
Manoz

Reputation: 6587

Try this

function isVisible( row, container ){
    
    var elementTop = $(row).offset().top,
        elementHeight = $(row).height(),
        containerTop = container.scrollTop(),
        containerHeight = container.height();
    
    return ((((elementTop - containerTop) + elementHeight) > 0) && ((elementTop - containerTop) < containerHeight));
}
$(window).scroll(function(){
  $('.main div').each(function(){
      if(isVisible($(this), $(window))){
      console.log($(this).attr('class')+" is visible");
      };  
  });
});
.main .box {
        position: relative;
        width: 100%;
    }
    .main .block1 {
        background: red;
        height: 800px;
    }
    .main .block2 {
        background: green;
        height: 600px;
    }
    .main .block3 {
        background: yellow;
        height: 900px;
    }
    .main .block4 {
        background: orange;
        height: 1000px;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
          <div class="box block1"></div>
          <div class="box block2"></div>
          <div class="box block3"></div>
          <div class="box block4"></div>
    </div>

On the console, You will note that only visible part of block elements is displayed!

And by default you get the part of displayed block by removing the scroll event.

Upvotes: 6

Timur Osadchiy
Timur Osadchiy

Reputation: 6209

// get top positions and references to all blocks
var pos = $(".box").map(function(){
  var $this = $(this);
  return {
    el: $this,
    top: $this.offset().top
  };
}).get();

var $result = $("#result-text");

// Set document scrolling event handler
$(document).on("scroll", function() {  
  var visible = [];
  var scrollStart = $(this).scrollTop();
  var scrollEnd = scrollStart+$(window).height();
  var vis=[];
  for (var i=0, l=pos.length; i<l; i++) {
    if (pos[i].top < scrollStart || pos[i].top > scrollEnd) { continue; }
    vis.push(pos[i].el.attr("class"));
  }
  $result.text("");
  $result.text(vis.join(", "));

}).scroll();
#result {
  background: #fff;
  border: 1px solid red;
  position: fixed;
  top: 0;
  left: 0;
}

.box {
  height: 200px;
  border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="result">You can see: <span id="result-text"></span></div>
<div class="main">
      <div class="box block1"></div>
      <div class="box block2"></div>
      <div class="box block3"></div>
      <div class="box block4"></div>
      <div class="box block5"></div>
      <div class="box block6"></div>
      <div class="box block7"></div>
      <div class="box block8"></div>
      <div class="box block9"></div>
      <div class="box block10"></div>
</div>

Upvotes: 1

Related Questions