Bootstrap中tab不能二次响应的问题

今天遇到一个非常奇怪的问题,有一个用bootstrap中的tab做的页面,页面上有一个元素,第一次点击时,能够正常进行对应tab的切换,但是切换成功后,先切换到其他tab,再试图通过点击那个页面元素进行切换时,居然不能正常响应了!

<li title="讨论" data-toggle="tooltip"><span class="glyphicon glyphicon-pencil" data-toggle="tab" data-target="#target">iconText</span></li>

这个问题让我百思不得其解,第一次能够切换成功,但是第二次就不可以-_-#,单步调试发现即便手动调用tab方法,都不能触发shown.bs.tab事件,看样子是在tab方法内部出了问题,只好查阅tab.js的相关源代码,果然有了重要发现,相关代码如下:

Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }

    if ($this.parent('li').hasClass('active')) return

    var $previous = $ul.find('.active:last a')
    var hideEvent = $.Event('hide.bs.tab', {
      relatedTarget: $this[0]
    })
    var showEvent = $.Event('show.bs.tab', {
      relatedTarget: $previous[0]
    })

    $previous.trigger(hideEvent)
    $this.trigger(showEvent)

    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return

    var $target = $(selector)

    this.activate($this.closest('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $previous.trigger({
        type: 'hidden.bs.tab',
        relatedTarget: $this[0]
      })
      $this.trigger({
        type: 'shown.bs.tab',
        relatedTarget: $previous[0]
      })
    })
  }

原来bootstrap的tab元素在切换时,会先判断所在触发事件的元素的parent中li元素是否是active状态,为什么要这么做的?bootstrap在进行tab切换的时候,会考虑触发切换的元素在list中的情况,比如一个dropdown-list中某个元素点击后切换tab,这时bootstrap会把这个元素所在的li设置成active,正是因为这个缘由,导致我的页面无法二次触发tab,因为恰好我把触发元素放置到了一个与tab的切换list不相干的另外一个list中,首次切换时,bootstrap以为那个li是tab导航用的,其实我并不是那个意思,但bootstrap却把那个li元素标记成了active。之后我希望进行二次切换时,由于那个li元素已经是active,bootstrap就认为不需要进行tab切换,从而导致了这个问题。

解决方法也很简单,在之前那个元素触发了shown.bs.tab之后将其父元素li的active去掉即可。

Show Comments

Get the latest posts delivered right to your inbox.