标签:
问题描述:
在创建iScroll实例的时候设置useTransform属性值为false,结果后面在使用scrollToElement方法滑动页面到指定位置时,除非滑动区域初始滑动距离为0,否则使用scrollToElement滑动时总会出现一定偏差,初始滑动距离越大,偏差越大。
原因分析:
1、找到scrollToElement方法的定义:
scrollToElement: function (el, time) { var that = this, pos; el = el.nodeType ? el : that.scroller.querySelector(el); if (!el) return; pos = that._offset(el); pos.left += that.wrapperOffsetLeft; pos.top += that.wrapperOffsetTop; pos.left = pos.left > 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left; pos.top = pos.top > that.minScrollY ? that.minScrollY : pos.top < that.maxScrollY ? that.maxScrollY : pos.top; time = time === undefined ? m.max(m.abs(pos.left) * 2, m.abs(pos.top) * 2) : time; that.scrollTo(pos.left, pos.top, time); }
调试可发现,出现问题时以上代码中that._offset(el)方法放回的数据有问题(pos.top值偏小);
2、找到offset(el)方法定义
_offset: function (el) { var left = -el.offsetLeft, top = -el.offsetTop; while (el = el.offsetParent) { left -= el.offsetLeft; top -= el.offsetTop; } if (el != this.wrapper) { left *= this.scale; top *= this.scale; } return {left: left, top: top}; }
问题就出在红色标记部分了,调试可发现top值多减去了滑动区域的offsetTop,这又是为什么呢?
看一下offsetParent是什么意思:
offsetParent属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过CSS定位的容器元素。 如果这个容器元素未进行CSS定位, 则offsetParent属性的取值为根元素(在标准兼容模式下为html元素;在怪异呈现模式下为body元素)的引用。 当容器元素的style.display 被设置为 "none"时(译注:IE和Opera除外),offsetParent属性 返回 null。
简单的说就是获取最近有设置position属性的父元素,但我们一般都不会给滑动区域设置position属性的,可通过调试发现滑动区域确实有设置position属性,这是为啥?于是想到了iScroll的构造函数。
在iScroll4的构造函数中有一下代码,若useTransform为false,则会给滑动块(scroller)添加css属性position:absolute;
if (that.options.useTransform) that.scroller.style[transform] = ‘translate(‘ + that.x + ‘px,‘ + that.y + ‘px)‘ + translateZ; else that.scroller.style.cssText += ‘;position:absolute;top:‘ + that.y + ‘px;left:‘ + that.x + ‘px‘;
至此终于真相大白!
总结下:在创建iScroll4实例时若设置seTransform为false,则iScroll4会给可滑动区域设置position:absolute,导致在运行scrollToElement方法过程中调用_offset方法计算滑动距离时会把滑动区域的offsetTop值也计算进去,最终导致滑动距离小于预期。
解决方案:
修改_offset定义,使其不计算滑动区域offset:
_offset: function (el) { var left = -el.offsetLeft, top = -el.offsetTop; while (el = el.offsetParent) { if (el == this.scroller) continue;//若为滑动块,则跳过 left -= el.offsetLeft; top -= el.offsetTop; } if (el != this.wrapper) { left *= this.scale; top *= this.scale; } return {left: left, top: top}; }
谨慎设置iScroll4的useTransform属性,他会导致scrollToElement方法表现异常
标签:
原文地址:http://www.cnblogs.com/dragon-aslan/p/4723769.html