Rourke McLaren
Rourke McLaren

Reputation: 69

Built a scroll controller, need to reverse it

My code allows scrolling vertically in the bottom section to control scrolling horizontally in the top section.

My jsfiddle

You'll see the colors shift through a gradient. Works pretty well. Problem is that I can't quite seem to get the inverse to work. Scrolling horizontally in the top controls scrolling in the bottom.

Any ideas?

Here's the script that makes it work:

// Add event listener for scrolling
$("#bottom").on("scroll", function bottomScroll() {
    var scrolledleft = parseInt($("#bottom").scrollTop()) * 1;
    console.log(scrolledleft + scrolledright)
    $("#top").scrollLeft(scrolledleft + scrolledright)
})

//Move right column to bottom initially
$("#top").scrollLeft($("#top").height())

//Get actual distance scrolled
var scrolledright = parseInt($("#top").scrollLeft())

Upvotes: 1

Views: 622

Answers (3)

DDave
DDave

Reputation: 618

Scroll to left ::

$('div').scrollLeft(1000);

Scroll back to normal/ scroll to right ::

$('div.slick-viewport').scrollLeft(-1000);

Upvotes: 0

James
James

Reputation: 22247

Your event handlers need to temporarily cancel each other so that they don't both fire at once. You want to calculate your position percentage based on the current scrollLeft / (width of child div - width of container), then apply that percentage to the other element, and likewise for top/height. Also I changed the height of #top to 50% in CSS.

var handler = function (e) {
  var src = e.target;
  
  // the first element that triggers this function becomes the active one, until it's done
  if (!activeScroller) activeScroller = src.id;
  else if (activeScroller != src.id) return;
  
  var $b = $("#bottom");
  var $t = $("#top");

  var scrollH = $("#bottom-content").height() - $b.height();
  var scrollW = $("#top-content").width() - $t.width();

  var scrollPct = 0;

  if (src.id == "top") {
    if (scrollW > 0) {
      scrollPct = $t.scrollLeft() / scrollW;
    }

    $b.scrollTop(scrollH * scrollPct);
  } else {
    if (scrollH > 0) {
      scrollPct = $b.scrollTop() / scrollH;
    }

    $t.scrollLeft(scrollW * scrollPct);
  }
  
  // give all animations a chance to finish
  setTimeout(function () { activeScroller = ""; }, 100);
};
var activeScroller = "";
$("#top,#bottom").on("scroll", handler);
#top {
  position: absolute;
  margin: auto;
  top: 0;
  right: 0;
  left: 0;
  width: 100%;
  height: 50%;
  position: fixed;
  overflow: auto;
  background: red;
}

#top-content {
  height: 100%;
  width: 2000px;
  background: linear-gradient(90deg, red, blue);
}

#bottom {
  position: absolute;
  margin: auto;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 50%;
  position: fixed;
  overflow: auto;
  background: green;
  z-index: 100;
}

#bottom-content {
  height: 2000px;
  width: 100%;
  background: linear-gradient(0deg, orange, green);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="top">
  <div id="top-content"></div>
</div>
<div id="bottom">
    <div id="bottom-content"></div>
</div>

Upvotes: 1

Steve Seeger
Steve Seeger

Reputation: 1477

Check out this: https://jsfiddle.net/1p7gp72h/1/

I'm not sure what your end goal is here.

$("#top").on("scroll", function topScroll() {
    var scrolledleft = parseInt($("#top").scrollTop()) * 1;

    $("#bottom").scrollLeft(scrolledleft + scrolledright)
});

#top {
  top: 0;
  right: 0;
  left: 0;
  width: 5000px;
  height: 100%;

  overflow: auto;
  background: red;
  overflow-x: scroll;
  overflow-y: hidden;
  white-space:nowrap;
}

Upvotes: 0

Related Questions