J'essaie de créer un mécanisme de changement d'onglet très simple en utilisant jQuery (c'est pour un plugin WordPress où tous les onglets affichent les champs qui doivent appartenir au même formulaire.)
Mon objectif est: 1) l'onglet cliqué est mis en évidence comme actif; 2) le contenu référencé à l'onglet cliqué devient visible à la place du contenu précédemment affiché; 3) seul le contenu actuellement actif doit être visible et seul son onglet doit être mis en surbrillance.
Mon code HTML ressemble à ceci:
(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 );
et mon Le code jQuery cassé est:
<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>
Il ne fonctionne pas comme prévu. Vous pouvez l'essayer sur JSFiddle (avec un minimum de CSS omis ici.)
Je suis nouveau sur jQuery. Qu'est-ce que je manque ou que je fais mal?
Merci d'avance.
4 Réponses :
Je suis un peu pressé maintenant, mais la première chose qui manque est de cacher tous les "actifs" lorsque vous cliquez sur un onglet, ajoutez:
$('.tab-content').removeClass('active');
après votre preventDefault () et essayez-le.
Supprimez ACTIVE de tout pour définir l'actif sur l'onglet conçu.
<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>
.active{display:block}
.hidden{display:none}
$('.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');
})
Plusieurs choses que je recommanderais:
Le wrapper doit également inclure les volets de contenu des onglets. De cette façon, si vous avez plusieurs conteneurs d'onglets sur la même page, l'encapsuleur sait quels onglets et volets vont ensemble.
Ecrivez des fonctionnalités jQuery à l'aide d'un plugin. Définir $ .fn.tabs nous permet de faire des choses comme $ (selector) .tabs () au lieu de mettre un gros désordre de code dans notre (fonction ( $) {...}) (jQuery) bloc prêt à l'emploi
la classe hidden est redondante et rend votre programme plus difficile à écrire. Si un onglet (ou un volet de contenu d'onglet) a la classe active , elle est active - sinon elle n'est pas active.
Parce que le plugin bascule actif sur tous les composants enfants dans un wrapper, cela peut provoquer un scintillement de l'écran (selon votre CSS) si nous cliquons sur un onglet déjà actif. Nous devrions empêcher le plugin de se déclencher sur les onglets actifs.
Utilisez la délégation d'événements avec .on pour attacher un écouteur d'événements à chaque wrapper au lieu d'utiliser .click pour attacher un événement écouteur de chaque onglet . L'utilisation de plus d'écouteurs d'événements entraîne des programmes qui sont plus lents à répondre aux événements. Utilisez le moins d'auditeurs possible.
Ce serait bien si nous pouvions personnaliser l'onglet et le volet de contenu initialement actifs. Peut-être que l'utilisateur clique sur / about # contact-us et cela va à la page About avec l'onglet Contactez-nous actif. À moins que le code HTML n'ait défini la classe active pour l'onglet Contactez-nous , elle ne sera pas affichée. Il s'agit d'une fonctionnalité plus avancée, nous la traitons donc dans une section distincte à la fin de cette réponse.
Voici une démo fonctionnelle complète. Des ajustements ont été apportés pour inclure les recommandations ci-dessus -
$('.tab-wrapper').tabs({ initialTab: '.nav-tab:eq(2)' })
// 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)' };
<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>
Comment transmettre des options aux plugins -
En tant que débutant, il est peu probable que vous ayez déjà écrit votre propre plugin jQuery. Comme vous pouvez le voir ci-dessus, il n'y a presque rien à cela. La seule pièce manquante est la possibilité d'envoyer des options ou arguments au plugin -
.nav-tab.active {
font-weight: bold;
}
.tab-content {
display: none
}
.tab-content.active {
display: inherit;
} Maintenant si vous oubliez de mettre actif code> sur vos onglets ou volets, le plugin activera toujours l'onglet initial basé sur le sélecteur par défaut, le premier onglet, .nav-tab: eq (0) .
Pour créer un conteneur d'onglets avec un onglet initial personnalisé, nous passons une option à notre plugin. Par exemple, le troisième onglet, .nav-tab: eq (2) -
// 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)
Utilisation du sélecteur sibling ()
<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>
.nav-tab-active {
color: #f00;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
$('.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');
});
Merci à tous! Je suis un débutant avec jQuery. Dans une mesure différente, chaque réponse m'a appris quelque chose d'utile. Celui-ci en particulier est intelligent, simple et a définitivement résolu mon problème.
Oh, j'ai oublié les frères et sœurs haha. Joli.
Cela a un nombre étonnamment faible de votes positifs et mérite plus.