【问题标题】:Zepto fallback to jQueryZepto 回退到 jQuery
【发布时间】:2012-02-02 07:08:43
【问题描述】:

我将 ZeptoJS 用于我的 Web 应用程序,但如果浏览器不支持 Zepto,我想回退到 jQuery。由于 IE 是目前唯一不支持的主流浏览器,我很想检测 IE:

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

但我更愿意专门检测 Zepto 支持并在其他情况下使用 jQuery。有没有一种特征检测方法可以做到这一点?

【问题讨论】:

  • 我这里有一些很好的 IE 检测答案,但我对更准确地匹配 zepto 浏览器的检测非常感兴趣。
  • 你最终使用了什么。我看到他们的 IE 检测示例,')
  • @GnrlBzik 那是__proto__ :)
  • 是的,是@alex,谢谢,不知道为什么我没有注意到。

标签: javascript jquery browser-detection zepto


【解决方案1】:

您也可以使用here 描述的JS技巧来检测浏览器是否为IE,并使用现代异步脚本加载库来加载所需的库。 Yepnope 例子:

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

【讨论】:

  • @Rocket:坏消息。然后应该使用条件语句。
  • 我现在使用test: navigator.appName.match(/Explorer/)
【解决方案2】:

我不会使用 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 及以下版本,上述 sn-p 将加载 jQuery。否则它将包含 zepto.js。

【讨论】:

  • 还确保只加载 zepto if not IE 块。
  • 谢谢 - 我在 IE9 中测试了 Zepto 0.8,但它似乎没有工作,所以我想我必须有一个毯子 IE -> jQuery
  • 应该是 &lt;![if !IE]&gt; 否则 Zepto 将作为评论被剥离。
  • 根据 Zepto 网站上的评论,IE 10 不支持条件 cmets,因此最好避免这种情况。他们的 IE 主页上有详细的解决方案。 zeptojs.com
【解决方案3】:

正如 Zepto 文档所说,如果您需要检测 Internet Explorer,您可以使用此代码

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

  } else {
    // IS IE

  }

Zepto 使用它来依赖 jQuery,但我也将它用作浏览器检测。

【讨论】:

  • 这是一种检测 IE 的可怕方法(在 Zepto 文档中)。
  • 这确实适用于 IE,但是,Firefox 3.6 可以进行此检查(并且绝对与 Zepto 不兼容)。
  • +1。如果这是他们推荐的代码,他们有他们的理由。正如 OP 所说,他宁愿直接检测“Zepto 支持”而不是 IE,听起来这是 Zepto 的首选方式。未来的 IE 可能会起作用,我敢肯定,这是一件好事。
  • Zepto 在 IE 中不工作,因为 IE 不支持__prototype__,所以这正是检查的正确方法。
  • 重点不是检测是否是IE;关键是Zepto依赖__proto__而IE没有__proto__,所以这实际上是检查这个的正确方法。从 navigator 中查看任何内容都是荒谬的,因为您实际上只是在猜测该库是否会在该浏览器中运行,而不是知道 确切它是否会运行。例如,这也将在 Opera 等浏览器上回退到 jQuery,并且不会回退到 (apparently) IE11
【解决方案4】:

这可能是一个疯狂的想法(我不确定 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; }
}

这不会捕获与 Zepto 配合良好的 chrome/firefox,但它确实符合 Zepto 团队的意图,可能会更好,也可能不会更好。

【讨论】:

  • 这不是要走的路,因为即使你不打算使用它,你也必须加载 zepto。
  • @gagarine 我想这不会是一个大问题,因为该库非常轻量级。无论如何,下面的答案,也就是你提出的观点,有更多的选票。我想这应该是公认的答案。
  • 我认为在不需要时加载 Zepto 的缺点是真实的,但是使用 isIE 作为 jquery 的开关并不理想——其他非 ie 浏览器不支持 Zepto。现在最好只在 Modernizr.isTouch 上加载 Zepto。
  • @SimpleAsCouldBe Modernizr.isTouch 肯定是在 IE mobile (windows phone) 上设置的
  • 好点,@gagarine。我想现在最好的方法是什么,我在过去的几个项目中使用了 jQuery。没有有效的能力检测。我想最好的选择是尝试将您的条件与图书馆的意图相匹配。该库打算支持 webkit,因此在这里测试 webkit 的 UA (gasp) 可能是一种有效的方法。
【解决方案5】:

不要使用条件 cmets,它不会被 IE10 支持。这是zepto documentation 推荐的方法:

在现代浏览器上加载 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 都没有脚本。
  • @ZachL 谢谢。我删除了条件注释示例,因为 IE10 无论如何都不支持 ..
【解决方案6】:
<script>
  document.write('<script src=' + ('__proto__' in {} ? 'zepto' : 'jquery') + '.js><\/script>')
</script>

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

【讨论】:

    【解决方案7】:

    虽然通过附加请求加载 Zepto.js 时,许多现有答案都可以正常工作,但我有一种情况,我知道 Zepto 在大多数情况下就足够了,我只想将它与我的脚本合并并延迟加载 jQuery如果需要的话。我为 Zepto 组装了一个小包装器就可以做到这一点。

    它运行the "offical" '__proto__' in ... test 并在失败时延迟加载 jQuery。如果成功,则继续加载 Zepto。

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

    对于乐观的情况,没有任何额外的脚本请求。对于 jQuery 路径,无论如何,这些用户并没有完全获得快速体验。

    【讨论】:

      【解决方案8】:

      这是一个老话题,但它是我想出来的,我对整个解决方案并不满意。有人在上面的评论中提到官方的 zepto 测试将导致 zepto 使用 FireFix 3.6 而不是 JQuery,如果可能的话,我宁愿避免。

      所以,我的想法是……测试它是否支持某些 HTML5 功能 AND 如果它不是 IE。这可能意味着更大的 jQuery 将用于更多的浏览器,但我更喜欢“工作”臃肿的代码,而不是快速下载任何内容。所以,无论如何,采用 ​​Modernizer 的 isCanvasSupported() 方法和 zepto 推荐的 __proto__ 测试,我认为这可能是一个很好的解决方案(还没有机会实际测试):

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

      然后,只需在上面的示例中使用 document.write() 中的该方法,或者在您定义 jquery/zepto 路径的任何地方使用该方法。

      我可以在快速交叉引用中看到支持画布但 zepto 不支持的仅有的两个浏览器版本是: * IOS Safari 3.2(Zepto 支持 4+) * Android 2.1(Zepto 支持 2.2+)

      http://zeptojs.com/#platforms

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

      【讨论】:

      • 我使用上述方法创建了一个使用 RequireJS、Bootstrap 3 和 Zepto 和 JQuery 回退的开源框架,如果你碰巧遇到这个网站并且是像我最初一样寻找这个问题的 RequireJS 解决方案:github.com/kevinknelson/bootstrap-mobile
      【解决方案9】:

      这就是我的做法:

      <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”hack
      【解决方案10】:

      您应该提高一点,这样不仅 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 和 A​​rray.prototype.some——所有这些都在 Zepto 中使用

      picoQuery 在这里描述了这个选择: http://picoquery.com/the_fallback

      【讨论】: