jQuery UI非ajax选项卡将整个网站加载到自身?

问题描述 投票:19回答:7

jQuery Tabs存在很大问题。

我试图加载我的网站产品页面上的选项卡...当页面加载时,我看到标签内容一秒钟(标准html选项卡不是ajax)然后突然我的整个网站加载在选项卡内。

我正在使用jquery ui tabs演示页面中的标准代码。

<div id="productTabs">
    <ul>
        <li><a href="#tabDescription">Description</a></li>
        <li><a href="#tabSpecs">Specifications</a></li>
        <li><a href="#tabReviews">Reviews</a></li>
        <li><a href="#tabDownloads">Downloads</a></li>
    </ul>
    <div id="tabDescription">test</div>
    <div id="tabSpecs">test</div>
    <div id="tabReviews">test</div>
    <div id="tabDownloads">Sorry, no downloads available for this product.</div>
</div>
<script type="text/javascript">jQuery(document).ready(function(){jQuery("#productTabs").tabs();});</script>

但是,我在网站上有很多其他的javascript,只是想知道是否有人之前见过这个。

非常感谢

jquery jquery-ui jquery-tabs
7个回答
29
投票

你是对的,它是BASE元标记。这是最新版本的jQuery UI(1.9)会遇到的问题,它适用于1.8。 Tabs API有很多变化,但在检查jQuery源代码之前似乎没有任何问题。

  1. BASE元标记指示浏览器将选项卡中的href属性(用作选项卡内容的参考)从hash + id转换为完整URL(使用BASE标记值)。这是预期的行为。
  2. Tabs UI的早期版本会尽量猜测href是否真的是远程的,拆分href选项卡值,然后将其与当前URL和BASE标记进行比较,然后确定它是否实际上是本地的。
  3. 最新版本的jQuery不检查BASE标记值。
  4. 因此,当与BASE元标记一起使用时,最新版本将尝试使用Ajax加载选项卡内容,重新加载自身(或BASE URL中的任何内容)。

