суббота, 28 марта 2009 г.

jQuery Tabs. Ajax загрузка в один и тот же div контейнер

Эта статья будет полезна тем, кто использует такую мощную штуку как jQuery UI, в частности элемент интерфейса Tabs. jQuery Tabs позволяет в несколько строчек кода создавать удобный и быстрый набор вкладок на HTML странице.

Контент в каждой из вкладок может быть как статическим,так и динамически загружаемым при помощи ajax-а. Все доступные опции и методы этого элемента управления неплохо расписаны на официальном сайте jQuery, поэтому я углубляться не буду.

Приведу пример использования:

<div id="contacttabs">
  <ul>
    <li><a href="all.html"><span>Все контакты</span></a></li>
    <li><a href="friends.html"><span>Друзья</span></a></li>
    <li><a href="invisible.html"><span>Список невидящих</span></a></li>
    <li><a href="ignore.html"><span>Список игнорируемых</span></a></li>
  </ul>
</div>

<script type="text/javascript">
  $(document).ready(function() {
    $("#contacttabs").tabs({
      spinner: 'загрузка...'
});
  }
</script>

После загрузки страницы создастся четыре вкладки, содержимое, в каждую из них, будет загружено динамически ajax-ом. Все недостающие контейнеры, в которые загружать содержимое вкладок, jQuery создаст сам. Эта часть будет выглядеть приблизительно вот так (содержимое div-ов опущено для упрощения восприятия):

<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">
...
</ul>
<div id="ui-tabs-16" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>
<div id="ui-tabs-27" class="ui-tabs-panel ui-widget-content ui-corner-bottom"></div>
<div id="ui-tabs-29" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>
<div id="ui-tabs-31" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"></div>

Вкладок четыре, соответственно DIVов-контейнеров тоже четыре. У меня проблема возникла вот в чём. В данном конкретном примере, содержимое вкладок было одинаковым по структуре, но различным по смыслу. Появлялась ситуация, когда элементы HTML-страницы имеющие одни и те же ID-шники появлялись на разных вкладках.

В текущий момент времени пользователь видит только активную вкладку, и может взаимодействовать только с элементами, находящимися в контейнере выбранной вкладки. Все остальные имеют атрибут hidden. Это значит, что элементы загружены в DOM для каждой из вкладок, хотя и не видны в данный момент времени, и если обратиться по уникальному ID-шнику элемента на вкладке, то может возникнуть «коллизия», и селектор выберет совсем не тот элемент, который хотелось из активной вкладки.

Единственным выходом для меня было – подчищать содержимое контейнеров неактивных вкладок, дабы не возникало дублирование ID-шников. Такой опции в jQuery Tabs, я найти не смог, пришлось написать небольшой hook. Я навесил на событие select, возникающее в Tabs, в момент переключения активной вкладки, очистку всех неактивных контейнеров <div>.

<script type="text/javascript">
  $(document).ready(function() {
    $("#contacttabs").tabs({
      spinner: 'загрузка...',
      select: function(event, ui) {
        /*clear all divs content except active one*/
        fakes = ui.panel.parentNode.getElementsByTagName('div');
        for(i=0;i<fakes.length;i++){
          if(fakes[i] != ui.panel){
            fakes[i].innerHTML = '';
          }
        }
      }
    });
  });
</script>

И тогда всё заработало, как следует..

3 комментария:

  1. подскажи как лучше сделать наоборот.
    нужно знать ID активной вкладки.

    задача подгружать в активную вкладку информацию, но для этого нужно знать её ID
    ...

    ОтветитьУдалить
  2. Владимир, ну самый простой способ - искать элемент li у которого в атрибуте class встречается класс ui-tabs-selected.

    ОтветитьУдалить
  3. решил проще

    panel = ui.panel

    где panel и есть активная вкладка.

    ОтветитьУдалить

Рекоммендую

Попробуйте надёжный хостинг от Scala Hosting