jquery滑动选择插件
这是该系列文章的第二部分的第二部分,介绍了如何创建jQuery插件来检测和响应滑动手势。
在第一部分中 ,我们看到了如何创建一个插件来更改轮播的图片以使其与手指在屏幕上的位置相对应。 在这一部分中,我们将其扩展为检测滑动手势。 这样可以通过创建固定间隔来提高轮播效果,以便滑动即可更改轮播效果,以完整显示下一张/上一张图片。
var Swiper = function (el, callbacks, options) {
...
this.opts = options;
this.swipeDone = false;
//perform binding
this.el.addEventListener('touchend', function (evt) {
tis.stop(evt);
});
....
};
Swiper.LEFT = - 1;
Swiper.RIGHT = 1;
...
$.fn.swiper = function (callbacks, options) {
var opts = $.extend({}, $.fn.swiper.defaults, options);
if (typeof callbacks.swiping !== 'function') {
throw '"swiping" callback must be defined.';
}
if (typeof callbacks.swiped !== 'function') {
throw '"swiped" callback must be defined.';
}
if (typeof callbacks.swipeCancel !== 'function') {
throw '"swipeCancel" callback must be defined.';
}
this.each(function () {
...
if (!swiper) {
tis.data('swiper', (swiper = new Swiper(this, callbacks, opts)));
}
});
};
$.fn.swiper.defaults = {
tolerance: 100
};
在上面的清单中,我们看到Swiper
的类构造函数已修改为接受第三个参数options
,该options
具有单个属性tolerance
。 参数分配给内部属性opts
。 所述touchend
事件被代理到stop()
的实例方法Swiper
类。
此外,两个回调函数已添加( swiped
和swipeCancel
)办理刷卡。 tolerance
的默认值设置为100(像素)。 注意,还有两个类属性Swiper.LEFT
和Swiper.RIGHT
。 它们分别代表向左滑动和向右滑动,并将在后续清单中使用。
插件定义也被修改为接受第二个可选参数,该参数提供了覆盖默认阈值100像素的选择。
我们需要扩展插件以识别何时发生了滑动,并相应地修改轮播。 我们需要考虑几种情况。 第一个也是最直接的,是用户在屏幕上拖动手指并释放手指时。 如果手指的距离大于或等于tolerance
值,则我们认为是轻扫,并且当手指离开屏幕时,转盘应该前进到下一张图像。 下图说明了这种情况。
另一方面,如果手指的距离小于tolerance
值, 则不认为该动作是滑动,转盘应恢复到其原始位置。
请记住,在屏幕接触期间,插件会移动轮播以反映手指的运动。 当手指从屏幕上抬起时(是touchend
事件的绑定touchend
),决定是前进还是退回转盘位置。
Swiper.prototype.stop = function (evt) {
if (!this.swipeDone) {
this.cbs.swipeCancel();
} else {
this.cbs.swiped(this.getDirection());
}
};
如果检测到滑动,调用回调用于推进转盘( swiped()
否则回复转盘( swipeCancel()
需要注意的一件事是,我们正在将移动方向返回到由getDirection
方法确定的“前进”回调。 这是必需的,因为回调需要知道将轮播推进到哪个方向。
Swiper.prototype.getDirection = function () {
var direction = this.diff();
if (direction < 0) {
return Swiper.LEFT;
}
if (direction > 0) {
return Swiper.RIGHT;
}
};
此方法使用本系列第1部分中定义的diff()
方法来获取手指的位移。 如果差异为负,则为向左滑动,否则为向右滑动。
现在,我们需要知道如何确定是否生成了滑动,即是否设置了swipeDone
标志。 在深入研究之前,让我们考虑下一种情况。
如果用户将手指移到屏幕上,将其拖动到阈值之外,然后再移回阈值以内,然后再移开手指,则我们不希望通过将手指移开轮播来作为用户的意图返回,是他/她不想推进轮播。
类似地,如果用户在移开手指之前将手指移回超出公差值,则他/她的意图是使转盘前进。
可以想象,确定何时检测到手势是在手指在屏幕上拖动时确定的,而不是在手指抬起时确定。 因此,我们必须对Swiper
类的move()
实例方法进行一些更改。
Swiper.prototype.move = function (evt) {
if (Math.abs(this.diff()) >= this.opts.tolerance) {
this.swipeDone = true;
} else {
this.swipeDone = false;
}
if (evt.targetTouches && evt.targetTouches.length === 1) {
if (evt.targetTouches[0].offsetX) {
this.points[1] = evt.targetTouches[0].offsetX;
} else if (evt.targetTouches[0].layerX) {
this.points[1] = evt.targetTouches[0].layerX;
} else {
this.points[1] = evt.targetTouches[0].pageX;
}
this.cbs.swiping(this.diff());
}
};
![](https://i-blog.csdnimg.cn/blog_migrate/f9d106d7232e37bccfa83f6ee1998970.png)
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
在move()
方法的开头,我们检查手指移动的距离是否超过了公差值。 该差异包含在Math.abs()
函数中,因为向左移动将始终生成一个小于任何正值的负值。 通过获取其绝对值,我们可以检查左右移动的距离。 如果确定该距离大于或等于公差值,则我们将其视为滑动。
进行这项工作的关键是删除this.points[0] = this.points[1];
来自move()
方法。 这绝对至关重要,因为我们希望从手指与屏幕接触的点( touchstart
)获取参考。 如果保留这行代码,则参考点将随着手指的每次移动而不断变化,并且我们将无法执行所需的计算。 但是,由于删除了这一行代码, diff()
返回的值也将与之前有所不同。 然后,我们必须更改swiping()
回调函数的定义。
对Swiper
类的最后一个更改是对其start()
实例方法的更改。 此更改基本上表示,每次第一次将手指放在屏幕上时, swipeDone
标志都为false,这很自然,因为当手指首次触摸屏幕时无法生成滑动。
Swiper.prototype.start = function (evt) {
if (evt.targetTouches && evt.targetTouches.length === 1) {
this.swipeDone = false;
...
}
};
插件本身已经完成很多工作。 更改应用程序代码以利用插件需要在手指仍在屏幕上拖动时我们如何操纵轮播的位置进行范式转换。 请记住,轮播应该“捕捉”到可以完整显示所有图像的位置。 结果,位置值始终是每个图像宽度的倍数。 因此,最容易将位置表示为百分比。 注意,由于我们将currPos
值视为百分比,因此MAX_RIGHT
需要将MAX_LEFT
和MAX_RIGHT
的值转换为百分比。
我们仍然希望保留轮播在手指上的镜像效果。 为此,在swiping()
回调中引入了一个新变量adhocPos
。 当手指在屏幕上拖动时,此值将保持轮播的位置。 它使用baseWidth
变量,该变量设置为330像素(轮播中每个图像的宽度)。 如果轮播中图像的宽度发生变化,则必须更改此值。
...
MAX_LEFT = -300,
MAX_RIGHT = 0,
baseWidth = 330;
cb = {
swiping: function (displacement) {
var adhocPos = currPos / 100 * baseWidth;
adhocPos += displacement;
pictures.css('left', adhocPos + 'px');
},
...
}
currPos
值被视为百分比,该百分比在下面的swiped
回调中设置:
swiped: function (direction) {
currPos += (direction * 100);
if (currPos < MAX_LEFT || currPos > MAX_RIGHT) {
//i.e. exceeded limit
currPos -= (direction * 100);
}
pictures.css('left', currPos + '%');
}
回调传递了一个direction
参数,正如我们前面所看到的,它是1
或-1
。 然后将其乘以100以转换为百分比值,然后再对currPos
求和。 if
语句检查以确保该值保留在边界内,以使轮播不会滚动到空白区域。 以前是在swiping()
回调中完成的。 通过将此检查放置在swiped()
回调中,我们得到的效果是,当用户将轮播拖动到最后一个图像之外时,我们会看到空白,但是只要抬起手指,轮播就会跳回,从而产生一种“弹跳”效果。
最后,有swipeCancel()
回调,可将轮播设置为拖动开始之前的原始位置。
swipeCancel: function () {
pictures.css('left', currPos + '%');
}
通过对本文中的插件进行的修改,我们有了一个不错的滑动轮播,其工作原理几乎类似于您浏览器中的本机应用。 同样,该插件已在第一篇文章中所述的相同浏览器中进行了测试。 您可以观看演示或下载源代码并与他们一起玩耍!
翻译自: https://www.sitepoint.com/jquery-plugin-for-touch-swiping-part-2-of-2/
jquery滑动选择插件