skip to Main Content

Is there a way I could refactor the below code so it doesn’t matter how many elements with ID there is? This is what I’ve got so far.

$(window).scroll(function(){;
   top = Math.floor( $(window).scrollTop() );  
   
   if(top<=$('#div-1').offset().top) {
       var value = $('#div-1').attr('data-value');
       console.log(value);

   } else if(top<=$('#div-2').offset().top) {
       var value = $('#div-2').attr('data-value');
       console.log(value); 
   
   } else if(top<=$('#div-3').offset().top) {
       var value = $('#div-3').attr('data-value');
       console.log(value);

   } else if(top<=$('#div-4').offset().top) {
       var value = $('#div-4').attr('data-value');
       console.log(value);
   }
}); 

4

Answers


  1. I think you can do

    $(window).scroll(function(){
        $('[id^="div-"]').each(function() { 
           let curr = $(this);
           if(top<=curr.offset().top) {
               console.log(curr.attr('data-id'));
               return false;
           } 
        })
    })
    

    I didn’t check if your code works nor didn’t try to improve it. Just refactored it to be the same as your functionality.

    Login or Signup to reply.
  2. To achieve this you could put the same class on all the div elements. Then you can use a loop in your jQuery logic to determine which are below the current scroll position.

    Also note the use of data() in the following example to retrieve the data-* attribute instead of attr()

    const $divs = $('.scroll-demo');
    
    $(window).scroll(function() {;
      const top = Math.floor($(this).scrollTop());
    
      $divs.each(i => {
        const $div = $divs.eq(i);
        if (top <= $div.offset().top) {
          let value = $div.data('value');
          console.log(value);
        }
      });
    });
    .scroll-demo {
      height: 1000px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="scroll-demo" data-value="1">Foo</div>
    <div class="scroll-demo" data-value="2">Bar</div>
    <div class="scroll-demo" data-value="3">Fizz</div>
    <div class="scroll-demo" data-value="4">Buzz</div>
    Login or Signup to reply.
  3. You can create a common class and keep iterating until you find what meets your condition and then attribute it.

    $(window).scroll(function() {
       var top = Math.floor($(window).scrollTop());
       var foundEle = false;
       $('[class^="div-"]').each(function() {
          var $this = $(this);
          if (top <= $this.offset().top && !foundEle) {
             var value = $this.attr('data-di');    
             foundEle = true;
             return false;
          }
       });
    });
    
    Login or Signup to reply.
  4. If the page is not dynamically generated.
    I haven’t run the code specifically, there may be a problem

    const obj = {};
    $('[id^="div-"]').each(function () {
        let curr = $(this);
        obj[curr.offset().top] = curr; //() => curr.attr("data-value");
    });
    const sortKeys = Object.keys(obj).sort((a, b) => b - a);
    
    $(window).scroll(function () {
        top = Math.floor($(window).scrollTop());
    
        for (let i = 0; i < sortKeys.length; i++) {
            const currDom = obj[sortKeys[i]]();
            const currHeight = currDom.height();
            const currTop = sortKeys[i];
            if (top >= currTop && top < currTop + currHeight) {
                console.log(currDom.attr("data-value"));
                return;
            }
        }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search