Zepto回退到jQuery

26

我正在使用ZeptoJS开发我的网页应用,但是如果浏览器不支持Zepto,我希望可以回退到jQuery。由于目前IE是唯一不支持Zepto的主要浏览器,所以我想检测它:

if(navigator.appName == 'Microsoft Internet Explorer'){
    // load jquery
} else {
    // load zepto
}

但我更希望能够特别检测Zepto的支持并在其他情况下使用jQuery。 有没有一种特性检测的方法来实现这一点?


1
我这里有一些不错的IE浏览器检测答案,但我真的很想有一个更准确匹配Zepto浏览器的检测方法。 - jos3000
你最终用了什么?我看到他们在IE检测方面的示例:<script> document.write('<script src=' + ('__proto__' in {} ? 'zepto' : 'jquery') + '.js></script>') </script> - GnrlBzik
1
@GnrlBzik 那是 __proto__ :) - alex
是的,@alex,谢谢你,不知道为什么我没有注意到那个。 - GnrlBzik
10个回答

20

你也可以使用这里描述的JS技巧(点击链接)来检测浏览器是否为IE,并使用现代异步脚本加载库来加载所需的库。 Yepnope示例:

yepnope({
  test: !+"\v1", // IE?
  yep: 'jquery.js',
  nope: 'zepto.js'
});

@Rocket:坏消息。应该使用条件语句。 - phil pirozhkov
6
我现在正在使用 test: navigator.appName.match(/Explorer/) - phil pirozhkov

16

不要使用JavaScript来完成这个任务,我会更进一步地使用条件语句。这样可以做到:

<!--[if lt IE 8 ]>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
<![endif]-->

<!--[if !IE]>
    <script src="/js/zepto.js"></script>
<![endif]-->

这段代码可以直接嵌入你的HTML文件中。上面的代码片段会在用户使用Internet Explorer 7及以下版本浏览器时加载jQuery,否则将加载zepto.js。


还要确保只在“非IE”块中加载zepto。 - Raynos
谢谢 - 我在IE9中测试了Zepto 0.8,似乎它不起作用,所以我想我必须使用一个全局的IE -> jQuery。 - jos3000
4
应该使用 <![if !IE]>,否则 Zepto 将被解析为注释。 - Brian Nickel
3
根据Zepto网站上现有的一条评论,IE 10不支持条件注释,因此最好避免使用它。他们在主页上为IE提供了解决方案。http://zeptojs.com/ - Josh Gallagher

12

根据Zepto文档所说,如果你需要检测Internet Explorer,可以使用以下代码:

  if ('__proto__' in {}) {
    // IS NOT IE

  } else {
    // IS IE

  }

我使用Zepto进行浏览器检测,它也可以用来作为jQuery的备选方案。


1
这是一种可怕的检测IE的方式(而且它在Zepto文档中)。 - alex
@alex 为什么你说这是个可怕的方式? - esp
1
如果这是他们推荐的代码,那么他们肯定有他们的理由。正如 OP 所述,他宁愿检测 "Zepto 支持" 而不是直接检测 IE,而且这似乎是 Zepto 首选的方式。未来的 IE 可能会起作用,我相信这是一件好事。 - Zach Lysobey
2
Zepto在IE中无法工作,因为IE不支持__prototype__,所以这正是检查的正确方式。 - nilskp
1
重点不是检测是否为IE,而是Zepto依赖于__proto__,而IE没有__proto__,所以这实际上是检查它的正确方式。从navigator中查看任何内容都是荒谬的,因为你基本上只是猜测库是否在该浏览器中工作,而不是确切地知道它是否能够工作。例如,在像Opera这样的浏览器上,它也会回退到jQuery,并且在(显然)IE11中不会回退。 - Travis Kaufman
显示剩余2条评论

8
这可能是一个疯狂的想法(我不确定Zepto是否能在不支持的浏览器中加载),但是我们可以使用Zepto自己的浏览器检测功能来检查它是否在不支持的浏览器上运行。
$.os.ios      // => true if running on Apple iOS
$.os.android  // => true if running on Android
$.os.webos    // => true if running on HP/Palm WebOS
$.os.touchpad // => true if running on a HP TouchPad
$.os.version  // => string with version number, "4.0", "3.1.1", "2.1", etc.
$.os.iphone   // => true if running on iPhone
$.os.ipad     // => true if running on iPad
$.os.blackberry // => true if running on BlackBerry

也许你可以尝试像这样做:

也许你可以尝试像这样做:

var isSupported = false;
for (os in $.os) {
    if ($.os[os] == true) { isSupported = true; }
}

这不适用于Chrome/Firefox,它们在Zepto上运行正常,但这符合Zepto团队的意图,这可能更好,也可能没有改善。

