Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

inverse scroll two divs

I am trying to inverse scroll two select controls. When I scroll down the first select the other one should scroll up. This is what I am currently doing

//scroll first list if second list is scrolled
$("#secondList").on("scroll", function(){    
    //alert("focused");
    $("#firstList").scrollTop($(this).scrollTop());
});

//scroll second list if first list is scrolled
$("#firstList").on("scroll", function(){
    $("#secondList").scrollTop($(this).scrollTop());
});

to start the second select box from bottom I am doing this

$("div #secondList").animate({ scrollTop: $("#2").height() }, "slow");

but it starts both selects from bottom. And my html is

<div class="container" style="margin-top: 50px;">
  <div id="1">
   <select name="color" id="firstList" size="3" class="form-control" ></select>
  </div>
  <div id="2">
    <select name="hex" size="3" id="secondList" class="form-control" style="margin-top: 50px;"></select>
  </div>
</div>

NOTE I am dynamically adding the options

$.getJSON("ColorNameMap.json", function(data){
    for (var i = 0, len = data.length; i < len; i++) {
        var color = data[i].color;
        var value = data[i].value;

        $("#firstList").append('<option value="'+value+'">'+color+'</option>');
        $("#secondList").append('<option value="'+color+'">'+value+'</option>');
    }
});

I can see the answers here but I want inverse scrolling. Please help me to proceed in right direction.

like image 430
Chaudhry Waqas Avatar asked Dec 15 '15 18:12

Chaudhry Waqas


Video Answer


1 Answers

One of the big challenges is getting the direction of the scroll - to get that, you need to record the current position and compare it to the last position.

Once you figure out which way the scrolling is going, you can add or subtract from the other scrollable area, depending on direction.

Below, I've assumed that $selects is always a set of two elements, and on load, I set the last one to be scrolled to the bottom (its scrollHeight). Then on scroll, I get the direction it was scrolling in (note that the first time the scroll handler is fired, we don't have a direction because we only have one data point - it's current position), and scroll the same amount in the opposite direction.

There is a slight trick (detailed in this question Updating scrollTop before scroll listener is assigned triggers a scroll event) regarding the requestAnimationFrame that I used here. Depending on your browser support you may need a polyfill.

(function() {
  // Start off scrolled to the bottom
  var $selects = $('select');
  $selects.last().scrollTop($selects.last().get(0).scrollHeight);

  var lastScroll = {
    whichEle: null,
    position: 0
  };
  
  // Wait until the scrollTop has applied itself (aka a repaint)
  window.requestAnimationFrame(function() {
    $selects.on('scroll', scrollOther);
  });
  
  function scrollOther() {
    var currPosition = $(this).scrollTop();

    if ($(this).is(lastScroll.whichEle)) {
      var positionDiff = currPosition - lastScroll.position;
     
      if(positionDiff === 0) { return; }

      var $other = $selects.not(this);
      
      $other.off('scroll'); // temporarily stop listening
      
      // Wait until the handler released itself (aka a repaint)
      window.requestAnimationFrame(function() {
        // Since scroll events happen so frequently, no need to animate (unless there's a debounce)
        $other.scrollTop($other.scrollTop() - positionDiff);
        
        // Wait until the scrollTop has applied itself (aka a repaint)
        window.requestAnimationFrame(function() {
          $other.on('scroll', scrollOther); // restart listening
        });
      });
      
      
      
      
    } else {
      // Just started scrolling a new div  
      lastScroll.whichEle = $(this);

      // Since there is no direction figured out yet, do nothing more than record for this event
    }

    lastScroll.position = currPosition;
  }
})();
select {
  width: 40%;
  margin: 0 5%;
  height: 75px;
  float: left;
  font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div id="1">
    <select name="color" id="firstList" size="3" class="form-control">
      <option>1 Lorem ipsum dolor</option>
      <option>2 sit amet, consectetur</option>
      <option>3 adipiscing elit</option>
      <option>4 Aenean venenatis lectus</option>
      <option>5 blandit, posuere eros ut</option>
      <option>6 condimentum nulla. Nulla facilisi</option>
      <option>7 Integer eget ex quis</option>
      <option>8 turpis ullamcorper vulputate</option>
      <option>9 eget a eros. Phasellus scelerisque</option>
    </select>
  </div>
  <div id="2">
    <select name="hex" size="3" id="secondList" class="form-control">
      <option>1 sit amet dignissim neque</option>
      <option>2 Suspendisse scelerisque</option>
      <option>3 vestibulum lacus</option>
      <option>4 eget tincidunt</option>
      <option>5 Phasellus aliquet</option>
      <option>6 leo eu purus sollicitudin</option>
      <option>7 semper quam ut ornare</option>
      <option>8 Nullam vitae mollis leo</option>
      <option>9 id hendrerit mi tristique</option>
    </select>
  </div>
</div>
like image 96
allicarn Avatar answered Nov 15 '22 00:11

allicarn