jQuery:非常简单的选项卡切换

时间:2019-02-28 13:47:05

标签: javascript jquery

我正在尝试使用jQuery创建一个非常简单的选项卡切换机制(这是一个WordPress插件,其中所有选项卡均显示必须属于同一表格的字段。)

我的目标是: 1)单击的选项卡突出显示为活动状态; 2)代替之前显示的内容,可以看到被单击的选项卡引用的内容; 3)只有当前活动的内容必须可见,并且其选项卡也必须突出显示。

我的HTML代码是这样的:

    <html>
      <body>
      <h2 class="nav-tab-wrapper">
        <a href="#tab-1" class="nav-tab nav-tab-active">First</a>
        <a href="#tab-2" class="nav-tab">Second</a>
        <a href="#tab-3" class="nav-tab">Third</a>
      </h2>
      <hr />
      <section id="tab-1" class="tab-content active">
        <P>Some content here.</P>
      </section>
      <section id="tab-2" class="tab-content hidden">
        <p>Some more here.</p>
      </section>
      <section id="tab-3" class="tab-content hidden">
        <p>Something else here.</p>
      </section>
    </body>
  </html>

和我的 jQuery代码是:

(function( $ ) {
    $('h2.nav-tab-wrapper > a').click(function(event) {
    // Clicked anchor: prevent browser from taking action.
    event.preventDefault();

    // jQuery selector to display tab content.
    var active_tab_selector = $('h2.nav-tab-wrapper > a').attr('href');

    // Find the activated navigation and remove '.active'.
    var activated_nav = $('h2.nav-tab-wrapper > a.nav-tab-active');
    activated_nav.removeClass('nav-tab-active');

    // Add '.active' to the clicked navigation.
    $(this).parents('a').addClass('nav-tab-active');

    // Hide the displayed tab content.
    $(active_tab_selector).removeClass('active');
    $(active_tab_selector).addClass('hidden');

    // Show target tab content.
    var target_tab_selector = $(this).attr('href');
    $(target_tab_selector).removeClass('hidden');
    $(target_tab_selector).addClass('active');
  });
})( jQuery );

它没有按预期工作。您可以在JSFiddle上进行尝试(此处省略了一些最低CSS。)

我是jQuery的新手。我想念什么或做错什么了?

谢谢。

4 个答案:

答案 0 :(得分:3)

使用sibling()选择器

$('.nav-tab').click(function(e) {
  //Toggle tab link
  $(this).addClass('nav-tab-active').siblings().removeClass('nav-tab-active');

  //Toggle target tab
  $($(this).attr('href')).addClass('active').siblings().removeClass('active');
});
.nav-tab-active {
  color: #f00;
}

.tab-content {
  display: none;
}

