Open yaoningvital opened 5 years ago
最近在做的项目中有一个需求,就是有一些标签,它们水平排列,点击每一个标签,要让它滑动到合适的位置,尽量让每一次点击的标签能显示在中间的位置。如下图1所示:
当点击“青年top10”时,要让它滑动到中间的位置来,如下图2所示:
如果把一个一个的标签定义为一个个 span 标签,包含它们的标签为class为'channel-slider'的 div,而包含在这个div外面的是class为'channel'的div,它们的html结构为:
span
<div class="channel"> <div class="channel-slider"> <span ng-repeat="item in main.bottomProductChannelData" ng-click="main.selectChannel(item.id)" >{{item.title}}</span> </div> </div>
要想实现需求的效果,其实就是:
如下图3所示: (图3)
上图3是 channel-slider 往右可以滑动的最远距离。 下图4是 channel-slider 往左可以滑到的最远距离: (图4)
怎么样能控制 channel-slider 实现左右的滑动呢?可以利用 channel 元素的 scrollLeft 属性。
.channel 元素有一个固定宽度(一般为屏幕的可视宽度),这里假设为300px:
.channel{ width:300px; overflow-x: scroll; }
注意:这里最为重要的一点就是,设置overflow-x: scroll; 或者是 overflow-x: auto;。
overflow-x: scroll;
overflow-x: auto;
这里假设设它的宽度为800px:
.channel-slider{ width: 800px; }
到这一步,.channel 元素的 scrollLeft 属性的值就是 .channel-slider 元素向左边滚动的距离,如下图5所示: (图5)
scrollLeft
原生的dom元素有一个scrollLeft属性。这个属性是可读并且可写的。 当读取 scrollLeft 属性时:
let channel=document.getElementsByClassName('channel')[0] channel.scrollLeft
它表示它内部的.channel-slider 元素向左边滑动的距离。
同时这个属性又可以设置,当设置它为某一个值时,它内部的元素将滑动到特定的位置。比如说:
let channel=document.getElementsByClassName('channel')[0] channel.scrollLeft = 100
那么 channel 内部的 .channel-slider 将向左移动100px。
如果说在上面的例子中,.channel-slider 最多能向左移动500px,但是设置它要向左移动600px,即:
let channel=document.getElementsByClassName('channel')[0] channel.scrollLeft = 600
那么,.channel-slider 将会移动到自己最多能移动到的位置,即这里的500px的位置。
同时,jquery也提供了一个scrollLeft()的方法,能实现原生的dom元素一样的功能。
$('.channel').scrollLeft()
上面的代码将读取.channel里面的滑动元素 .channel-slider 向左滑动的距离。
而
$('.channel').scrollLeft(100)
上面的代码将让 .channel 内部的 .channel-slider 元素向左滑动100px。
了解了上面的东西后,要实现需求,其实就是每点击一个span,就要让.channel-slider 相应地移动一定的距离。那么要移动多少距离呢?
假设我们设当前被点击的span的中心位置距离它的父元素 .channel-slider 最左边的距离为 origin,设视框 .channel 的中心位置距离它本身的最左边的距离为 aim,因为我们想将被点击的span元素尽量移到视框 .channel 的中间位置,所以,需要移动的距离就是 origin - aim,如下图6所示:
origin - aim
即:
let channel = document.getElementsByClassName('channel')[0] channel.scrollLeft(origin - aim)
如果用jquery实现:
$('.channel').scrollLeft(origin - aim)
上面的代码可以将元素直接滑动到合适的位置,没有动画效果。 注意,如果 origin - aim的值小于0怎么办?我们知道scrollLeft 的值大于0时,slider 向左移动响应的距离,如果scrollLeft 的值小于0时,slider不会移动。
$('.channel').animate({ scrollLeft: origin - aim },300)
以上,可以实现移动时的动画效果。
1、情景描述
最近在做的项目中有一个需求,就是有一些标签,它们水平排列,点击每一个标签,要让它滑动到合适的位置,尽量让每一次点击的标签能显示在中间的位置。如下图1所示:
当点击“青年top10”时,要让它滑动到中间的位置来,如下图2所示:
2、问题分析
如果把一个一个的标签定义为一个个
span
标签,包含它们的标签为class为'channel-slider'的 div,而包含在这个div外面的是class为'channel'的div,它们的html结构为:要想实现需求的效果,其实就是:
如下图3所示: (图3)
上图3是 channel-slider 往右可以滑动的最远距离。 下图4是 channel-slider 往左可以滑到的最远距离: (图4)
3、解决方案
怎么样能控制 channel-slider 实现左右的滑动呢?可以利用 channel 元素的 scrollLeft 属性。
3.1 第一步,设置 .channel 元素的css属性如下:
.channel 元素有一个固定宽度(一般为屏幕的可视宽度),这里假设为300px:
注意:这里最为重要的一点就是,设置
overflow-x: scroll;
或者是overflow-x: auto;
。3.2 第二步,设置 .channel-slider 宽度
这里假设设它的宽度为800px:
到这一步,.channel 元素的
scrollLeft
属性的值就是 .channel-slider 元素向左边滚动的距离,如下图5所示: (图5)原生的dom元素有一个scrollLeft属性。这个属性是可读并且可写的。 当读取 scrollLeft 属性时:
它表示它内部的.channel-slider 元素向左边滑动的距离。
同时这个属性又可以设置,当设置它为某一个值时,它内部的元素将滑动到特定的位置。比如说:
那么 channel 内部的 .channel-slider 将向左移动100px。
如果说在上面的例子中,.channel-slider 最多能向左移动500px,但是设置它要向左移动600px,即:
那么,.channel-slider 将会移动到自己最多能移动到的位置,即这里的500px的位置。
同时,jquery也提供了一个scrollLeft()的方法,能实现原生的dom元素一样的功能。
上面的代码将读取.channel里面的滑动元素 .channel-slider 向左滑动的距离。
而
上面的代码将让 .channel 内部的 .channel-slider 元素向左滑动100px。
3.3 设置 .channel 的 scrollLeft 属性的值
了解了上面的东西后,要实现需求,其实就是每点击一个span,就要让.channel-slider 相应地移动一定的距离。那么要移动多少距离呢?
假设我们设当前被点击的span的中心位置距离它的父元素 .channel-slider 最左边的距离为 origin,设视框 .channel 的中心位置距离它本身的最左边的距离为 aim,因为我们想将被点击的span元素尽量移到视框 .channel 的中间位置,所以,需要移动的距离就是
origin - aim
,如下图6所示:即:
如果用jquery实现:
上面的代码可以将元素直接滑动到合适的位置,没有动画效果。 注意,如果
origin - aim
的值小于0怎么办?我们知道scrollLeft 的值大于0时,slider 向左移动响应的距离,如果scrollLeft 的值小于0时,slider不会移动。3.4 利用jquery 的 animate() 方法实现移动的动画效果
以上,可以实现移动时的动画效果。