Zepto 框架是一个类似于 jQuery 的轻量级框架,抛弃了低级浏览器的适配问题,所以体积更小,如果会使用 jQuery,那么基本上也会使用 Zepto,jQuery 通常用于 PC 端,而 Zepto 通常用于移动端,所以说,Zepto 即为用于移动端的轻量级 jQuery
导入 Zepto 核心库
<script src="./zepto.js"></script>
示例如下:
<button>Click Me</button>
<script>
window.onload = function () {
console.log($("button").html()); // Click Me
}
</script>
Zepto 采用了模块化开发,即使用哪一种功能,导入哪一个模块,例如在 zepto 核心模块中无事件相关的代码,所以不能使用类似于 jQuery 添加事件的方式,必须导入 Zepto 的 event 模块:
<script src="./event.js"></script>
示例如下:
<button>Click Me</button>
<script>
window.onload = function () {
$("button").click(function () {
alert("Hello World"); // Hello World
})
}
</script>
若从 Zepto 官网下载的 Zepto 库,默认包含一些模块,若从 GibHub 下载,那么必须手动导入必须的模块
由于 Zepto 的使用方法与 jQuery 极为相似,所以次数不再详细说明,必须注意的是,如果想要使用高级特性,那么必须导入相应的模块,以下是常用模块的描述:
模块 | 描述 |
---|---|
zepto | 核心模块 |
event | 通过 on() & off() 处理事件 |
ajax | XMLHttpRequest 和 JSONP 实用功能 |
fx | The animate() 方法 |
fx_methods | 以动画形式的 show,hide,toggle 和 fade*() 方法 |
selector | jQuery CSS 表达式实用功能 |
touch | 在触摸设备上触发 tap– 和 swipe– 相关事件 |
gesture | 在触摸设备上触发 pinch 手势事件 |
由于 Zepto 通常应用在移动端,所以之后介绍移动端相关的特性(touch 模块)
原生 JS、jQuery 以及 Zepto 不论在 PC 端还是移动端均支持 click 点击事件,但移动端通常并不使用 click 事件,由于移动端的点击存在若干情况(轻扫、拖拽等),若使用 click 事件监听将影响性能,存在 100ms ~ 300ms 的延迟,所以,如果在移动端监听点击事件,建议使用 tap
tap 是 Zepto 在 touch 模块中自定义的事件,专门用于监听移动端的点击事件,导入模块:
<script src="./zepto.js"></script>
<script src="./event.js"></script>
<script src="./touch.js"></script>
示例如下:
<div></div>
<script>
$("div").tap(function () {
console.log("Tapped!"); // Tapped!
});
</script>
Zepto 中 tap 事件的底层使用了原生 JS 提供的移动端的 touch 事件:
事件 | 描述 |
---|---|
touchstart | 触碰 |
touchmove | 移动 |
touchend | 脱离 |
示例如下:
<div></div>
<script>
let oDiv = document.querySelector("div");
oDiv.ontouchstart = function () {
console.log("Start"); // Start
}
oDiv.ontouchmove = function () {
console.log("Move ..."); // Move ...
}
oDiv.ontouchend = function () {
console.log("End"); // End
}
</script>
原生 JS 的 touch 事件对象中有如下属性:
属性 | 描述 |
---|---|
touches | 以列表的形式保存屏幕上的所有手指 |
targetTouches | 以列表的形式保存屏幕上某一个 DOM 元素上的所有手指 |
changedTouches | 以列表的形式保存屏幕上瞬间触碰或脱离的手指 |
示例如下:
<div></div>
<script>
let oDiv = document.querySelector("div");
oDiv.ontouchstart = function (event) {
console.log(event.touches);
console.log(event.targetTouches);
console.log(event.changedTouches);
}
</script>
通常情况下使用 targetTouches
每一个 Touch 实例都有位置相关的属性:
属性 | 描述 |
---|---|
screenX/screenY | 触碰点到屏幕左上角的水平和垂直偏移位 |
clientX/clientY | 触碰点到可视区域左上角的水平和垂直偏移位 |
pageX/pageY | 触碰点到网页左上角的水平和垂直偏移位 |
示例如下:
<div></div>
<script>
let oDiv = document.querySelector("div");
oDiv.ontouchstart = function (event) {
let obj = event.targetTouches[0];
console.log("screenX", obj.screenX);
console.log("screenY", obj.screenY);
console.log("clientX", obj.clientX);
console.log("clientY", obj.clientY);
console.log("pageX", obj.pageX);
console.log("pageY", obj.pageY);
}
</script>
以下示例是 Zepto 中 tap 的实现原理:
(function (window) {
function myTap(elem, fn) {
if (!(elem instanceof HTMLElement)) {
return;
}
let startX = 0, startY = 0, startStamp = 0;
elem.ontouchstart = function (event) {
if (event.targetTouches.length > 1) {
return;
}
startX = event.targetTouches[0].clientX;
startY = event.targetTouches[0].clientY;
startStamp = Date.now();
};
elem.ontouchend = function (event) {
if (event.changedTouches.length > 1) {
return;
}
let stopX = event.changedTouches[0].clientX;
let stopY = event.changedTouches[0].clientY;
if (Math.abs(stopX - startX) > 5 || Math.abs(stopY - startY) > 5) {
return;
}
let stopStamp = Date.now();
if (stopStamp - startStamp > 100) {
return;
}
fn && fn();
};
}
window.myTap = myTap;
})(window);
当使用原生 JS 的 toush 相关事件时,在移动端存在点透问题,示例如下:
<style>
* {
margin: 0;
padding: 0;
}
.outter {
width: 300px;
height: 300px;
background-color: red;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.inner {
width: 200px;
height: 200px;
background-color: blue;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="outter"></div>
<div class="inner"></div>
<script>
window.onload = function () {
let oOutter = document.querySelector(".outter");
oOutter.onclick = function () {
console.log("Hello World"); // Hello World
}
let oInner = document.querySelector(".inner");
oInner.ontouchstart = function () {
oInner.style.display = "none"; // disappear
}
}
</script>
在上述示例中,当触碰 inner 之后,inner 消失,且 outter 将触发 click 事件,原因在于在移动端触碰屏幕时,将同时产生 touch 和 click 事件,由于 click 事件存在 100ms ~ 300ms 的延迟,因此 touch 事件先于 click 事件触发,当 inner 消失后,click 事件触发,此时已无 inner,所以将触发 outter 的 click 事件,解决方案如下:
window.onload = function () {
let oOutter = document.querySelector(".outter");
oOutter.onclick = function () {
console.log("Hello World"); // nothing
}
let oInner = document.querySelector(".inner");
oInner.ontouchstart = function (event) {
oInner.style.display = "none"; // disappear
event.preventDefault();
}
}
在上述示例中,调用 touch 事件对象的 preventDefault 方法,关闭事件冒泡,此外最新版本的 Zepto 的 tap 事件默认解决了点透问题,示例如下:
<script src="./zepto.js"></script>
<script src="./event.js"></script>
<script src="./touch.js"></script>
<script>
window.onload = function () {
let oOutter = document.querySelector(".outter");
oOutter.onclick = function () {
console.log("Hello World"); // nothing
}
let oInner = document.querySelector(".inner");
$(oInner).tap(function () {
oInner.style.display = "none"; // disappear
});
}
</script>
在上述示例中,若使用的是老版本的 Zepto,那么仍将存在点透问题,此时,可以使用 Fastclick 库来解决点透问题,示例如下:
<script src="./fastclick.js"></script>
<script>
window.onload = function () {
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function () {
FastClick.attach(document.body);
}, false);
}
let oOutter = document.querySelector(".outter");
oOutter.onclick = function () {
console.log("Hello World"); // nothing
}
let oInner = document.querySelector(".inner");
oInner.addEventListener("click", function () {
oInner.style.display = "none"; // disappear
})
}
</script>
在上述示例中,看似使用原生 JS 为 oInner 添加了 click 事件,但此 click 事件是已经被 fastclick 库升级之后的 click 事件,同时解决了 300ms 的延迟问题以及点透问题
在 Zepto 的 touch 模块中,除了 tap 事件之外,还有一个 swipe 事件,专门用于监听移动端手指在屏幕上的轻扫,示例如下:
<script src="./zepto.js"></script>
<script src="./event.js"></script>
<script src="./touch.js"></script>
<div></div>
<script>
$("div").swipe(function () {
console.log("Swiped!"); // Swiped! ...
})
</script>
在上述示例中,监听了 div 的 swipe 事件,不过无法得知轻扫的方法,所以可以监听 swipeLeft、swipeRight、swipeUp、swipeDown 事件,示例如下:
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100px;
height: 100px;
background-color: red;
margin-left: 100px;
margin-top: 100px;
}
</style>
<script src="./zepto.js"></script>
<script src="./event.js"></script>
<script src="./touch.js"></script>
<script src="./fx.js"></script>
<div></div>
<script>
$("div").swipeLeft(function () {
$(this).animate({marginLeft: "0"}, 1000);
})
$("div").swipeRight(function () {
$(this).animate({marginLeft: "100px"}, 1000)
})
$("div").swipeUp(function () {
$(this).animate({marginTop: "0"}, 1000);
})
$("div").swipeDown(function () {
$(this).animate({marginTop: "100px"}, 1000);
})
</script>
和 jQuery 相同,Zepto 也可以自定义插件,格式如下:
;(function($){
$.extend($.fn, {
stop: function(){
// ...
}
})
})(Zepto)