.tab-content.active {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<h2 class="nav-tab-wrapper">
  <a href="#tab-1" class="nav-tab nav-tab-active">First</a>
  <a href="#tab-2" class="nav-tab">Second</a>
  <a href="#tab-3" class="nav-tab">Third</a>
</h2>
<hr />
<section id="tab-1" class="tab-content active">
  <P>Some content here.</P>
</section>
<section id="tab-2" class="tab-content">
  <p>Some more here.</p>
</section>
<section id="tab-3" class="tab-content">
  <p>Something else here.</p>
</section>

答案 1 :(得分:2)

我会推荐几件事:

  1. wrapper也应包含选项卡内容窗格。这样,如果您在同一页面上有多个选项卡容器,则包装程序将知道哪些选项卡和窗格属于在一起。

  2. 使用插件编写jQuery功能。定义$.fn.tabs可以使我们做$(selector).tabs()之类的事情,而不是在我们的(function ($) { ... })(jQuery)就绪块中放入大量代码

  3. hidden类是多余的,使程序难以编写。如果选项卡(或选项卡内容窗格)具有active类,则该选项卡处于活动状态-否则处于活动状态。

  4. 由于该插件会在包装器中的所有子组件上切换active,因此如果我们单击一个已经处于活动状态的选项卡,则可能会导致屏幕闪烁(取决于CSS)。我们应该防止插件在活动标签上触发。

  5. 使用事件委托和.on将事件侦听器附加到每个包装器,而不是使用.click将事件侦听器附加到每个 tab < / em>。使用更多的事件侦听器会导致程序对事件的响应速度变慢。使用尽可能少的侦听器。

  6. 如果我们可以自定义最初处于活动状态的选项卡和内容窗格,那就太好了。也许用户单击/about#contact-us,然后转到关于页面,其中联系我们选项卡处于活动状态。除非HTML为与我们联系标签设置了active类,否则它将不会显示。这是一项更高级的功能,因此我们在此答案末尾的单独部分中进行介绍。

这是一个完整的工作演示。已进行调整,以包括上述建议-

// write new features as a plugin
$.fn.tabs = function () {
  // for each tab wrapper ... 
  return this.each(function () {
    // capture wrapper context
    var wrapper = this
    // use single click event per wrapper, delegate  only to inactive tabs
    $(wrapper).on('click', '.nav-tab:not(.active)', function (event) {
      // remove all active
      $('.active', wrapper).removeClass('active')
      // get the clicked tab
      var clicked = $(event.target)
      // add the active class
      clicked.addClass('active')
      // find the tab's content and add the active class
      $(clicked.attr('href'), wrapper).addClass('active')
    })
  })
};

// keep on-ready function nice and clean!
(function ($) {
  $('.tab-wrapper').tabs()
})(jQuery)
.nav-tab.active {
  font-weight: bold;
}

.tab-content {
  display: none
}

.tab-content.active {
  display: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab-wrapper">
  <nav>
    <a href="#tab-1" class="nav-tab active">First</a>
    <a href="#tab-2" class="nav-tab">Second</a>
    <a href="#tab-3" class="nav-tab">Third</a>
  </nav>
  <hr />
  <section id="tab-1" class="tab-content active">
    <P>Tab Contents 1</P>
  </section>
  <section id="tab-2" class="tab-content">
    <p>Tab Contents 2</p>
  </section>
  <section id="tab-3" class="tab-content">
    <p>Tab Contents 3</p>
  </section>
</div>

<div class="tab-wrapper">
  <nav>
    <a href="#tab-1" class="nav-tab active">First</a>
    <a href="#tab-2" class="nav-tab">Second</a>
    <a href="#tab-3" class="nav-tab">Third</a>
  </nav>
  <hr />
  <section id="tab-1" class="tab-content active">
    <P>Some content here.</P>
  </section>
  <section id="tab-2" class="tab-content">
    <p>Some more here.</p>
  </section>
  <section id="tab-3" class="tab-content">
    <p>Something else here.</p>
  </section>
</div>


如何将选项传递给插件-

作为初学者,您不太可能之前已经编写了自己的jQuery插件。正如您在上面看到的,几乎没有任何内容。缺少的一项功能是能够将选项或参数发送到插件-

// make our function accept an argument, userOptions
$.fn.tabs = function (userOptions) {
  // merge default options with userOptions
  var options =
    $.extend(true, $.fn.tabs.defaults, userOptions || {})

  return this.each(function () {
    // capture wrapper context
    var wrapper = this
    // setup event listener (truncated)
    $(wrapper).on('click', '.nav-tab:not(.active)', ...)
    // click the initial tab  
    $(options.initialTab, wrapper).click()
  });
};

// default options
$.fn.tabs.defaults =
  { initialTab: '.nav-tab:eq(0)' };

现在,如果您忘记将active类放在标签或窗格中,该插件仍会基于默认选择器即第一个标签.nav-tab:eq(0)激活初始标签。

要创建带有自定义初始标签的标签容器,我们将一个选项传递给插件。例如,第三个标签.nav-tab:eq(2)-

$('.tab-wrapper').tabs({ initialTab: '.nav-tab:eq(2)' })

答案 2 :(得分:1)

从所有位置删除“活动”以在设计的标签上设置活动。

$('.nav-tab').click(function(e){

var target_tab_selector = $(this).attr('href');

 $('.tab-content').addClass('hidden');
 $('.tab-content').removeClass('active');
    $(target_tab_selector).removeClass('hidden');
    $(target_tab_selector).addClass('active');

})
.active{display:block}
.hidden{display:none}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
      <body>
      <h2 class="nav-tab-wrapper">
        <a href="#tab-1" class="nav-tab nav-tab-active">First</a>
        <a href="#tab-2" class="nav-tab">Second</a>
        <a href="#tab-3" class="nav-tab">Third</a>
      </h2>
      <hr />
      <section id="tab-1" class="tab-content active">
        <P>Some content here.</P>
      </section>
      <section id="tab-2" class="tab-content hidden">
        <p>Some more here.</p>
      </section>
      <section id="tab-3" class="tab-content hidden">
        <p>Something else here.</p>
      </section>
    </body>
  </html>

答案 3 :(得分:0)

我现在有点着急,但是缺少的第一件事是,当您单击某些选项卡时,隐藏所有“活动”的选项,然后添加:

$('.tab-content').removeClass('active');

在您的preventDefault()之后,尝试一下。