简体   繁体   中英

Get an element based on window position

What I'm trying to accomplish: When any element with the class "yes" is scrolled to a specific Y position in the window (we'll just pretend it's the very top of the window to keep it simple), I just want to get that element so I can grab some of its attributes.

<div class="container">
  <div class="no"></div>
  <div class="yes"></div>
  <div class="yes"></div>
  <div class="yes"></div>
  <div class="yes"></div>
  <div class="no"></div>
</div>

I've tried this two ways, and this first way works , but it seems terribly inefficient, as it's constantly have to assess the position all of the elements during scroll. There can be a lot. But maybe I'm overestimating how how inefficient it is?

Method 1:

$el = $('.yes');
$el.each(function(){
  var distance = $(this).offset().top;
  $window.scroll(function() {
    if ( $window.scrollTop() >= distance ) {
      // get the stuff
    }
  });
});

The other way seems more efficient (but maybe not?) but I haven't gotten it to work as needed:

$window.scroll(function(){
    var el = document.elementsFromPoint(0, 0);
    var $el = $(el);
    if($el.hasClass('yes')){
        //get the stuff
    }
});

This doesn't seem to be working correctly at all. Picks up some child elements ".yes" element, even if those elements don't have the "yes" class themselves, and also fails to pick up other ".yes" elements at all. I don't know why.

(Side note: I've simplified the code examples to remove other efficiencies, such as setTimeout for scrolling and tests to only perform functions if the element I'm trying to get changes, etc… I just need to figure out how to get position testing to work best).

I think what you're looking for is the intersection/observer API

<div class="container">
  <div class="no"></div>
  <div lang="javascript" class="yes"></div>
  <div class="no"></div>
  <div lang="python" class="yes"></div>
  <div class="no"></div>
  <div lang="go" class="yes"></div>
  <div class="no"></div>
  <div lang="rust" class="yes"></div>
  <div class="no"></div>
  <div class="end"><h1>HOORAY! YOU KNOW KNOW THE INTERSECTION OBSERVER API</h1>
    <a href="https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver" target="_new" rel="noopener">Read more about it here</a>
  </div>
</div>


<script>
let observer = new IntersectionObserver((divs, observer) => { 
    divs.forEach(div => {
        if(div.isIntersecting){
            //grab your attributes
            var _target = div.target
            let theAttr = _target.getAttribute("lang");
            console.log('div is intersecting with language attribute of: ' + theAttr);
            observer.unobserve(div.target);
        }
    });
    }, {threshold: 1});

document.querySelectorAll('div.container > div.yes').forEach(div => { observer.observe(div) });
 </script>
<style>
.container {height: 500vh;}
.no {background-color: #e87e7e;
height: 50vh;}
.yes {background-color: #00800478;
height: 50vh;}
.end{text-align: center;}
</style>

here is mozilla's documentation on the intersection/observer API .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM