【问题标题】:Custom horizontal scrollbar logic自定义水平滚动条逻辑
【发布时间】:2015-01-25 12:39:30
【问题描述】:

我基于 TweenMax 缓动和 jQuery 鼠标滚轮事件制作了一个自定义 div 滚动条。滚动就像一个魅力,但我需要移动滚动条处理程序来显示滚动进度。我根据父宽度、scrollLeft 和总 div 宽度的计算做了一些测试,但没有找到正确的解决方案……
I tried 为我的水平滚动条调整this example,但这仍然是一种奇怪的行为。 有什么想法吗?

$(window).on("mousewheel DOMMouseScroll", function (e) {
    e.preventDefault();
    var delta = e.originalEvent.wheelDelta / 120 /* Chrome */ || -e.originalEvent.detail; /* FF */
    var dur = 1.2;
    TweenLite.to($("#photos"), dur, {
        scrollLeft: $("#photos").scrollLeft() - parseInt(delta * 35),
        ease: Expo.easeOut,
        overwrite: 5
    });
});

现场示例:
http://jsfiddle.net/tccsq6e9/2/

【问题讨论】:

  • 您的handle 的宽度为 12%。为什么?宽度应与正确的比例匹配,并且还应在调整窗口大小时计算,因为 #photos 的 scrollWidth 会发生变化。
  • @RokoC.Buljan 绝对不是,12% 只是样式选择。我只想移动那个滚动条处理程序。
  • 哦,知道了,所以它总是“固定”在 12% 的宽度。无论如何,在调整窗口大小时,您需要重新计算处理程序宽度和区域滚动宽度比率,以使其在#photos 到达远端滚动条时始终到达远端滚动条。
  • @RokoC.Buljan 就是这样! / 没有保留。那是行不通的,而且很麻烦……:/
  • @RokoC.Buljan 从 Time Machine 备份中恢复了它:jsfiddle.net/tccsq6e9/3 — 如您所见,计算量很大,并且边缘没有限制。我在online example 上找到了垂直滚动条的代码。

标签: javascript jquery scrollbar gsap


【解决方案1】:

jsBin demo

(P.S:使用 Tween onUpdate callback function 在画廊滚动上移动处理程序)

逻辑:

//     How much available scroll-space** have our elements:
//
//     |--$element--|<---------------avail scroll space--------------->|
//     |<------------------------total width-------------------------->|
//
//     Same logic goes for both elements:

galleryAvailScroll =  $gallery[0].scrollWidth - $gallery.outerWidth(true);
handlerAvailScroll =  $scrollbar.width() - $handler.width();

//     On $gallery scroll, how to move the $handler to the proper left position?

handlerLeft = $gallery.scrollLeft() * handlerAvailScroll / galleryAvailScroll; // left PX

就是这样。在滚动和窗口调整大小上进行数学运算,以使处理程序像真正的滚动条一样:

这是简化 CSS、HTML 和 JS 的最终结果

var $gallery   = $("#thumbs"),
    $scrollbar = $("#scrollbar"),
    $handler   = $("#scrollbar-handle"),
    galleryAvailScroll = 0,
    handlerAvailScroll = 0,
    handlerLeft = 0;

function setPos() {
  galleryAvailScroll = $gallery[0].scrollWidth - $gallery.outerWidth(true); // PX
  handlerAvailScroll = $scrollbar.width() - $handler.width(); // PX
  handlerLeft = $gallery.scrollLeft() * handlerAvailScroll / galleryAvailScroll;
  $handler.css({left: handlerLeft});
}
setPos(); // Get the sizes
$(window).on("resize", setPos); // Also on resize

// Scroll
$gallery.on("mousewheel DOMMouseScroll", function (e) {
  e.preventDefault();
  var eorg  = e.originalEvent,
      delta = eorg.wheelDelta/120 || -eorg.detail; // Ch || FF
  
  TweenLite.to( $gallery, 0.7, {
    scrollLeft : $gallery.scrollLeft() - delta * 35,
    ease : Expo.easeOut,
    overwrite : 5,
    onUpdate : setPos
  });
  
});
body {
  padding: 15px 0 0;
  margin: 0;
}
#thumbs {
  position:relative;
  overflow:hidden;
  padding:0 10px;
  height: 175px;
  white-space: nowrap;
}
#thumbs > div {
  font-size:16px;
  display:inline-block;
  width: 150px; height: 150px;
  margin: 0 6px; /*6 + 4 LineWidth = 10 */
  background:#000;
}
#scrollbar {
  margin:0 70px;
  height:3px;
  position:relative;
  background:#ddd;
}
#scrollbar-handle {
  position:absolute;
  width:12%;
  left:0;
  height:3px;
  background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<div id="thumbs">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div id="scrollbar">
  <span id="scrollbar-handle"></span>
</div>

由于您的处理程序“固定”在 12% 宽度,如果您决定使其宽度与内容相关,您可以从 How to make custom scrollbar jQuery plugin 获得所需的数学运算

【讨论】:

  • 该死,你就是那个男人!不知道可以使用该 onUpdate 回调来移动滚动条指示器。非常感谢您的帮助:)
  • 我只是在我的实际设计中修改了代码,这就像一个魅力。但我有一个简单的问题:为什么当我写onUpdate: setPos() 时,它可以工作但移动颠簸? onUpdate: setPos 运作良好。 setPos() 是否被视为函数,setPos 是否被视为变量?或者类似的东西?
  • @flks(如果答案有点混乱)onUpdate 方法接受一个函数onUpdate : function(){ /*code here*/ },所以我们像onUpdate : setPos 这样使用它分配该方法(属性)>我们的功能。相反,如果您写 onUpdate : setPos() 将与 立即执行该函数 (而不是分配)几乎相同,例如:onUpdate : (function(){ /*execute!*/ }()) 这不是我们需要的,也不是回调的用途。 .
  • 哦,好的,知道了。谢谢你的解释!
猜你喜欢
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-16
  • 2018-03-28
相关资源
最近更新 更多