iscroll是移端端开发的两大利器之一(另一个是fastclick),为了将它整合的avalon,需要对它认真学习一番。下面是我的笔记。

第一天看的是它的工具类util.js

//用于做函数节流
var rAF = window.requestAnimationFrame	||
	window.webkitRequestAnimationFrame	||
	window.mozRequestAnimationFrame		||
	window.oRequestAnimationFrame		||
	window.msRequestAnimationFrame		||
	function (callback) { window.setTimeout(callback, 1000 / 60); };

var utils = (function () {
	var me = {};

	var _elementStyle = document.createElement('div').style;
        //取得可以用的私有前缀
	var _vendor = (function () {
		var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
			transform,
			i = 0,
			l = vendors.length;

		for ( ; i  0 ) {
			destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
			distance = Math.abs(current) + destination;
			duration = distance / speed;
		}

		return {
			destination: Math.round(destination),
			duration: duration
		};
	};
        //取得可以用transform样式名
	var _transform = _prefixStyle('transform');

	me.extend(me, {
		hasTransform: _transform !== false,//判定浏览器是否支持CSS3 transform
		hasPerspective: _prefixStyle('perspective') in _elementStyle,//支持透视效果
		hasTouch: 'ontouchstart' in window,//是否是触摸屏
		hasPointer: window.PointerEvent || window.MSPointerEvent, // IE10 is prefixed
		hasTransition: _prefixStyle('transition') in _elementStyle//支持CSS3渐变
	});

	// This should find all Android browsers lower than build 535.19 (both stock browser and webview) 
        //判定安卓的浏览器是否版本过低
	me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion));

	me.extend(me.style = {}, {//修正与CSS3变渐相关的样式名
		transform: _transform,
		transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
		transitionDuration: _prefixStyle('transitionDuration'),
		transitionDelay: _prefixStyle('transitionDelay'),
		transformOrigin: _prefixStyle('transformOrigin')
	});
        //操作类名的三个常用方法
	me.hasClass = function (e, c) {
		var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
		return re.test(e.className);
	};

	me.addClass = function (e, c) {
		if ( me.hasClass(e, c) ) {
			return;
		}

		var newclass = e.className.split(' ');
		newclass.push(c);
		e.className = newclass.join(' ');
	};

	me.removeClass = function (e, c) {
		if ( !me.hasClass(e, c) ) {
			return;
		}

		var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
		e.className = e.className.replace(re, ' ');
	};

	me.offset = function (el) {
		var left = -el.offsetLeft,
			top = -el.offsetTop;

		// jshint -W084
		while (el = el.offsetParent) {
			left -= el.offsetLeft;
			top -= el.offsetTop;
		}
		// jshint +W084

		return {
			left: left,
			top: top
		};
	};

	me.preventDefaultException = function (el, exceptions) {
		for ( var i in exceptions ) {
			if ( exceptions[i].test(el[i]) ) {
				return true;
			}
		}

		return false;
	};
        //四套事件名
	me.extend(me.eventType = {}, {
		touchstart: 1,
		touchmove: 1,
		touchend: 1,

		mousedown: 2,
		mousemove: 2,
		mouseup: 2,

		pointerdown: 3,
		pointermove: 3,
		pointerup: 3,

		MSPointerDown: 3,
		MSPointerMove: 3,
		MSPointerUp: 3
	});
        //各种缓动公式
	me.extend(me.ease = {}, {
		quadratic: {
			style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
			fn: function (k) {
				return k * ( 2 - k );
			}
		},
		circular: {
			style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',	// Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
			fn: function (k) {
				return Math.sqrt( 1 - ( --k * k ) );
			}
		},
		back: {
			style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
			fn: function (k) {
				var b = 4;
				return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
			}
		},
		bounce: {
			style: '',
			fn: function (k) {
				if ( ( k /= 1 ) 

源码还算易读,但也遇到几个不懂的地方。一个是momentum方法,物理公式忘光了,另一个是offset方法。offset的结果与我们常用的不一致。

<!DOCTYPE html>
<html>
    <head>
        <title>iscroll学习 by 司徒正美</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="avalon.js" ></script>
        <script>

            window.onload = function() {
                var elem = document.querySelector("#son")
                var offset = function(el) {
                    var left = -el.offsetLeft,
                            top = -el.offsetTop;

                    // jshint -W084
                    while (el = el.offsetParent) {
                        left -= el.offsetLeft;
                        top -= el.offsetTop;
                    }
                    // jshint +W084

                    return {
                        left: left,
                        top: top
                    };
                };
                console.log(offset(elem)) //iscroll.offset 返回 [-400,-400]
                console.log(avalon(elem).offset()) //jQuery.offset, avalon.offset返回 [400, 400]
               
            }


        </script>
    </head>
    <body>
        <style>
          
            #parent{
                position: absolute;
                top:200px;
                left:200px;
            }
            #son {
                position: absolute;
                top:200px;
                left:200px;
            }
        </style>
        <div ms-controller="test">
            <div   >
                <input   />ddd   
            </div

        </div>
    </body>
</html>

相关文章: