<div id="pullrefresh" class="mui-scroll-wrapper">
<div class="mui-scroll">
</div>
</div>
安卓手机没有bug,但是IOS的不能显示渐变效果,看见一位前辈说scrollY冲突了,重写一下Transparent,其中的handleScroll。原因确实是这个,不过还不清楚如何解决,望各位大神不吝指教!
<div id="pullrefresh" class="mui-scroll-wrapper">
<div class="mui-scroll">
</div>
</div>
安卓手机没有bug,但是IOS的不能显示渐变效果,看见一位前辈说scrollY冲突了,重写一下Transparent,其中的handleScroll。原因确实是这个,不过还不清楚如何解决,望各位大神不吝指教!
最佳回复
刚好碰到这个问题,分享一下解决思路,对解决其他一些监听滚动的问题也有帮助。
结合源码图消化效果更佳。P.S. Line[8056-8058]是修改添加后的源码
注意到末尾Line:8109对含有mui-bar-transparent这个class的元素初始化ready后调用了一次
mui('.mui-bar-transparent').transparent();
组件的4个可选参数应该都比较好理解,上面的调用没有传参,根据Line:8019的逻辑,导航栏的透明度改变是根据默认window(或者说body)的滚动来计算的,对于hellomui中的nav-transparent.html这样的简单页面是有效的。
但是想要指定根据某个容器的滚动来计算的话,在不修改源码的情况下,局限性还是比较大的,下面指出源码的3个关键点以及大部分不生效的原因。
1.Line:8023--实例对象上挂了一个属性isNativeScroll,默认为false,当监听容器为window或者非mScroll容器时,值为true。从initEvent可以看出,这个值是用来判断监听滚动的容器是否需要添加touchmove事件的监听,mScroll自带touchmove监听,无需重复添加。值得注意的是,在初始化transparent组件之前,如果这个容器之前已经初始过了,需要调用mui('.xxx').transparent().destroy()销毁原实例,以免重复绑定事件,导致效果无常;
2.Line:8026--限制了指定的容器必须是mScroll组件的容器,必须含class名mui-scroll-wrapper。
3.Line:8054--仅当滚动事件e(event)有detail属性时,滚动距离y才会从e.detail.y里取值。这两点涉及到了mScroll组件的实现原理,简而言之,是使用两层容器利用绝对定位和transform:translate3D(x,y,z)动画,加上touchmove以及自定事件customEvent来实现滚动效果的。默认事件流对象是没有detail这个属性的,从文档中可以了解到mui大多数组件的回调、监听事件都是有detail这样一个用于回调传值的形参。那么滚动距离y(正值)是从mScroll组件滚动时触发的自定事件里拿到的e.detail.y(负值)取反用来计算透明度,如果不满足这两点,滚动距离y保持缺省值window.scrollY(Line:8053)。
综上三点,上述局限性就在于只能指定mScroll容器作为scrollby参数值,一旦不满足2、3点中的条件,比如下拉刷新上拉加载、iScroll一类组件,尽管传入了指定的容器dom,在handleScroll时,y还是保持window.scrollY,滚动容器与window(body)滚动大多数情况下是老死不相往来,滚动距离y取值自然一直取window.scrollY的初始值0,计算出来的opacity则一直为0,也就是没有效果的原因。
相对应地,在Line[8056-8058]添加了y的取值点,
y = this.scrollByElem.scrollTop;
从传入的scrollby即scrollByElem容器上取scrollTop值,不过,这并非通用的解决办法,还得按需灵活处理,关键点在于要从scrollby传入的容器dom上拿到滚动距离,建议按照实际情况实际处理。这应该也是上述局限性存在的原因,因为很难找到满足所有需求场景的取值逻辑,如果统一使用mScroll组件,就比较好处理。
最后需要注意一点的是,参数duration不要设置过大,因为duration作用于实例上的节流函数_bufferFn,设定了节流周期,按照1秒24帧算下来1000/24≈42,如果duration>>42,滚动触发的透明度变化的“动画”将小于24帧,界面可能产生明显的锯齿般的卡顿挫感,同样地,建议按照实际情况实际处理。
路人甲LURENJIA
这个方法在没有图片轮播的时候可行,但是如果页面有图片轮播,一轮播导航栏就会消失了。有没有什么解决方法吗?
2020-07-07 18:53
[已删除]
回复 路人甲LURENJIA: 在mui.js中的Transparent.prototype.handleScroll函数中进行判断,排除mui-slider即可
2020-09-22 10:29
[已删除]
Transparent.prototype.handleScroll = function(e) {
var y = window.scrollY;
if (!this.isNativeScroll && e && e.detail) {
y = -e.detail.y;
}
2020-09-22 10:30