网站移动版本开发踩坑实录三
网站移动版本开发踩坑实录三
鉴于本人在移动wap上的开发经验少,遇到的问题确实不少,很多问题都是为了项目紧急上线而不得已的写临时性的fixed的方案,所以解决方法也存在缺陷,这次记录的虽然没有什么高大上的东西,把几个明显的问题和解决过程记录下来。
1、ios系统浏览器事件会触发两次
问题发现于ipad、iphone上,起初遇到这个问题本以为自己在绑定了两次事件(touchstart click),但是由于最新的ipad对click事件不支持以及为了防止重复绑定事件,因此我特意处理了关于touchstart和click做了一个统一的处理,看过事件绑定以后我就想着是不是我触发了两次呢,然后我跟踪代码发现确实触发了两次,google一下:click event call twice in ipad 发现还真有类似的情况,http://stackoverflow.com/questions/4569869/jquery-click-event-is-called-twice-on-ipad ; 无奈啊。看着处理方式是unbind然后在bind这样每次都要将点击相关的事件做这种处理,先不管效率如何,单纯的反复绑定就不是很习惯。然后我继而找了fastclick 的插件,大概看了一下源代码,通过touch.identifier === this.lastTouchIdentifier 最后一次touch标识判断是否是重复调用(我没有那么高深,以前没注意过).起初我想靠这种方式解决我们的问题,之前也说过我们wap上用的是zepto,而如果引入fastclick意味着点击相关的事件绑定要移到fastclick相关,而dom选择和操作都要zepto需要两套,因此我决定放弃。被逼无奈我想到了一种方式就是dom锁,即dom点击触发以后锁定dom,让dom 1s 之内不反复调用,从而第二次touchend就不会触发业务代码。
2、android平台遮罩层下的input、select、a等元素可以被点击和focus
问题发现于三星手机,这个在特定需求下才会有,因此如果没有类似问题的可以不看。首先需求是浮层操作,在三星上被遮罩的元素依然可以获取focus、click、change.这个问题着实棘手啊,记不得怎么查的了,最后找到https://code.google.com/p/android/issues/detail?id=6721 ,据了解3.0以下都会受到影响,在我测试的小米手机上怎么也不会出现这个问题。在查看bug报告list以后,找到了两种解决方案,第一是通过层显示以后加入对应的class名控制,第二是通过将可获取焦点元素加入的disabled属性,于是我采用了第二种方案,就因为我更喜欢js控制他们,当然由于浮沉下不仅用可获取焦点的元素还有a这类的链接和用a模拟的button,所有在不可用disabled控制的元素一律加入永久锁定,然后浮层隐藏或关闭后取消锁定(其实只有我管这种通过data属性确定是否触发dom业务的代码加锁而已),然后幸运的测试通过了。
3、android平台下获取光标的input在上下滚动的时候位于在fixed元素上
问题依旧发现在三星自带浏览器上,获取焦点的input通过在上下滚动的时候input focus 呈现在fixed的层上,这个确实很让我郁闷, 三星不但在横屏调起时我各种苦恼,还出现很多恶心的事情,在网上找一种解决方案就是input获取焦点以后去掉fixed,因此在还没有事件代码之前我yy了一下,当页面input获取焦点以后将fixed的层变为static,然后页面滚动的时候判断docuemnt.activeelement 是否是input或是select等可输入和选择的元素,如果时继续去掉fixed,不是则还原fixed。然后在这些元素blur以后还原fixed(貌似scroll看起来没意义啊)
4、ipad上从一个输入框获取焦点的状态切换到另一个遮罩层的input框时,高度计算有问题
只发现在ipad上,iphone上没有,这个我只看到效果,还没有对应测试具体代码
5、微信自带浏览器获取视窗高度和可操作高度不一致的问题
需求是弹出搜索层时计算视窗高度动态控制可显示区域和滑动处理,问题源自于站点嵌入到微信以后,通过自带浏览器打开网站,$(window).height()获取的高度比实际可操作高度大(怀疑是微信上有个壳,壳上有一个可操作菜单),虽然没有把测试代码部署实际测试一下,紧迫的项目进度催促下,只能通过agent判断是来自于微信,将实际获取高度减去100
6、select-option的展现行为
如果让你隐藏一个元素,直观的第一想法一定是element{dislay:none};嗯,那么在select的option上display貌似就不那么奏效了,考虑到在wap上根据特定条件展现下拉框中的内容,我很自然的应用了display,在模拟器里测试没有问题,然后我就特别放心的放到测试版本里面。手机上看了一眼,我擦竟然没有隐藏。看到这里有解决办法: http://stackoverflow.com/questions/9234830/how-to-hide-a-option-in-a-select-menu-with-css 。虽然我没有亲测,但是在chrome下option display:none 没有问题。
7、ios平台转屏页面紊乱问题
问题发现于ipad上,当页面反复旋转的时候自适应的页面出现紊乱,如下图
很蹊跷就是当没有调起键盘的时候页面旋转正常,只有调起键盘再旋转的时候就乱了, 先不管是否调起键盘,据我分析一定是旋转以后重绘那里出了问题了,因此找了一下对应的解决方案, http://stackoverflow.com/questions/8840580/force-dom-redraw-refresh-on-chrome-mac 基本上就是旋转触发的时候重绘一下,然后通过hide.show去达到页面区域重绘(不过设置为0貌似没有通过)。
8、ipad上safari历史记录后退页面布局混乱
这个问题出现于safari上(ios平台会出现),数据提交html更改了或是页面产生动画这类的行为,至于其他浏览器我没测试过,问题归结于回退到上一步的时候使用的html cache,记录了跳转到下一个页面的html,所以回退回来以后页面出现页面絮乱(忘记截图了),因此这样子只能出大招了,如果判断页面是通过回退过来的就强制刷新页面,如何处理在这里http://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked ,补上一篇ff的文档https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
9、chrome 地址栏自动隐藏交互行为对于fixed 顶部的元素遮挡
系统:ios8.1
浏览器:chrome 26.0.1410.53
描述信息:页面包含fixed顶部的tip element,当页面向下滑动的时候chrome地址栏自动隐藏,当向上滑动的时候地址栏自动出现。这种交互行为本身的好处会增大用户可视、交互区域。但是在chrome 26这个版本貌似这个浏览器UI布局使用adjustPan的方式,以至于向上滑动以后fixed的元素没有被自动向下移动(没有重绘)。