RubyLouvre / mmRouter

avalon的三柱臣之一( 路由,动画,AJAX)
119 stars 78 forks source link

ios9 hash bug导致router错误,angular和backbone社区也发现了,能给个暂时的热兼容版本吗? #94

Open IndexXuan opened 9 years ago

IndexXuan commented 9 years ago

问题链接如下 http://www.bubuko.com/infodetail-1106351.html 一个通用的问题导致spa路由跳转出现了问题,ios9 hash更改会自动延迟几十毫秒。

哎,苹果的bug导致的,向司徒大大求救,给个小兼容版本的mmState吧。辛苦了~

我去研究下源码,看看能自救不。。。

IndexXuan commented 9 years ago

目前仿照上文,在mmHistory中大概第250行的avalon.router.navigate加了延迟做暂时解决。。。

IndexXuan commented 9 years ago

但是上述暂时方案对于js(比如avalon.router.go)引导的跳转还是有问题。

gogoyqj commented 9 years ago

@IndexXuan 你提个merge request

IndexXuan commented 9 years ago

这个bug太恶心,感觉这修复merge进入主干实为不妥,就贴出我的暂时解决办法吧(解决了a链接跳转问题,但对avalon.router.go等js引导的跳转貌似还有问题) 修改mmHistory.js的268行左右:

if (hash) {
    event.preventDefault()
    setTimeout(function() { // TODO: rm the timeout when ios9 fix its location-hash-delay bug
        avalon.router && avalon.router.navigate(hash)
    }, 60);
}
rong4188 commented 9 years ago

try this. rewrite loadUrl in Backbone.js. you can put this piece of code anywhere after backbone.js loaded.

Backbone.history.loadUrl = function (fragment) {
    fragment = this.fragment = this.getFragment(fragment);
    return _.any(this.handlers, function (handler:any) {
        if (handler.route.test(fragment)) {

            // fix iOS 9 navigation and location hash change issue
            // the setting of location.hash is not immediate
            setTimeout(function () {
                handler.callback(fragment);
            }, 0);
            return true;
        }
    });
};

sorry can't type Chinese in company

IndexXuan commented 9 years ago

@rong4188 3q! my code above do the same thing,but still cannot deal with jumping which controlled by js,e.g. avalon.router.go

hope apple fix the bug,too ugly way for us,woops~

rong4188 commented 9 years ago

Actually it is not just a bug. it is a js feature called event loop, which causes problem in some particular browsers. you may want to read this article. http://www.ruanyifeng.com/blog/2013/10/event_loop.html

rong4188 commented 9 years ago

and this one: http://www.ruanyifeng.com/blog/2014/10/event-loop.html

IndexXuan commented 9 years ago

thank you for the resource. But I still not understand why event loop make the ios9 set the hash not immediately and not have the same behaviour with other browsers, even its old version ios8/7/6...?

and I think set hash should the same like set the variable, such as var a = 1; it should synchronous! overall, thank you and I will read the article again and other relevant refs

IndexXuan commented 8 years ago

@rong4188 前几天放假没好好研究,嘿嘿。你说的event loop虽然一直都知道,不过一直浮躁,没好好理解,刚又好好看了看你推荐的几篇文章,多谢! 另外兄台认为这是苹果的bug吗? 会修复吗? 毕竟现在越来越多的设备升级了Ios9 ,这样的问题每个这种带路由的spa都会遇到,这种赋值不同步,到下一个loop执行真不爽...

rong4188 commented 8 years ago

@IndexXuan So sorry for not replying you earlier. Being busy these days.

I think it is a bug, but sometimes i proved to be wrong just because I was 'too young too simple, sometimes naive ' :D .

However about this issue, we did some further research. we tested the fix in several different devices and environment, but not all the devices worked fine. So it proved to be more complicated that I thought. Then we just did some re-coding. The final solution was like:

  1. cache the old location.hash
  2. wait until newHash !== oldHash
  3. navigate

so sorry for provided you incorrect information just FYI.

Thanks, Roni

RubyLouvre commented 8 years ago

还有问题吗?

IndexXuan commented 8 years ago

@RubyLouvre 有,部分js引导的跳转avalon.router.go有时候还是有问题。希望您再帮忙看看,毕竟ios9的很多地方(比如微信)应用很多,而且升级ios9的用户也是大量的。

不知道会是apple的长期bug需要兼容还是会修复,持续关注中...

IndexXuan commented 8 years ago

@rong4188 朋友你好。感觉你真的非常谦逊,非常nice。对待问题,能很好的解答和分享,同时给出相关资料和研究进展,非常感谢。我会持续关注的,也祝你工作顺利,一切ok~