这几天刚刚到新公司,他们做了一个基于TkinkPHP框架的一个订货系统,因为临近上线了,所以我也搞不大懂。索性就不管了,招头头问了问需不需要做一个什么效果,偷偷说做一个下拉刷新的效果,然后就去做了。
有个一插件名字叫做iScroll.js,谁写的我忘了,我看了一下源代码大约是1000行,不算长。寻思放着以后再看,就没管它。
然后就开始自己做,思路是做成一个插件,使用了构造函数+原型的模式。
结构是
<div class=''wrapper'>
<ul di="the-scroller"><li>....<li>
</ul>
</div>
css很简单,就不说了。
主要是在js的阶段,在构造函数内部声明默认属性,以及获得相关对象。
其中一个比较陌生和重要的就是默认属性和客户自定义属性的获取。
我开始是这样写的
function PullScroller(){
this.option = {
id:arguments[0].id||"wrapper",
type:arguments[0].type||"up"
}
很Low的方式,要是一个两个还好,要是200个呢?(Question1)
所以我看了iscroll.js的代码,
function PullScroll(el, options){
//------------default option------------
this.options = {
listId:'',moveType:'up',CLName:'loading'
};
//------------user option------------
for (i in options) this.options[i] = options[i];//i是key通过arr[key]的方式访问value
}
首先new的时候要把wrapper这个容器先传进去,然后后面跟一个options参数对象,这个对象就是客户可以自定义的参数接口,用for(key in value)的方式获得客户设置的每一个对象的值,然后赋值给默认的属性。关键是根据key来区分每一不同得属性。
事件,关于touch的事件ontouchstart,touchmove,ontouchend,开始写的是用那种事件里面嵌套事件的方式写的,基本效果可以实现,但是在ontouchstart之后,ontouchmove里面的判断不好用,只要点击就会触发ontouchend事件。(Question2)
关于这个问题分为两个步骤进行解决:
1、不再使用ontouch等方式触发事件,而是使用addEventListener来添加事件监听,从而防止事件之间相互冲突。
2、改变算法添加一个全局moving作为判断条件,如果只是start事件被触发那么moving为false,因为定义为向下移动,所以如果向上移动手指那么moving还是false,只有当向下移动成功的时候moving才是true,然后才可以触发end事件的监听。
var that = this;//保存PullScroll对象; var moving = false;//是否移动完毕。 //绑定触摸开始事件 this.onEve(this.scroller,'touchstart',function(e){ //e.stopPropagation(); startPos = e.changedTouches[0].clientY; loadBan = document.createElement('div');//创建一个div装载loading loadBan.innerHTML = 'loading...'; loadBan.className = that.options.CLName; that.wrapper.appendChild(loadBan); }); //绑定触摸移动事件 this.onEve(this.scroller,'touchmove',function(e){ //e.stopPropagation(); movePos = e.changedTouches[0].clientY; if(movePos>startPos){ dist = (movePos - startPos)/3; that.scroller.style.top = dist + 'px'; loadBan.style.cssText = "display:block;height:"+dist+'px;line-height:'+dist+'px;'; moving = true }else{ moving = false; } }); //绑定触摸结束事件 this.onEve(this.scroller,'touchend',function(){ //e.stopPropagation(); if(moving){ console.log(that.scroller); var liItem = document.createElement('li'); liItem.innerHTML = "Hello World"; that.scroller.insertBefore(liItem,that.scroller.children[0]); that.scroller.style.top = 0; that.wrapper.removeChild(loadBan); moving = false; } });基本效果到这里就写完了,然后就是下一个问题,在ios端Safari浏览器有一个橡皮筋效果,这个效果是浏览器自定义的。关问题是我还不知道他叫什么,百度了各种之后才知道这个叫橡皮筋效果,各种烦人啊。拉倒头之后就出现了一个打白条。(Question3)
这个问题的解决方案就是组织浏览器document对象的默认行为。但是又出现问题了,就是整个项目无法滚动了。这是目前我困扰的一个问题。不知道如何解决。