12
这样做并不可取,因为即使你不打算使用它,你也必须加载 zepto。 - gagarine
1
@gagarine 我想这不会是一个大问题,因为这个库非常轻量级。无论如何,下面的答案,也就是你提出的观点,得到了更多的投票。我想那应该是被接受的答案。 - Ravindranath Akila
我认为在不需要的情况下加载Zepto的缺点是真实存在的,但是使用isIE作为jquery的开关并不理想——其他非IE浏览器不支持Zepto。现在可能更好的做法是仅在Modernizr.isTouch上加载Zepto。 - SimplGy
@SimpleAsCouldBe Modernizr.isTouch 在 IE 移动版(Windows Phone)上肯定是设置的。 - gagarine
好观点,@gagarine。我正在思考现在最好的方法是什么,过去几个项目我都使用了jQuery。没有有效的能力检测。我想最好的办法是尝试将您的条件与库的意图匹配。该库旨在支持webkit,因此在这里测试UA(惊叹)以获取webkit可能是一种有效的方法。 - SimplGy

8
不要使用条件注释,IE10将不再支持。这是Zepto文档中推荐的方法:
在现代浏览器上加载Zepto,在IE上加载jQuery。
<script>
document.write('<script src=' +
('__proto__' in {} ? 'zepto' : 'jquery') +
'.js><\/script>')
</script>

Zepto在IE中不起作用,因为IE不支持原型(prototype),所以这正是检查的正确方法。
上面的脚本进行了动态加载,但逻辑是...
<script>
if ('__proto__' in {}) {
  // This is NOT IE

  } else {
    // This is IE

  }
</script>

在您的条件注释示例中,IE9和IE10都没有脚本。 - Zach Lysobey
@ZachL 谢谢。我删除了条件注释示例,因为IE10不支持它。 - gagarine

5
<script>
  document.write('<script src=' + ('__proto__' in {} ? 'zepto' : 'jquery') + '.js><\/script>')
</script>

这是zepto.js官方网站推荐的方法。请参考http://zeptojs.com/#download

1

虽然现有的许多答案在通过额外请求加载Zepto.js时运行良好,但我有一个情况,我知道大多数情况下Zepto就足够了,我只想将其与我的脚本合并,并在需要时延迟加载jQuery。我为Zepto编写了一个小包装器,可以实现这一点。

它运行"官方"'__proto__' in ...测试,如果失败,则延迟加载jQuery。如果成功,则继续加载Zepto。

我发现即使加载了Zepto,IE8也会崩溃。这通过跳过模块的其余部分来解决了这个问题。

对于乐观情况,没有任何其他脚本请求。对于jQuery路径,那些用户也没有得到快速体验。


1
这是一个老话题,但它是针对我出现的情况,而且我对整体解决方案并不满意。上面有人评论提到官方zepto测试将导致zepto转到FireFix 3.6而不是JQuery,如果可能的话我希望避免这种情况。

所以,我的想法是...测试一下它是否支持某些HTML5特性,并且检查一下它是否不是IE。这可能意味着更大的jQuery会进入比应有的更多的浏览器,但与快速下载空白相比,我更喜欢“可工作”的臃肿代码。所以,无论如何,从Modernizer中取出isCanvasSupported()方法和zepto推荐的__proto__测试,我认为这可能是一个好的解决方案(还没有机会实际测试):

   var isHtml5AndNotIE     = function() {
        var elem = document.createElement('canvas');
        return '__proto__' in {} && !!(elem.getContext && elem.getContext('2d'));
    };

然后,只需像上面的示例或在定义jquery/zepto路径的任何位置中使用该方法在document.write()中。我可以在快速交叉引用中看到支持画布但不受zepto支持的唯一两个浏览器版本是: * IOS Safari 3.2(4+由Zepto支持) * Android 2.1(2.2+由Zepto支持)

http://zeptojs.com/#platforms

http://caniuse.com/#feat=canvas


我创建了一个开源的骨架,使用RequireJS、Bootstrap 3和Zepto,并使用上述方法提供了一个JQuery回退,如果您偶然发现这个网站并正在寻找一个RequireJS解决方案来解决这个问题,那么您可以使用它作为一个示例:https://github.com/kevinknelson/bootstrap-mobile - Kevin Nelson

0
这是我的做法:
<script type="text/javascript">
if(top.execScript){ // true only in IE
    document.write("<script src='/js/jquery.js'>\x3C/script>");
}
else{
    document.write("<script src='/js/zepto.min.js'>\x3C/script>");
}
</script>

谢谢Timbo,但我真的很想找一个专门寻找Zepto兼容性的东西,而不是改进我的“检测IE”黑客技巧。 - jos3000

0

你应该提高标准,这样不仅IE8可以使用jQuery,其他旧浏览器也可以。例如Zepto需要像Array.prototype.some这样的功能。

Zepto需要与picoQuery(这是Zepto的替代品)几乎相同的功能。在picoQuery中,他们这样做:

if (Array.isArray) {
   // Modern browser
   // (FF4+, IE9+, Safari 5+, Opera 10.5+, Konq 4.9+, Chrome 5+, etc)
   document.write("<script src='/js/zepto.min.js'></script>");
}
else {
   document.write("<script src='/js/jquery.js'></script>");
}

从兼容性表中我们可以得知,任何支持Array.isArray的浏览器也支持querySelectorAll()、addEventListener()、dispatchevent、Array.prototype.indexOf和Array.prototype.some - 这些都是在Zepto中使用的。 picoQuery在这里描述了这个选择: http://picoquery.com/the_fallback

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接