iScroll5 笔记

1.使用iScroll5的场景

iScroll5主要解决的两个问题,弹性效果,以及浏览器不支持fixed。产品设计中,涉及到许多的表单填写,同时,有许多悬浮在屏幕底部的按钮以及输入框。因此引入iScroll5框架。同时对于设备进行判断,只有iphone使用该框架。

2.tap与click

tap事件,一般是由移动端的touchstart,touchmove,touchend组合而成。对于这样做,可以解决,click的300ms延迟。

在iScroll5中,默认click事件是禁止的。官方推荐是响应tap事件来进行处理。但项目中,一部分功能是从其它项目迁过来的,中间不少的代码,以及插件都需要click事件。所以需要根据具体的设备,来判断是否开启click配置,代码如下。

//设备识别来控制iscroll的click真假

function iScrollClick(){
    var UA = navigator.userAgent;
    if (/iPhone|iPad|iPod|Macintosh/i.test(UA)) return true;
    if (/Chrome/i.test(UA)) return (/Android/i.test(UA));
    if (/Silk/i.test(UA)) return false;
    if (/Android/i.test(UA)) {
        var s = UA.match(/Android [\d+.]{1,5}/)[0].replace('Android ','');
        return parseFloat(s[0]+s[2]+s[4]) <= 442 && parseFloat(s[0]+s[2]+s[4]) > 430 ? true : false;
    }
}

window.scroll = new IScroll('#wrapper',{
            click:iScrollClick()
        });

2.双击问题

click配置放开后,问题就出来了,移动端,会出现类似点击一次,响应两次的问题。原因装要是因为,iScroll同时响应了tap和click,而click由于延迟300ms,所以,先触发tap,后触发click。

可以通过修改iScroll的源码来解决,代码段如下:

// we scrolled less than 10 pixels

if ( !this.moved ) {
	if ( this.options.tap ) {
		utils.tap(e, this.options.tap);
	}

	if ( this.options.click ) {
		utils.click(e);
	}

	this._execEvent('scrollCancel');
	return;
}

修改后代码如下:

if ( !this.moved ) {  

    if ( this.options.tap ) {
        utils.tap(e, this.options.tap);
    }

    if ( this.options.click) {
        if(this.endTime - this.startTime > 60) {
            	utils.click(e);
        }
    }
    this._execEvent('scrollCancel');

    return;
}

判断两次响应的时间间隔。

3.在不开启click配置时,节点无法点击

由于click配置未开启,iScroll屏蔽了所有点击。如果想解除某些节点的屏蔽。可以在初始化中配置代码类似于:

preventDefaultException:{tagName: /^(INPUT|TEXTAREA|BUTTON|DIV|SELECT|A|SPAN|I|TABLE|TR|TD|P|UL|LI|H4|IMG)$/ }

4.开启click配置后,select,input,textarea无法响应click

开启click配置后,本以为所有的节点都可以响应click了,结果不然。select,input,textarea还是无法绑定click。解决这个问题,也是从iScroll源码下手,找到如下代码段:

if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
	ev = document.createEvent('MouseEvents');
	ev.initMouseEvent('click', true, true, e.view, 1,
		target.screenX, target.screenY, target.clientX, target.clientY,
		e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
		0, null);

	ev._constructed = true;
	target.dispatchEvent(ev);
}

修改后代码如下:

if ( !(/(SELECT|TEXTAREA)/i).test(target.tagName)) {
	ev = document.createEvent('MouseEvents');
	ev.initMouseEvent('click', true, true, e.view, 1,
		target.screenX, target.screenY, target.clientX, target.clientY,
		e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
		0, null);

	ev._constructed = true;
	target.dispatchEvent(ev);
}

这样就开启了input节点,如果要开启其它的,也是类似的处理。

5.页面节点动态变化

由于iScroll的scroll高度,是初始化时,就计算好了。如果在页面中动态添加节点,则会出现,显示不全的现象。可以在每一次操作完dom后,通过scroll.refresh方法刷新视图,重新计算高度。但可能在实际的页面中,会有许多地方对dom节点进行动态的操作。所以,可以用一个定时器,定时刷新视图,方便许多。

*****
Written by Zheng Yu on 26 June 2015