chender
chender
  • 发布:2015-05-26 22:23
  • 更新:2015-05-26 22:34
  • 阅读:3327

一个关于和原生滚动的有关的很严重的问题,大家很有可能遇到了,只是没有察觉

分类:MUI

因为这个问题的排查耗费了我好几个小时的时间,所以打算在这里记个流水账,留个记忆,发个感慨
事情是这样的,我的app里面有个消息列表的模块,今天下午测试人员告诉我:收到新消息后消息列表不会自动滚动到最下面了;
滚动的功能我是用的mui.scrollTo(99999,10),以达到滚动到最底部的效果;
当时觉得很奇怪,这个功能之前都是好好的,并且那一块儿代码一直没动过,怎么突然就出问题了;
然后我就跟踪了一下代码,发现mui.scrollTo这句代码明明是有被执行到的,我就开始怀疑是不是官方更新后产生的新bug,索性看了一下mui.js里对应的源码,发现这个功能就是通过js原生的scroll实现的,只是加入了动画,所以mui.js是不可能有什么问题;
然后我就断定肯定是document的高度出了问题,打印了一下document.body的高度,果不其然,无论页面上内容有多少,document.body的高度始终是一个固定值(换算后大概就是我屏幕的高度),难怪scrollTo会失效,webview(document.body的高度应该和所在的webview的高度是一样的)的高度和屏幕的高度一样了,当然滚不动了,因为在这种情况下根本就不会出现原生的滚动条;
那页面上的滚动条是哪里来的,跟踪了一下,是mui-scroll-wrapper的(因为使用的下拉刷新),难怪干绝有点卡卡的(页面上内容比较多,且有不少图片),原来这滚动条是html的滚动条。
所以我就官方的qq群里,论坛了各种找大神,大概就是问:使用mui-scroll-wrapper后是不是会让document.body的高度固定,导致原生的滚动条消失;
可能是我问题描述不太清楚(因为这个问题确实不太好描述),发了好几篇帖子,基本上没有人理我,
后来DCloud_MUI_FXY回复了我的一篇帖子,他说要通过mui('#scroll').scroll()初始化,虽然我不太相信(因为之前也没调这句话,就是好使的),但还是试了一下,果然不行;然后他又回复了一个:区域滚动本来就是限制了document.body的高度的;我把这句话理解成了:用了mui-scroll-wrapper后document.body的高度确实是会固定的,所以我又看了一下demo,发现demo里面居然是原生的滚动条,body的高度并不是固定的;
当时我就扇了自己一耳光,因为官网的demo都没问题,那肯定是我自己代码的问题了,所以对官方人员不积极回答我问题这个事情就没什么埋怨了,开始把自己的代码和demo做对比,把自己的代码放到demo里面去,把demo的代码放到我的环境里面了,搞了大半个小时,还是没办法定位到问题(看到最后就知道为什么定位这个问题这么难的。。);
最后没办法,只有各种反编译5+ sdk里的jar包,连蒙带猜,终于找到原因了,非常让我不可思议的原因!
是因为我的app里面设置了自定义的userAgent(plus.navigator.setUserAgent( "Application/xxxx" )),本来以为完全是八竿子打不着的事情,却阴差阳错的搭上了关系,你说奇葩不奇葩;
所以各位同行,如果你有用到下拉刷新,又有设置自定义的userAgent(这个概率可能有点小),可以试一下,看是不是我说这样的;
希望官方下次能修复这个bug;然后我发帖子花了大几十分啊,如果这个问题确实是bug的话,求补偿啊,如果不是bug的话,也不要骂我傻逼啊,不管怎样我态度还是很端正的,支持dcloud,支持中国的开源事业,代码写久了,对母语的拿捏不是很准,如有用词不当的地方,还请见谅!

2015-05-26 22:23 负责人:无 分享
已邀请:
DCloud_UNI_FXY

DCloud_UNI_FXY

