最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there a way to use bootstrap tabs without using a unique identifier - Stack Overflow

programmeradmin8浏览0评论

I would like to be able to use bootstrap tabs but without using a unique selector.

I cannot guarantee that the selector is the only one in the dom.

I have many sub templates which are either included in the page as it is rendered or can be loaded inside a modal via ajax.

I do use id's but never in the templates i might use within a modal, some modals are preloaded after the page load event.

  <div class="panel">
    <div class="panel-heading">
       <ul class="nav nav-tabs">
        <li><a data-target=".pane1" data-toggle="tab" aria-expanded="true">pane 1</a></li>
        <li><a data-target=".pane2" data-toggle="tab" aria-expanded="true">pane 2</a></li>
      </ul>     
    </div>
    <div class="panel-body">
      <div class="tab-content">
        <div class="tab-pane pane1">pane 1</div>
        <div class="tab-pane pane2">pane 2</div>
      </div>
    </div>
  </div>

I have tried an onclick event on the anchor tag with just jquery which is less than ideal, but cannot get it to work with the .tab('show')

onclick="$(this).closest('.panel')
   .find('.tab-pane').hide();$(this).closest('.panel').find('.pane1').show();"

I would like to be able to use bootstrap tabs but without using a unique selector.

I cannot guarantee that the selector is the only one in the dom.

I have many sub templates which are either included in the page as it is rendered or can be loaded inside a modal via ajax.

I do use id's but never in the templates i might use within a modal, some modals are preloaded after the page load event.

  <div class="panel">
    <div class="panel-heading">
       <ul class="nav nav-tabs">
        <li><a data-target=".pane1" data-toggle="tab" aria-expanded="true">pane 1</a></li>
        <li><a data-target=".pane2" data-toggle="tab" aria-expanded="true">pane 2</a></li>
      </ul>     
    </div>
    <div class="panel-body">
      <div class="tab-content">
        <div class="tab-pane pane1">pane 1</div>
        <div class="tab-pane pane2">pane 2</div>
      </div>
    </div>
  </div>

I have tried an onclick event on the anchor tag with just jquery which is less than ideal, but cannot get it to work with the .tab('show')

onclick="$(this).closest('.panel')
   .find('.tab-pane').hide();$(this).closest('.panel').find('.pane1').show();"
Share Improve this question edited Dec 10, 2015 at 17:20 TarranJones asked Apr 28, 2015 at 16:08 TarranJonesTarranJones 4,2522 gold badges40 silver badges56 bronze badges 5
  • 2 Wait, you can have exclusive classes but not ids? – Carrie Kendall Commented Apr 28, 2015 at 16:11
  • 1 Also, why can't you guarantee unique ids? Maybe giving more information about that will allow us to help you find a solution without writing huge jquery selectors – Carrie Kendall Commented Apr 28, 2015 at 16:14
  • That is a rather OTT jQuery selector chain. have a look at api.jquery./end – Josh Stevenson Commented Apr 28, 2015 at 16:16
  • why are you using onclick when it already works using your markup and no ID's? plnkr.co/edit/nnsXInx3Hyuti3qjNPuR?p=preview – charlietfl Commented Apr 28, 2015 at 16:20
  • it wont work if i have duplicate selectors. ill make an edit – TarranJones Commented Apr 28, 2015 at 16:28
Add a ment  | 

2 Answers 2

Reset to default 9

Yes it is possible...for this HTML:

 <div class="panel">
    <div class="panel-heading">
       <ul class="nav nav-tabs">
        <li><a href="#">pane 1</a></li>
        <li><a href="#">pane 2</a></li>
      </ul>     
    </div>
    <div class="panel-body">
      <div class="tab-content">
        <div class="tab-pane">pane 1</div>
        <div class="tab-pane">pane 2</div>
      </div>
    </div>
  </div>

This Javascript:

$('.panel .nav-tabs').on('click', 'a', function(e){
  var tab  = $(this).parent(),
      tabIndex = tab.index(),
      tabPanel = $(this).closest('.panel'),
      tabPane = tabPanel.find('.tab-pane').eq(tabIndex);
  tabPanel.find('.active').removeClass('active');
  tab.addClass('active');
  tabPane.addClass('active');
});

See this functioning bootply

Note Take note that I removed all data attributes from the anchors to prevent bootstraps auto wireup to them**

This solution uses role attributes to control functionality rather than class names, all role are valid ARIA values. http://accessibility.athena-ict./aria/examples/tabpanel2.shtml. The solution works when nesting "tabpanels".

   <div role="tabpanel">
      <ul class="nav nav-tabs" role="tablist">
        <li role="presentation"><a role="tab" data-toggle="tab">1</a></li>
        <li role="presentation"><a role="tab" data-toggle="tab">2</a></li>
        <li role="presentation"><a role="tab" data-toggle="tab">3</a></li>
      </ul>
      <div class="tab-content">
        <div role="tabpanel">1</div>
        <div role="tabpanel">2</div>
        <div role="tabpanel">3</div>
      </div>
    </div>

    <div role="tabpanel">
      <ul class="nav nav-tabs" role="tablist">
        <li role="presentation"><a role="tab" data-toggle="tab">1</a></li>
        <li role="presentation"><a role="tab" data-toggle="tab">2</a></li>
        <li role="presentation"><a role="tab" data-toggle="tab">3</a></li>
      </ul>
      <div class="tab-content">
        <div role="tabpanel">1</div>
        <div role="tabpanel">2</div>
        <div role="tabpanel">3</div>
      </div>
    </div>

javascript

I modified bootstrap tabs "show" method to include this code these lines.

var $context = $this.closest('[role="tabpanel"]');
if($context.length && $target.length != 1){

    if($target.length > 1){
        $target = $context.find('[role="tabpanel"] ').eq($this.parent().index());
    } else {
        $target = $context.find(selector).length ? $context.find(selector) : $target;
    }
}

Full method.

 $.fn.tab.Constructor.prototype.show=function(){var t=this.element,e=t.closest("ul:not(.dropdown-menu)"),a=t.data("target");if(a||(a=t.attr("href"),a=a&&a.replace(/.*(?=#[^\s]*$)/,"")),!t.parent("li").hasClass("active")){var r=e.find(".active:last a"),n=$.Event("hide.bs.tab",{relatedTarget:t[0]}),i=$.Event("show.bs.tab",{relatedTarget:r[0]});if(r.trigger(n),t.trigger(i),!i.isDefaultPrevented()&&!n.isDefaultPrevented()){var l=$(a),s=t.closest('[role="tabpanel"]');s.length&&1!=l.length&&(l=l.length>1?s.find('.tab-pane, [role="tabpanel"] ').eq(t.parent().index()):s.find(a).length?s.find(a):l),this.activate(t.closest("li"),e),this.activate(l,l.parent(),function(){r.trigger({type:"hidden.bs.tab",relatedTarget:t[0]}),t.trigger({type:"shown.bs.tab",relatedTarget:r[0]})})}}};
发布评论

评论列表(0)

  1. 暂无评论