嗯,我们还需要完成一些事情,才能搞定这个方法。目前,我们已经实现了触控手势和鼠标拖拽。
function addSlide(element, options) {
// Validate arguments...
// Resolve element...
// Touch supports...
// Mouse supports...
// ToDo: Implement it.
return null;
}
现在我们来处理返回值。这将是一个包含能够注销滑动事件的方法的对象。
return {
dispose: function () {
// Remove touch events.
ele.removeEventListener("touchstart", touchStart, false);
if (!!touchMove)
ele.removeEventListener("touchmove", touchMove, false);
ele.removeEventListener("touchend", touchEnd, false);
// Remove mouse event.
ele.removeEventListener("mousedown", mouseDown, false);
}
};
至此,大功告成!我们来看一下最终代码。
/**
* Adds gesture handlers.
* @param element the target element.
* @param options the options.
*/
function addSlide(element, options) {
if (!options || !element) return {
dispose: function () { }
};
// Get the element.
var ele = !!element && typeof element === "string" ? document.getElementById(element) : element;
if (!ele) return {
dispose: function () { }
};
// Get the minimum moving distances.
var minX = options.minX;
var minY = options.minY;
if (minX == null || minX < 0) minX = 1;
minX = Math.abs(minX);
if (minY == null || minY < 0) minY = 1;
minY = Math.abs(minY);
// The handler occured after moving.
var moved = function (x, y) {
var isX = !y || (Math.abs(x) / Math.abs(y)
> (minX + 0.01) / (minY + 0.01));
if (isX) {
if (x > minX && !!options.turnLeft)
options.turnLeft(ele, x);
else if (x < -minX && !!options.turnRight)
options.turnRight(ele, -x);
} else {
if (y > minY && !!options.turnUp)
options.turnUp(ele, y);
else if (y < -minY && !!options.turnDown)
options.turnDown(ele, -y);
}
if (!!options.moveEnd)
options.moveEnd(ele, x, y);
};
// Touch starting event handler.
var start = null;
var touchStart = function (ev) {
start = {
x: ev.targetTouches[0].pageX,
y: ev.targetTouches[0].pageY
};
if (!!options.moveStart)
options.moveStart(ele);
};
ele.addEventListener("touchstart", touchStart, false);
// Touch moving event handler.
var touchMove = !!options.moving
? function (ev) {
var point = ev.touches ? ev.touches[0] : ev;
if (!point) return;
var coor = {
x: point.pageX - start.x,
y: point.pageY - start.y
};
options.moving(ele, coor.x, coor.y);
}
: null;
if (!!touchMove)
ele.addEventListener("touchmove", touchMove, false);
// Touch ending event handler.
var touchEnd = function (ev) {
if (start == null) return;
var x = ev.changedTouches[0].pageX - start.x;
var y = ev.changedTouches[0].pageY - start.y;
start = null;
moved(x, y);
};
ele.addEventListener("touchend", touchEnd, false);
// Mouse event handler.
var mouseDown = function (ev) {
// Record current mouse position
// when mouse down.
var mStartP = getMousePosition();
// Mouse moving event handler.
var mouseMove = function (ev) {
var mCurP = getMousePosition();
var x = mCurP.x - mStartP.x;
var y = mCurP.y - mStartP.y;
options.moving(ele, x, y);
};
document.body.addEventListener("mousemove", mouseMove, false);
// Mouse up event handler.
// Need remove all mouse event handlers.
var mouseUpHandlers = [];
var mouseUp = function (ev) {
mouseUpHandlers.forEach(function (h, hi, ha) {
h(ev);
});
};
mouseUpHandlers.push(
function () {
document.body.removeEventListener("mousemove", mouseMove, false);
},
function () {
document.body.removeEventListener("mouseup", mouseUp, false);
},
function (ev) {
var mCurP = getMousePosition();
var x = mCurP.x - mStartP.x;
var y = mCurP.y - mStartP.y;
moved(x, y);
}
);
document.body.addEventListener("mouseup", mouseUp, false);
};
ele.addEventListener("mousedown", mouseDown, false);
// Return a disposable object
// for removing all event handlers.
return {
dispose: function () {
// Remove touch events.
ele.removeEventListener("touchstart", touchStart, false);
if (!!touchMove)
ele.removeEventListener("touchmove", touchMove, false);
ele.removeEventListener("touchend", touchEnd, false);
// Remove mouse event.
ele.removeEventListener("mousedown", mouseDown, false);
}
};
}
现在我们来进行一个测试。假设有这样一个 DOM 元素。
<div id="demo_gesture">
<div id="demo_gesture_fore">
</div>
</div>
样式如下。
#demo_gesture {
max-width: 800px;
height: 20px;
background-color: #EEE;
border: 1px solid #CCC;
border-radius: 10px;
position: relative;
overflow: hidden;
}
#demo_gesture > #demo_gesture_fore {
color: #CCC;
text-align: center;
width: 20px;
height: 20px;
background-color: #CCC;
border-radius: 10px;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
cursor: pointer;
}
当文档元素加载完后,我们执行以下代码。
var adjustPosition = function (ele, x) {
x = (ele.position || 0) + x;
if (x < 0)
x = 0;
else if (x > ele.parentElement.offsetWidth - ele.offsetWidth)
x = ele.parentElement.offsetWidth - ele.offsetWidth;
ele.style.left = x + "px";
return x;
};
addSlide("demo_gesture_fore", {
moving: function (ele, pos) {
adjustPosition(ele, pos.x);
},
moveEnd: function (ele, pos) {
ele.position = adjustPosition(ele, pos.x);
}
});
这个测试页面创造一个水平的滑动模块。你也可以用这个创造更多滑动组件出来。
【完】
文章类型及复杂度:Web 前端开发进阶。
节选翻译自 MSDN 博文 Slide on web,内容有所调整。
http://blogs.msdn.com/b/kingcean/archive/2016/03/23/slide-on-web.aspx