Casual & Fellow

关于jQuery Mobile进行Page Transition时出现闪烁

在做项目的时候遇到此前没有遇到的事情,就是引入jQuery Mobile的时候出现了闪烁的情况。这个问题在我半年前处理其他项目的时候并不出现,而且最近大部分时间我都在用模拟器去调试,因此也不太察觉。不过既然问题出现了,那么就必须要解决,不要过夜。

具体问题呈现:

当我们使用茅点a,从页面A链接到页面B的时候,jQuery Mobile会自动地帮忙进行一次page transition的动画。默认情况下这个动画默认值是fade。问题就出现这里,在这个动画进行之前,页面会自动引入并闪烁,这个体验非常不好,而且很生硬。我们就要解决这个问题。

问题分析:

既然是页面转换,我们就要分析jQuery Mobile的页面且换机制的做法。一般情况下,目前的Web App的做法就是Single Page App。但是目前我们如果使用的是jQuery Mobile做程序的时候,好处就是希望多页面架构,而且可以帮助我们处理部分的动画效果。这样的好处就是每个View可以直接地在HTML文档下进行分离,方便了代码的管理,而且对于一个长线的应用来说,这样做的好处就是日后维护代码的时候可以更好地管理,而且做到了逻辑,界面渲染的分离。当然我也不反对Single Page App,但是对于一个SPA,在做代码的分离以及维护的时候都很辛苦。最终你喜欢哪个,就要看需求而订下来了。

扯远了,现在再回顾jQuery Mobile的页面引入机制。在多个页面内,进行页面切换,实质上jQuery Mobile也是在但一个页面内进行的。如果你打开浏览器的调试器,观察其HTML代码的变化,实质上在页面内引入了一个新的标签,并载入了新的页面的代码,并执行。对于旧的页面的代码实质上是终止了所有的js,并hide了下去。

按照这么说,我们就可以推断出,出现问题的地方就在于这个新的标签被过早地显示出来了。我们接下来要做的事情就是要防止这个标签被过早地显示出来。

解决问题:

为了解决这个问题呢,我们必须要利用到jQuery Mobile js 还有CSS文件,而且这两个文件必须是开发版本的(就是未压缩的),我们需要修改内部的代码尝试去解决这个问题。而实际上在下载这两个文件之前,我也去了Github,找到了jQuery Mobile的项目,并在内部找issue,而且也上了stackoverflow去看看有没有人遇到类似的问题。答案是有的!这里面我们可能会讨论到几个问题,希望大家不要嫌我说得啰嗦。

首先,我上去stackoverflow的时候,搜索了「jQuery Mobile page transition blinking」就會發先很多人遇到了同样的问题。听到的答案也有以下:

 

1,这个是jQuery Mobile的bug,早在以前的版奔上出现过(这个我此前没有发现,不太清楚)

2,修改css文件中ui-page的css代码,这个比较逼近问题根源。但是修改后无效。

3,这个是浏览器的问题。这个答案也比较逼近真相,因为这里发生了一件有趣的事情。一般我们做Web App的时候会尝试在浏览器中进行调试,而调试的过程当中,我们可能希望这个Web App展现得更加逼真,我们就希望其能够在HOME界面上登陆并展示出来。这样做了下来之后我们就发现一个有趣的事情,在浏览器中(也就是没有去掉底部的工具栏)时,Web App的页面转换非常,流畅,但是到了主屏幕中打开的时候,就会发现这个问题出现了。这里就涉及到苹果safari以及应用中Webview的运行机制了。出于安全因素的考虑,第三方开发者只可以用Nitro较早版本UIWebView作为其引擎,这就是iOS版本Chrome浏览器被迫使用较慢的引擎的原因。这里也导致了添加到主屏幕,或者在iPhone App中的WebView中浏览的时候,效率不够在纯浏览器中高。所以js处理机制上面也会出现一定的问题。

针对上面提出的几个答案,最后我是通过一些比较诡异的办法去解决这个诡异的问题的。最初的时候我是希望能够找到那段处理page transition的函数出来,然后通过修改函数的方式进行处理的。其实已经找到了这段函数,但是如果确实要修改的话,的确不那么快,因为这里涉及到几个比较重要的东西。而核心的代码是在2800行左右(因为里面的代码实在凌乱,而且jQuery Mobile的代码量实在庞大,改了一下,最终还是放弃了。)如果你有兴趣的话,你也可以上去参考一下的。

最终我实现的办法是:
<pre> 《body》 《div class="special_wrap"》 《div id="main_content"》《/div》 《/div》 《script type="text/javascript"》 $(".special_wrap").show(); var dis_spe = setTimeout("display_special_wrap()", 550); 《/script》 《/body》 </pre>
因为我阻止了其因为点击< a >标签后马上显示,做了一定的延时,因此在page transition中,只会有动画出现,而这个闪的诡异问题也即将消失。其实在这篇文章里面并没有说太多技术性,技巧性的东西。只是希望让大家去思考几个问题。

1,在Web App中,实现这些Page Transition的动画一直是个难点,当然这其中浏览器的性能也存在一个瓶颈,如果在当初设计的时候做好架构是一个经验以及技巧,大家可以分享一下大家的做法;
2,在开发过程当中,我们可以引用jQuery Mobile去解决这个问题,发现他太大的时候,我们可以在github上面抽出他的核心代码进行引入。当然如果我们希望更轻便的话,我们还可以使用这个小项目https://github.com/tpryan/CSS-Slide-Transition 不过至于体验,大家懂的。
3,Web App开发还有很长的一段路还走的。我认为在目前开发的过程中很多时候是摸着石头过河,大家都积累好经验吧,而且也只能够期待浏览器的瓶颈慢慢被突破!
4,此外,这片文章就是希望其中提及到的问题引导大家发散思维,想想Web App面临的更多问题。如果有建议,随时可以留言!