Organische Tabs

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Haben Sie jemals einen getaggten Inhaltsbereich in einer Seitenleiste gesehen, der ein wenig „ruckartig“ war? Das Ruckeln kann durch eine Reihe von Dingen verursacht werden, z. B. dass die Inhalte in den Tab-Bereichen unterschiedliche Höhen haben, oder vielleicht, wie der Wechsel passiert, wird das aktuelle Element für einen kurzen Moment ausgeblendet, bevor das neue erscheint, und der Inhalt darunter springt schnell auf und wieder ab. Mangels eines besseren Begriffs nenne ich Tabs, die sich flüssiger verhalten, organische Tabs.

Dieser Artikel wurde ursprünglich am 27. Oktober 2009 veröffentlicht und wird nun aktualisiert, um 1) in ein jQuery-Plugin umgewandelt zu werden, 2) mehrere Demos auf einer Seite zu haben, 3) jQuery Event Delegation zu nutzen und 4) die Animationen-Warteschlange zu verhindern.
Erneut bearbeitet am 13. Juni 2011, um jQuery 1.6.1 und HTML5 zu verwenden
Erneut bearbeitet am 17. August 2019, um jQuery 3.4.2 zu verwenden und die Demo zu CodePen zu verlegen.

Finale Demo

Sehen Sie den Pen
jQuery Organic Tabs
von Chris Coyier (@chriscoyier)
auf CodePen.

Der Plan

Der Plan ist, einen Tab-Bereich zu erstellen, der ziemlich einfach mit jQuery von Grund auf neu zu machen ist, und ihn dann besser funktionieren zu lassen. Natürlich halten wir es einfach und halten das Markup sauber und semantisch. Das Herzstück der Funktionalität wird auf der Berechnung von Höhen und dem Animieren zwischen diesen Höhen im laufenden Betrieb basieren.

Da es denkbar ist, dass man mehrere Tab-Bereiche auf einer Seite haben möchte, machen wir daraus ein jQuery-Plugin, damit es einfach auf mehrere Elemente angewendet werden kann.

Das HTML

Zuerst haben wir ein Wrapper-Element, das den gesamten Tab-Inhaltsbereich umschließt. Dies schließt alles schön ein und bietet ein gutes Ziel für das jQuery-Plugin. Innen haben wir eine ungeordnete Liste für die Tabs (Navigation) selbst. Diese Tabs habenhrefAttribute, die den IDs der unten aufgeführten ungeordneten Listen entsprechen, auf die sie sich beziehen. Der Inhalt der Tabs ist ein weiterer Wrapper-Div mit der Klasse „list-wrap“. Jedes der „Panels“ ist eine ungeordnete Liste. Der Schlüssel hier ist wirklich der „list-wrap“, der uns letztendlich ein gutes Ziel für das Einstellen und Animieren der Höhe des Inhalts bietet.

<div id="example-one">
			
    <ul class="nav">
                <li class="nav-one"><a href="#featured" class="current">Featured</a></li>
                <li class="nav-two"><a href="#core">Core</a></li>
                <li class="nav-three"><a href="#jquerytuts">jQuery</a></li>
                <li class="nav-four last"><a href="#classics">Classics</a></li>
    </ul>
	
    <div class="list-wrap">
	
		<ul id="featured">
			<li>Stuff in here!</li>
		</ul>
		 
		 <ul id="core" class="hide">
			<li>Stuff in here!</li>
		 </ul>
		 
		 <ul id="jquerytuts" class="hide">
			<li>Stuff in here!</li>
		 </ul>
		 
		 <ul id="classics" class="hide">
			<li>Stuff in here!</li>
		 </ul>
		 
    </div> <!-- END List Wrap -->
 
 </div> <!-- END Organic Tabs (Example One) -->

Das CSS

Hier gibt es nicht viel Trickreiche, nur die Einrichtung, damit alles richtig aussieht. Nur sehr wenig davon ist für das Funktionieren des Plugins/der Technik „erforderlich“, also können Sie hier gerne Ihre eigene Gestaltung rocken. Meine erste Demo ist nur eine horizontale Reihe von Tabs, von denen jeder seine eigene spezielle Rollover-Farbe hat.

/* Specific to example one */

#example-one { background: #eee; padding: 10px; margin: 0 0 15px 0; -moz-box-shadow: 0 0 5px #666; -webkit-box-shadow: 0 0 5px #666; }

#example-one .nav { overflow: hidden; margin: 0 0 10px 0; }
#example-one .nav li { width: 97px; float: left; margin: 0 10px 0 0; }
#example-one .nav li.last { margin-right: 0; }
#example-one .nav li a { display: block; padding: 5px; background: #959290; color: white; font-size: 10px; text-align: center; border: 0; }
#example-one .nav li a:hover { background-color: #111; }

#example-one ul { list-style: none; }
#example-one ul li a { display: block; border-bottom: 1px solid #666; padding: 4px; color: #666; }
#example-one ul li a:hover, #example-one ul li a:focus { background: #fe4902; color: white; }
#example-one ul li:last-child a { border: none; }

