Skip to content

Commit

Permalink
Merge pull request #27 from owenliang/gh-pages
Browse files Browse the repository at this point in the history
support multi-touch
  • Loading branch information
owenliang authored Apr 3, 2017
2 parents 26ce3c8 + 0ef398b commit 174d35d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 18 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ If you have problems with this plugin, then just create an issue, and I will sol
* *Simple API*: only need to provide your data-callback-function, the plugin will do the left.
* *Configurable*: you can specific the position where "refresh/load" will be triggered, the images that show up...But the default config already works well.
* *Flexibility*: "pull-down/pull-up" features can be "open/close" separately, and "pull-up-to-load" anamition can be added by yourself additionaly.
* *Experience*: in line with user's operating habits, strongly support multi-touch.

# Dependency
* *iscroll5*: high performance, small footprint, dependency free, multi-platform javascript scroller.
Expand Down Expand Up @@ -145,6 +146,7 @@ You may need to load data for the first screen in app without user's touch, the
* 简单的接口:用户仅需提供数据回调函数,框架负责剩余任务
* 参数化配置:用户可自定义"下拉/上拉"的触发位置、图片等,但是默认值通常可以满足需求
* 灵活的设定:"下拉/上拉"特性可独立"开启/关闭","上拉加载"特效交由用户订制
* 良好的体验:拖拽行为符合用户习惯,支持强大的多点触摸

# 依赖
* iscroll5:兼容各移动平台的滚动条方案
Expand Down
81 changes: 63 additions & 18 deletions pullToRefresh.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
*/
$.installPullToRefresh =
function (container, option) {
// 上一次移动的位置
var touchLastY = null;
// 当前的触摸事件
var touchEvent = null;
// 当前的刷新事件
Expand All @@ -23,6 +21,8 @@ function (container, option) {
var curY = -55;
// 当前的加载事件
var loadEvent = null;
// 正在触屏的手指数量
var touchFinger = 0;

// 默认参数
var defaultOption = {
Expand Down Expand Up @@ -181,45 +181,75 @@ function (container, option) {
}
}

// 更新最新的手指集合
// 浏览器对changedTouches的实现存在问题, 因此总是使用全量的touches进行比对
function compareTouchFingers(event) {
var identSet = {};
// 将不存在手指的添加到集合中
for (var i = 0; i < event.originalEvent.touches.length; ++i) {
var touch = event.originalEvent.touches[i];
identSet[touch.identifier] = true;
if (touchEvent[touch.identifier] === undefined) {
touchEvent[touch.identifier] = null;
++touchFinger;
}
}
// 将已删除的手指集合清理
for (var identifier in touchEvent) {
// 浏览器集合中已不存在,删除
if (identSet[identifier] === undefined) {
delete(touchEvent[identifier]);
--touchFinger;
}
}
}

// 父容器注册下拉事件
$(container).on("touchstart", function (event) {
// 新的触摸事件
touchEvent = {};
// 有一个刷新事件正在进行
if (!touchEvent) {
// 第一根指头触屏, 产生新的触摸事件
touchEvent = {};
}
// 将本次的手指加入到触摸事件集合中
compareTouchFingers(event);

// 刷新事件正在进行,忽略本次触屏
if (refreshEvent) {
return;
}

// 一个新的刷新事件
// 产生新的刷新事件
refreshEvent = touchEvent;
// 重置下拉启动时的手势位置
touchLastY = null;
// 如果存在,则关闭回弹动画与相关监听
pullToRefresh.removeClass("backTranTop");
pullToRefresh.unbind();
// 切换为pull图
pullImg.attr("src", finalOption.pullImg);
}).on("touchmove", function (event) {
var touchCurY = event.originalEvent.changedTouches[0].clientY;

// 在刷新未完成前触摸,将被忽略
if (touchEvent != refreshEvent) {
return;
}

// 滚动条必须到达顶部,才开始下拉刷新动画
var maxDelta = 0;
if (iscroll.y != 0) {
return;
} else if (touchLastY === null) {
touchLastY = touchCurY; // 下拉启动时的手势位置
} else { // 计算每个变化的手指, 取变化最大的delta
for (var i = 0; i < event.originalEvent.changedTouches.length; ++i) {
var fingerTouch = event.originalEvent.changedTouches[i];
if (touchEvent[fingerTouch.identifier] !== null) {
var delta = fingerTouch.clientY - touchEvent[fingerTouch.identifier];
if (Math.abs(delta) > Math.abs(maxDelta)) {
maxDelta = delta;
}
}
touchEvent[fingerTouch.identifier] = fingerTouch.clientY;
}
}

// 计算与前一次事件之间移动的距离
var delta = touchCurY - touchLastY;
touchLastY = touchCurY;

// 图标的目标位置
var destY = curY + delta;
var destY = curY + maxDelta;
// 向下不能拉出范围
if (destY > finalOption.lowerBound) {
destY = finalOption.lowerBound;
Expand All @@ -237,8 +267,23 @@ function (container, option) {
iscroll.unlockScrollUp();
}
}).on("touchend touchcancel", function (event) {
// 从touchEvent移除手指对应的记录
compareTouchFingers(event);

var touchEventRef = touchEvent;

// 所有手指都离开, 则当前触摸事件结束
if (!touchFinger) {
touchEvent = null;
}

// 在刷新未完成前触摸,将被忽略
if (touchEvent != refreshEvent) {
if (touchEventRef != refreshEvent) {
return;
}

// 只有所有手指都离开后, 才开始刷新动作
if (touchFinger) {
return;
}

Expand Down

0 comments on commit 174d35d

Please sign in to comment.