这是版本1.8.24中使用的jQuery UI选项卡:

    this.anchors.each(function( i, a ) {
      var href = $( a ).attr( "href" );
      // For dynamically created HTML that contains a hash as href IE < 8 expands
      // such href to the full page url with hash and then misinterprets tab as ajax.
      // Same consideration applies for an added tab with a fragment identifier
      // since a[href=#fragment-identifier] does unexpectedly not match.
      // Thus normalize href attribute...
      var hrefBase = href.split( "#" )[ 0 ],
        baseEl;
      if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
          ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
        href = a.hash;
        a.href = href;
      }

这是jQuery UI Tabs在1.9.2版中使用的内容:

    function isLocal( anchor ) {
      return anchor.hash.length > 1 &&
        anchor.href.replace( rhash, "" ) ===
          location.href.replace( rhash, "" )
            // support: Safari 5.1
            // Safari 5.1 doesn't encode spaces in window.location
            // but it does encode spaces from anchors (#8777)
            .replace( /\s/g, "%20" );
     }

由于Tabs代码的大量重写,代码的组织方式不同,但您可以理解($(“base”)[0]是BASE元标记值)。

到目前为止,我还没有找到任何方法告诉标签“这是本地的,不使用Ajax”使用普通的标签API。我能为您提供的是我在同一时间快速修复它所做的事情(当我问,重新检查并填写错误报告时):一个黑客。

    function isLocal( anchor ) {
      return anchor.hash.length > 1 &&
        ( (anchor.href.replace( rhash, "" ) === location.href.replace( rhash, "" ).replace( /\s/g, "%20" )) ||
          (anchor.href.replace( rhash, "" ) === $( "base" )[ 0 ].href));
    }

这是较新版本加上先前版本中的检查。

在最新jQuery UI的非缩小副本中,将isLocal函数替换为该函数。然后缩小文件。替换原始版本。测试。

它在Firefox(17.0.1)和Chromium(18.0.1025.168)中适用于我。

缺点是您无法使用第三方副本(来自CDN)。对我来说这不是问题,因为我的大多数应用程序都在内联网中使用。

如果有人找到了更好的解决方案,或者在不破解jQuery UI代码的情况下知道如何做到这一点,请告诉我们。

更新:我发现了这个错误报告(有几个重复):http://bugs.jqueryui.com/ticket/7822我很想添加我自己的评论,但似乎jQuery开发人员不会“修复”这个,因为他们认为问题在其他地方。来自bugtracker的引用:

我不明白这是多么重要的修复......

这是一个简单,动态的PHP实现:'http://'。 $ _SERVER ['HTTP_HOST']。 $ _SERVER ['REQUEST_URI']。 '#foo'。

在JavaScript中修复它也是相当简单的,但我不会提供示例代码,因为这是修复它的错误位置,应该非常劝阻。链接的行为在所有浏览器中都是明确定义和一致的。人们绝对没有理由使用错误的URL,然后在JavaScript中乱砍它们。

最后,重要的是要注意“修复”这意味着要为正确使用的每个人打破正确的行为。请记住,这是固定的,因为具有正确URL的人遇到了旧代码中存在的真正错误。


18
投票

这是一个简单的解决方法,适用于.js,因此您可以将第三方副本用于jquery.ui。 使用Jquery UI 1.10.2进行测试。 解决基本元标记问题以及可选的尾部斜杠n url的问题。

$("#mytabs UL LI A").each(function() {
    $(this).attr("href", location.href.toString()+$(this).attr("href"));
});
$("#mytabs").tabs();

6
投票

正如@MV提到的那样,问题是jquery在我的网页上混淆了基本标记。因此,我没有在我的选项中编辑jQuery ui文件,而是使用jQuery删除了基本标记

<script>
    jQuery(function() {
        jQuery('base').remove();
        jQuery( "#tabs" ).tabs();                   
    });
</script>

这似乎对我有用,因为我不介意为了特定页面上的选项卡控件而临时删除基本标记。但我也在想一个解决方案,以防万一需要这些定义,比如将这些基本标签收集到一个数组中,删除它们然后在执行tabs()方法之后,再次添加它们看起来有点st ..id但是应该工作如果tabs()未实现任何侦听器模式。我没试过,我还没有。无论如何它看起来像jQuery ui确实有一个bug!


2
投票

Angelica的答案对我有用。我在requirejs文件中使用了这个,其中任何页面都带有'tabs'类作为选项卡的选择器。

jQuery(".tabs ul li a").each(function() {
    jQuery(this).attr("href", location.href.toString()+jQuery(this).attr("href"));
});
jQuery(".tabs").tabs();

0
投票

我的结论

var base=$('base').clone(true);

$("#selector").dialog({
    open: function( event, ui ) {
        $('base').remove(); //Delete the Basepath to solve the Problem by loading Content
        $('#tabs').tabs();//Create the Tabs   
    }
    close: function( event, ui ) {base.insertAfter("head");
});

也许看看这个删除基本路径非常有帮助,而不是创建你的tabs(),当你使用标签完成后你必须追回到头部


0
投票

base属性混淆只是为了使标签工作。太多了

另一个hacky解决方法:

element.tabs({
  create: function(event, ui){
    var tabsData = $(event.target).data('ui-tabs');
    tabsData.anchors.each(function(idx, anchor){
      var contentId = $(anchor).attr('href');
      var $panel = $(tabsData.panels[idx]);
      $panel.html($(contentId).remove().html());
    });
  },
  beforeLoad: function(event, ui){
    event.preventDefault();
  }
});

jQuery UI - v1.11.1测试


0
投票

我绝不是JS程序员,更多的是Windows上的C ++ / C#,在他帮助一个亲戚在他的网站Joomla上遇到了这个帖子,他有类似的问题,但是由于MVlink对bug项目的解决方案很简单。底线 - 您不能使用“local”href =,所以..不要使用它们,例如对于服务器http://www.example.com上的页面mypage.html代码而不是原始代码:

<div id="productTabs">
    <ul>
        <li><a href="#tabDescription">Description</a></li>
        <li><a href="#tabSpecs">Specifications</a></li>
        <li><a href="#tabReviews">Reviews</a></li>
        <li><a href="#tabDownloads">Downloads</a></li>
    </ul>
    <div id="tabDescription">test</div>
    <div id="tabSpecs">test</div>
    <div id="tabReviews">test</div>
    <div id="tabDownloads">Sorry, no downloads available for this product.</div>
</div>

你应该使用:

<div id="productTabs">
    <ul>
        <li><a href="http://www.example.com/mypage.html#tabDescription">Description</a></li>
        <li><a href="http://www.example.com/mypage.html#tabSpecs">Specifications</a></li>
        <li><a href="http://www.example.com/mypage.html#tabReviews">Reviews</a></li>
        <li><a href="http://www.example.com/mypage.html#tabDownloads">Downloads</a></li>
    </ul>
    <div id="tabDescription">test</div>
    <div id="tabSpecs">test</div>
    <div id="tabReviews">test</div>
    <div id="tabDownloads">Sorry, no downloads available for this product.</div>
</div>

一切都会好起来的。当然,如果你使用一些代码生成,比如Joomla中的PHP,那么在代码生成中放置示例()echo JUri::getInstance() . '#tab<Name>'变得更加容易

© www.soinside.com 2019 - 2024. All rights reserved.