下拉刷新在初始化的时候,会根据不同环境(userAgent识别)做不同选择。
当在5+ android平台的时候,会使用原生滚动。其他平台使用区域滚动(自绘滚动条)

因为你修改了userAgent,导致识别为非android平台,所以下拉刷新初始化成了区域滚动。

假设你需要自定义userAgent的话,建议不要完全重写。而是加上自己的标识。免得一些框架在做userAgent识别时出现错误。

  • chender (作者)

    恩,是这个原因,不过判断环境通过这个userAgent来做有点不太合适吧

    2015-05-26 22:38

  • DCloud_UNI_FXY

    一般的框架做环境识别,都是通过userAgent来做。当然在5+环境里还有更准确的识别方法。通过plus.os来识别。但是这个识别时机比较靠后,必须在plusReady之后才能识别到。

    而userAgent可以直接得到。方便提前做一些初始化的准备工作。不需要等到plusReady之后才做。

    2015-05-26 22:45

  • DCloud_UNI_FXY

    建议自定义userAgent的时候,一定要保留原有的可以识别环境的参数。以微信举例,他不会说直接替换掉原来的userAgent。他只会加上自己特殊的标识,告诉第三方你是在微信里运行。第三方仍可以识别出是在android还是ios。

    2015-05-26 22:49

  • chender (作者)

    回复 DCloud_UNI_FXY:哦,其实不管之前做或之后做花的总的时间都应该是差不多的吧,其实这个问题确实不能完全算bug,但是确实有点设计不合理的意思,如果要拿userAgent来做识别的话,那也应该是在用户设置userAgent之前先自己保持一份,比如放到localstorage里,获取用户设置的userAgent只能添加到原来的userAgent后面,要不然像今天我遇到这种问题,确实也不能说是我的错啊;

    2015-05-26 22:57

  • chender (作者)

    回复 DCloud_UNI_FXY:恩,这个有道理,按规范来说的话,userAgent确实用追加会比较好一点,但是也不排除有时候为了后台识别方便直接设置userAgent的情况;如果有好的思路还是希望官方优化一下环境识别的功能,或者是对userAgent设置做一些限制,实在不行也要有个文档明确的说明一下设置了userAgent可能会导致哪些问题

    2015-05-26 23:12

  • DCloud_UNI_FXY

    关键点不是花费的时间,而是执行的时机问题,很多东西的初始化是跟环境相关的。而很多初始化工作的原则是越早越好。

    你说的用localStorage之类的方案,做到是都可以,只是有无必要。

    这个谈不上错不错,只是个经验问题,今天遇到了,明天就知道以后如果设计userAgent要注意的事项。

    2015-05-26 23:12

  • chender (作者)

    回复 DCloud_UNI_FXY:如果做80分的话肯定没什么必要,90分的话就不一定了,我有点强迫症,所以可能和你们的立场不太一样,相信肯定也有很多人遇到过这个问题,只是没有发觉,并且以后可定还会有人遇到这样的问题,也未必能发现;

    这种设计上的问题,如果我是站在你那边的话,估计也会说和你一样的话,你要是站在我这边的话,也会说和我一样的话,大家立场不太一样,所以观点会有些冲突,谁也没办法说服谁的,只是我比较好心,想给其他同行带来点便利,因为我肯定不会因为这个问题而麻烦了;

    所以我真心不是想和你们犟哈;最近由于项目忙,除了写代码,都没咋说话,所以一时话有点多,权当找个朋友聊聊天那么想,如有打扰,望见谅。

    2015-05-26 23:32

  • DCloud_UNI_FXY

    回复 chender:多虑了,这个谈不上说服不说服,观点冲突之类的。作为平台,需要兼顾各个方面。比如目前绝大部分js库都是根据userAgent来识别环境的,那么就需要兼容这点,不然很多库就没法用了。不过文档上是应该说明一下这种情况。

    2015-05-26 23:43

  • 开心就好

    好帖,学习了

    2015-11-26 14:39

该问题目前已经被锁定, 无法添加新回复