#example-one li.nav-one a.current, ul.featured li a:hover { background-color: #0575f4; color: white; }
#example-one li.nav-two a.current, ul.core li a:hover { background-color: #d30000; color: white; }
#example-one li.nav-three a.current, ul.jquerytuts li a:hover { background-color: #8d01b0; color: white; }
#example-one li.nav-four a.current, ul.classics li a:hover { background-color: #FE4902; color: white; }

Es gibt jedoch eine generell nützliche Technik, die wir anwenden. Wir müssen alle Inhaltsbereiche ausblenden, außer dem Standardbereich. Es gibt viele Möglichkeiten, wie wir das tun könnten. Wir könntendisplay: nonein CSS verwenden. Wir könnten die.hide()Funktion in JavaScript verwenden. Beide Wege haben Nachteile. Das Ausblenden in CSS bedeutet Barrierefreiheitsprobleme. Das Ausblenden in JavaScript bedeutet, dass die Bereiche möglicherweise kurz angezeigt werden, wenn die Seite geladen wird, und dann unbeholfen verschwinden. Stattdessen können wir eine Kombination aus beidem verwenden.

/* Generic Utility */
.hide { position: absolute; top: -9999px; left: -9999px; }

Schauen Sie dann im untenstehenden jQuery-Plugin-Code nach, wir setzen diese Werte wieder auf „normal“ und blenden sie mit JavaScript aus, sodass sie bereit sind, angezeigt zu werden, wenn sie benötigt werden (nicht weit weg von der Seite geschoben).

Das jQuery

Das ist der Plan in klaren Worten für unser Plugin

  1. Wenn das Plugin auf ein Element angewendet wird…
  2. Bewegen Sie den versteckten Inhalt zurück an seinen normalen Ort
  3. Wenn auf einen „Tab“ geklickt wird…
  4. Wenn es nicht bereits der aktuelle Tab ist…
  5. … und nichts gerade animiert wird…
  6. Setzen Sie den äußeren Wrapper auf eine feste Höhe des aktuellen Inhalts
  7. Heben Sie den aktuell ausgewählten Tab hervor
  8. Aktuellen Inhalt ausblenden
  9. Aktuellen Inhalt einblenden
  10. Animieren Sie die Höhe des äußeren Wrappers auf die Höhe des neuen Inhalts
(function($) {

    $.organicTabs = function(el, options) {
    
        var base = this;
        base.$el = $(el);
        base.$nav = base.$el.find(".nav");
                
        base.init = function() {
        
            base.options = $.extend({},$.organicTabs.defaultOptions, options);
            
            // Accessible hiding fix
            $(".hide").css({
                "position": "relative",
                "top": 0,
                "left": 0,
                "display": "none"
            }); 
            
            base.$nav.delegate("li > a", "click", function() {
            
                // Figure out current list via CSS class
                var curList = base.$el.find("a.current").attr("href").substring(1),
                
                // List moving to
                    $newList = $(this),
                    
                // Figure out ID of new list
                    listID = $newList.attr("href").substring(1),
                
                // Set outer wrapper height to (static) height of current inner list
                    $allListWrap = base.$el.find(".list-wrap"),
                    curListHeight = $allListWrap.height();
                $allListWrap.height(curListHeight);
                                        
                if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
                                            
                    // Fade out current list
                    base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
                        
                        // Fade in new list on callback
                        base.$el.find("#"+listID).fadeIn(base.options.speed);
                        
                        // Adjust outer wrapper to fit new list snuggly
                        var newHeight = base.$el.find("#"+listID).height();
                        $allListWrap.animate({
                            height: newHeight
                        });
                        
                        // Remove highlighting - Add to just-clicked tab
                        base.$el.find(".nav li a").removeClass("current");
                        $newList.addClass("current");
                            
                    });
                    
                }   
                
                // Don't behave like a regular link
                // Stop propegation and bubbling
                return false;
            });
            
        };
        base.init();
    };
    
    $.organicTabs.defaultOptions = {
        "speed": 300
    };
    
    $.fn.organicTabs = function(options) {
        return this.each(function() {
            (new $.organicTabs(this, options));
        });
    };
    
})(jQuery);

Verwendung des Plugins

Wie bei jedem anderen Plugin müssen Sie zuerst die jQuery-Bibliothek laden, dann die Plugin-Datei und dann das Plugin aufrufen.

<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js'></script>
<script type="text/javascript" src="js/organictabs.jquery.js"></script>
<script type='text/javascript'>
    $(function() {

        $("#example-one").organicTabs();
        
        $("#example-two").organicTabs({
            "speed": 200
        });

    });
</script>

Sie können das Plugin ohne Parameter aufrufen oder „speed“ übergeben, um die Fade-Out-/Fade-In-Animationen anzupassen.

Viel Spaß! Und denken Sie daran, die Idee ist, dass Sie dies nehmen, in Stücke hacken, tun, was immer Sie wollen, vorzugsweise reich und berühmt werden können.