Подтвердить что ты не робот

Вкладка jQuery UI non ajax загружает весь сайт в себя?

Наличие большой проблемы с вкладками jQuery.

Я пытаюсь загрузить вкладки на странице своего сайта... Когда страница загружается, я вижу содержимое вкладки для второго (стандартные вкладки html не ajax), а затем весь сайт загружается внутри вкладки.

Я использую стандартный код с демонстрационной страницы вкладок jquery ui.

<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 вокруг сайта, просто интересно, видел ли кто-нибудь это раньше.

Большое спасибо

4b9b3361

Ответ 1

Вы правы, это метатег BASE. Это проблема, с которой вам придется столкнуться с последней версией jQuery UI (1.9), она работала с 1.8. Было много изменений в API вкладок, но ничего не вызывало этой проблемы, пока вы не проверите исходный код jQuery.

  • Метатег BASE указывает браузеру преобразовать атрибут href на вкладках (которые вы используете в качестве ссылки для содержимого вкладок) с хеш-id на полный URL-адрес (используя значение тега BASE). Это ожидаемое поведение.
  • Предыдущие версии пользовательского интерфейса Tabs будут пытаться угадать, если href был действительно удален или нет, разделив значение вкладки href, а затем сравнив его с текущим URL И с тегом BASE, затем решив, действительно ли он локальный.
  • Последняя версия jQuery не проверяет значение тега BASE.
  • Итак, последняя версия, когда используется с метатегами BASE, попытается загрузить содержимое вкладки с помощью Ajax, перезагрузив себя (или что-то еще в BASE-URL).

Это вкладки jQuery UI, используемые в версии 1.8.24:

    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 замените функцию isLocal на это. Затем уменьшите файл. Замените исходную версию. Контрольная работа.

Он работал у меня в Firefox (17.0.1) и Chromium (18.0.1025.168).

Недостатком является то, что вы не можете использовать стороннюю копию (из CDN). Для меня это не проблема, так как большинство моих приложений используются в интрасетях.

Если кто-то найдет лучшее решение или знает, как это сделать, не взломав код пользовательского интерфейса jQuery, сообщите нам.

UPDATE: я нашел этот отчет об ошибке (с несколькими дубликатами): http://bugs.jqueryui.com/ticket/7822 У меня возникло соблазн добавить свой собственный комментарий, но, похоже, разработчики jQuery не будут "исправить" это, поскольку они считают, что проблема в другом месте. Цитата из bugtracker:

Я не вижу, как это нетривиально для исправления...

Здесь тривиальная динамическая реализация PHP: 'http://'. $_SERVER ['HTTP_HOST']. $_SERVER ['REQUEST_URI']. '#foo'.

Это также довольно тривиально, чтобы исправить это в JavaScript, но я не буду приводить пример кода, потому что это неправильное место для исправления этого и должно быть сильно обескуражено. Поведение ссылок четко определено и согласовано во всех браузерах. Нет абсолютно никакой причины, по которой люди должны использовать неправильные URL-адреса, а затем взломать их в JavaScript.

Наконец, важно отметить, что "исправление" это означало бы нарушение правильного поведения для всех, кто правильно использует. Имейте в виду, что это было исправлено, потому что люди с правильными URL-адресами столкнулись с реальной ошибкой, которая существовала в старом коде.

Ответ 2

Это простой способ обхода, который работает внутри вашего .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();

Ответ 3

Как упоминалось в @MV, проблема в том, что jquery запутывает базовый тег поверх моей веб-страницы. Поэтому вместо редактирования файла jQuery ui в моих опциях я просто не удалял базовый тег, используя jQuery вроде этого

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

Это, похоже, работает для меня, так как я не против удаления базового тега, временного для управления вкладками на этой конкретной странице. Но я также думал о решении, если вам нужны эти определения, например, сбор этих базовых тегов в массив, их удаление, а затем после выполнения метода tabs() добавьте их снова, который выглядит немного st..id, но должен работать, если tabs() не реализует шаблон прослушивателя. Я не пробовал, и еще не хочу. Во всяком случае, похоже, что у jQuery ui есть ошибка!

Ответ 4

У Анжелики был ответ, который сработал у меня. Я использовал это в файле requirejs для любой страницы с вкладками класса в качестве селектора для вкладок.

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

Ответ 5

Мой вывод

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");
});

Возможно, посмотрите на это, может быть очень полезно удалить базовый путь, чем создать свои вкладки(), а когда ваши работы с вкладками закончены, вам нужно добавить обратно в голову

Ответ 6

Посылка с атрибутом base только для работы вкладок. Это слишком много

Еще один хакерский способ:

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();
  }
});