最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get the element closer to the middle of the screen in jQuery - Stack Overflow

programmeradmin2浏览0评论

I have a list of item divs in the page.

example:

<div data-page='1' class'item' ></div>
<div data-page='1' class'item' ></div>
<div data-page='1' class'item' ></div>
<div data-page='2' class'item' ></div>
<div data-page='2' class'item' ></div>
<div data-page='2' class'item' ></div>
<div data-page='3' class'item' ></div>
<div data-page='3' class'item' ></div>
<div data-page='3' class'item' ></div>

I need to find out the element that is in the most center part of the screen and get its data-page number.

If all the div are close to the button of the page or not visible because its down the page, I get the top most one because it's closer to the middle, and if all the div are above the middle or not visible because they are at the upper part of the window outside the visible view, I get the bottom most div because it's closer to the middle.

What I've tried (source):

$(".item").sort(function(a,b){
      return Math.abs(1 - (($(window).scrollTop()+$(window).height()/2-$(a).height()/2) / $(a).position().top)) - 
             Math.abs(1 - (($(window).scrollTop()+$(window).height()/2-$(b).height()/2) / $(b).position().top))
    })[0].css("background", "red");

The above function didn't work for me, because it highlighted in red a bottom most element.

How can I do that in jQuery and also continuously report the closest one as I vertically scroll the page.

I have a list of item divs in the page.

example:

<div data-page='1' class'item' ></div>
<div data-page='1' class'item' ></div>
<div data-page='1' class'item' ></div>
<div data-page='2' class'item' ></div>
<div data-page='2' class'item' ></div>
<div data-page='2' class'item' ></div>
<div data-page='3' class'item' ></div>
<div data-page='3' class'item' ></div>
<div data-page='3' class'item' ></div>

I need to find out the element that is in the most center part of the screen and get its data-page number.

If all the div are close to the button of the page or not visible because its down the page, I get the top most one because it's closer to the middle, and if all the div are above the middle or not visible because they are at the upper part of the window outside the visible view, I get the bottom most div because it's closer to the middle.

What I've tried (source):

$(".item").sort(function(a,b){
      return Math.abs(1 - (($(window).scrollTop()+$(window).height()/2-$(a).height()/2) / $(a).position().top)) - 
             Math.abs(1 - (($(window).scrollTop()+$(window).height()/2-$(b).height()/2) / $(b).position().top))
    })[0].css("background", "red");

The above function didn't work for me, because it highlighted in red a bottom most element.

How can I do that in jQuery and also continuously report the closest one as I vertically scroll the page.

Share Improve this question edited May 23, 2017 at 12:16 CommunityBot 11 silver badge asked Jul 25, 2016 at 9:30 Liron HarelLiron Harel 11.2k27 gold badges123 silver badges223 bronze badges 3
  • Can you please explain more ? – Sunil Kumar Commented Jul 25, 2016 at 9:41
  • @SunilKumar There are DIVs arranged one of top of the other vertically. I want to get the element that is in the most middle part of the screen. – Liron Harel Commented Jul 25, 2016 at 9:43
  • you can try this link jsfiddle/adminsunil/2L92c7ww – Sunil Kumar Commented Jul 25, 2016 at 10:02
Add a ment  | 

3 Answers 3

Reset to default 5

On the scroll event, you can get the middle of the sreen and then loop the elements you want to check and get each of their positions and find which is closest to the middle of the screen

 $(function(){
    $(window).scroll(function(){        
        // get the scroll position of the document + half the window height
        var scrollTop = $(document).scrollTop() + ($(window).height() / 2);
        var positions = [];

        // push each of the items we want to check against to an array with their position and selector
        $('.item').each(function(){
            $(this).removeClass("active");
            positions.push({position:$(this).position().top, element: $(this)});
        });

        var getClosest = closest(positions,scrollTop);
        getClosest.addClass("active"); // the element closest to the middle of the screen
        console.log( getClosest.attr("data-page") );
    });

    // finds the nearest position (from an array of objects) to the specified number
    function closest(array, number) {
        var num = 0;
        for (var i = array.length - 1; i >= 0; i--) {
            if(Math.abs(number - array[i].position) < Math.abs(number - array[num].position)){
                num = i;
            }
        }
        return array[num].element;
    }        
});

Here is a working example

you can use document.elementFromPoint giving it the x and y coordinates of the middle of the screen

document.addEventListener("scroll", function(){
  let x = window.innerWidth / 2;
  let y = window.innerHeight / 2;
  let element = document.elementFromPoint(x, y);
  let page = element.getAttribute("data-page");
  document.querySelector(".middle") &&   document.querySelector(".middle").classList.remove("middle");
  element.classList.add("middle"); 
})

read more about document.elementFromPoint

here is a Codepen example

In case anyone else runs into this sometime later, building on @[Idan Schechter][1]'s response, I thought I would show the change that he found. (Full credit to him). I couldn't ment so am adding as a plete answer here:

    $(function(){
    $(window).scroll(function(){        
        // get the scroll position of the document + half the window height
        var scrollTop = $(document).scrollTop() + ($(window).height() / 2);
        var positions = [];

        // push each of the items we want to check against to an array with their position and selector
        $('.item').each(function(){
            $(this).removeClass("active");
            positions.push({position:$(this).offset().top, element: $(this)});
        });

        var getClosest = closest(positions,scrollTop);
        getClosest.addClass("active"); // the element closest to the middle of the screen
        console.log( getClosest.attr("data-page") );
    });

    // finds the nearest position (from an array of objects) to the specified number
    function closest(array, number) {
        var num = 0;
        for (var i = array.length - 1; i >= 0; i--) {
            if(Math.abs(number - array[i].position) < Math.abs(number - array[num].position)){
                num = i;
            }
        }
        return array[num].element;
    }
});

The big change is to change the position in the main function to offset. That was what helped the function do what I needed.

发布评论

评论列表(0)

  1. 暂无评论