2015-05-15 6 views
7

Ich verwende eine eckige Akkordeon-Direktive, um Inhalt zu verstecken/anzuzeigen.Eckiges Akkordeon erweitert die Höhe nicht

Das Problem, mit dem ich konfrontiert bin, ist, dass sich die Höhe des Inhaltscontainers nicht ändert.

Hier ist ein Plunker: http://plnkr.co/edit/oWXrqoJpaYPDbe4TwT3c?p=preview

Wenn Sie auf anzeigen Mehr klicken, können Sie sehen, wie der Inhalt verborgen ist eher als die Höhe der Show-Jobs ändern.

JS:

app.directive('sliderContentDirective', function() { 
    return { 
     restrict:'A', 
     compile: function (element, attr) { 
      // wrap tag 
      var contents = element.html(); 
      element.html('<div class="slideable_content" style="margin:0 !important; padding:0 !important" >' + contents + '</div>'); 

      return function postLink(scope, element, attrs) { 
       // default properties 
       attrs.duration = (!attrs.duration) ? '0.7s' : attrs.duration; 
       attrs.easing = (!attrs.easing) ? 'ease-in-out' : attrs.easing; 
       element.css({ 
        'overflow': 'hidden', 
        'height': '0px', 
        'transitionProperty': 'height', 
        'transitionDuration': attrs.duration, 
        'transitionTimingFunction': attrs.easing 
       }); 
      }; 
     } 
    }; 
}); 

app.directive('sliderToggleDirective', function($document, $timeout) { 
    return { 
     restrict: 'AE', 
     scope: { 
      target: "@" 
     }, 
     link: function(scope, element, attrs) {    

      var timeoutFunc = function() { 
       var target = angular.element($document[0].querySelector("#" + scope.target))[0]; 

       attrs.expanded = false; 
       element.bind('click', function() { 

        var content = target.querySelector('.slideable_content'); 
        if(!attrs.expanded) { 
         content.style.border = '1px solid rgba(0,0,0,0)'; 
         var y = content.clientHeight; 
         content.style.border = 0; 
         target.style.height = y + 'px'; 
        } 
        else { 
         target.style.height = '0px'; 
        } 

        attrs.expanded = !attrs.expanded; 
       }); 
      } 

      $timeout(timeoutFunc, 0); 
     } 
    } 
}); 

Wenn ich die Show-Jobs Element inspizieren, kann ich sehen, daß es eine Anfangshöhe von 312px hat. Wenn ich das entferne, funktioniert es wie erwartet.

+0

Dies könnte mit CSS und Angular-Animationen gelöst werden, wenn Sie nicht auf CSS-Logik angewiesen, um Ihre Zeilen nach 3 Elementen zu wickeln. Ansonsten ist Christinas Antwort die beste Lösung, die Sie finden werden. –

Antwort

6

Wie Giliar schon gesagt, das Problem ist, dass Sie eine feste Höhe haben, die nicht Ihre section Element automatisch erlaubt zu seiner Höhe erhalten alle seine Inhalte (einschließlich der neu erweiterten Akkordeon) zu passen. Die Lösung, die ich auf diese schlagen kann (was auch ziemlich viel ist, was Bootstrap tut, soweit ich das beurteilen kann)

  1. Ihre section Set ‚s Höhe auto wenn die Animation beendet ist, so dass, wenn verschachtelte divs erweitert werden Die section wird korrekt erweitert.
  2. Setzen Sie eine feste Höhe wieder auf section, wenn der Benutzer versucht, es zu schließen, , bevor Sie seine Höhe wieder auf 0 setzen, damit die schließende Animation ordnungsgemäß funktioniert.

den ersten Teil zu tun, definieren Sie können nur eine Funktion, die die section ‚s Höhe auto und nennen Sie es, nachdem die Animation beendet ist erweitern einstellt.

var adjustHeightFunc = function() { 
    var target = angular.element($document[0].querySelector("#" + scope.target))[0]; 
    if (attrs.expanded) { 
     var content = target.querySelector('.slideable_content'); 
     target.style.height = 'auto'; 
    } 
} 

Da die erweitern Animation 0,7 Sekunden dauert können Sie nur mit einem Timeout von 0,8 Sekunden, um die adjustHeightFunc Funktion aufrufen (ich dies nicht wirklich optimal ist, da, wenn Sie die Dauer der Animation ändern werden Sie auch brauchen Ändern Sie diese Zeitüberschreitung, aber es ist die beste Lösung, die ich bisher gefunden habe, andere Vorschläge sind willkommen).Also am Ende Ihrer onClick Funktion können Sie haben:

$timeout(adjustHeightFunc, 800); 

den zweiten Teil zu tun, ist nicht die section ‚s Höhe auf 0 gesetzt, wenn der Abschnitt kollabiert werden soll, aber immer setzen Sie sich auf die Höhe von seinem Inhalt. Nachdem Sie dies getan haben und der Abschnitt minimiert werden soll, rufen Sie eine separate Funktion auf, die $ timeout mit dem Wert 0 verwendet (so dass sie in einem separaten Digest-Zyklus ausgeführt wird), der die Höhe des Abschnitts auf 0 setzt und so den Kollaps auslöst Animation. Ihre onClick Funktion wird daher so etwas wie dieses:

element.bind('click', function() { 
    var content = target.querySelector('.slideable_content'); 
    var y = content.clientHeight; 
    target.style.height = y + 'px'; 
    if(!attrs.expanded) { 
     content.style.border = '1px solid rgba(0,0,0,0)'; 
     content.style.border = 0; 
    } 
    else { 
     $timeout(closeAccordionFunc, 0); 
    } 

    attrs.expanded = !attrs.expanded; 
    $timeout(adjustHeightFunc, 800); 
}); 

Siehe updated Plunker.

EDIT: Wie sich aus den Kommentaren der closeAccordionFunc mit Timeout 0 ausgeführt wird funktioniert nicht gut mit allen Browsern. Eine Umgehung dafür besteht darin, eine CSS-Klasse zu deklarieren, die die Höhe des Elements auf auto setzt (!important, um die direkt auf dem Element festgelegte Höhe zu überschreiben) und den $animate-Dienst von Angular zum Hinzufügen/Entfernen dieser Klasse zum Element und zum Ausführen der closeAccordionFunc nach verwenden Die Klasse wurde entfernt. Die aktualisierte onClick Funktion ist daher:

element.bind('click', function() { 
    var content = target.querySelector('.slideable_content'); 
    var y = content.clientHeight; 
    target.style.height = y + 'px'; 
    if(!attrs.expanded) { 
     content.style.border = '1px solid rgba(0,0,0,0)'; 
     content.style.border = 0; 
    } 
    else { 
     $animate.removeClass(angular.element(target), 'auto', function(){$timeout(closeAccordionFunc);}); 
    } 

    attrs.expanded = !attrs.expanded; 
    if (attrs.expanded) { 
     $timeout(adjustHeightFunc, 800); 
    } 
}); 

es Siehe auch in Plunker.

+0

Danke, das ist fast da.Das einzige Problem ist, dass beim zweiten Klick von "Mehr anzeigen" der gelöschte Inhalt verschwindet und nicht nach oben rutscht. –

+0

@OamPsy Bist du dir sicher? Dies wird tatsächlich durch den zweiten Teil meiner Antwort oben behandelt und ich kann das Akkordeon in meinem Plunker nach oben rutschen sehen. Welchen Browser benutzen Sie? – Christina

+0

yup, klicken Sie einmal auf Mehr anzeigen, und der Inhalt wird nach unten verschoben. Klicken Sie erneut auf die Schaltfläche Mehr anzeigen, und der Inhalt verschwindet sofort, anstatt langsamer zu werden. Usinf FF und Chrome. –

6

Wenn Ihre Absicht ist, dass slider-content-Direktive rauf und runter gleitet, den Inhalt beim Anklicken des Knopfes ein-/ausblenden, scheint es zu funktionieren ... gut?

Ok, ich sehe, was vor sich geht. In Ordnung, so scheint das Problem eine feste Höhe von 300px zu haben. Sie könnten es in height überschreiben: auto;, aber das wird die Gleitanimation des Containers unterbrechen - weil Übergänge harte Werte für den Anfang und das Ende der Übergänge benötigen. Jetzt gibt es mindestens zwei Möglichkeiten, das zu lösen:

  • Sie könnten es neu arbeiten, um es mit maximaler Höhe arbeiten zu lassen. Siehe Animating max-height with CSS transitions
  • Sie könnten es so als die gleitende Animation des Containers machen, wenn die Erweiterung abgeschlossen ist, legen Sie eine Klasse auf die die Höhe überschreibt und wenn Sie auf die Schaltfläche "Show My Jobs >>" klicken, berechnet sie die neue Höhe der Container und weist es dem Container inline zu. Dieses Problem ist übrigens ein wenig schwierig zu lösen. :-)
+0

Nein. Öffnen Sie den Kolben. Klicken Sie auf Meine Jobs anzeigen. Klicken Sie auf Mehr anzeigen von einem Element in der oberen Reihe. Beachten Sie, dass die zweite Reihe darunter geschoben wird. –

+0

Ich habe Max-Höhe statt Höhe verwendet. Dies ist nicht die Verwendung, es sei denn, Sie wollen es grob überschätzen (wie ich). Sie arbeiten fast genauso. Max Höhe kann dir einen ähnlichen Effekt geben und trotzdem Raum zum Wachsen lassen ... wenn du genug padst. Aber dann wird das Problem verzögerte Reaktion auf Fell. Das ist ein viel schlechterer Ansatz als Christinas Verzögerung/ –

1

Ich denke, Codierung ist nur sinnvoll, wenn Sie weniger schreiben können und mehr (ok, es ist jQuery Motto, aber es ist ein gutes). Nach dieser Idee habe ich nur ein Akkordeon, das ich wirklich für nützlich halte. Ich habe es bereits here gepostet. Es basiert auf dem Material here. Die Hauptidee ist die Nützlichkeit von Radio-Buttons (es kann auch mit Checkboxen gemacht werden). Ich denke, dass die Erstellung eines AngularJS-Codes sehr schwer ist. Der Code ist:

    .accordion-example .accordion input[type="radio"] { 
 
         position: absolute; 
 
         left: -9999rem; 
 
        } 
 
        .accordion-example .accordion label { 
 
         display: block; 
 
         background: #4f6f8b; 
 
         color: #fff; 
 
         text-align: center; 
 
         padding: 1rem; 
 
         font-size: .8em; 
 
         letter-spacing: .13em; 
 
         padding-left: .13em; 
 
         padding-right: 0; 
 
         text-transform: uppercase; 
 
         cursor: pointer; 
 
         height: 3.3rem; 
 
         font-weight: 300; 
 
         transition: background 400ms, color 400ms, border-radius 400ms; 
 
        } 
 
        .accordion-example .accordion label:hover { 
 
         background: #385670 
 
        } 
 
        .accordion-example .accordion .baffle { 
 
         position: relative; 
 
         height: 3.3rem; 
 
         overflow: hidden; 
 
         transition: height 400ms; 
 
         -webkit-transform: translateZ(0); 
 
        } 
 
        .accordion-example .accordion .baffle-inner { 
 
         padding: 1.25rem; 
 
         background: #eee; 
 
         position: absolute; 
 
         top: 3.3rem; 
 
         left: 0; 
 
         height: 13.5rem; 
 
         -webkit-overflow-scrolling: touch; 
 
         overflow: scroll; 
 
         overflow-y: scroll; 
 
         overflow-x: hidden 
 
        } 
 
        .accordion-example .accordion .baffle-inner :first-child { 
 
         margin-top: 0 
 
        } 
 
        .accordion-example .accordion .baffle-inner :last-child { 
 
         margin-bottom: 0 
 
        } 
 
        .accordion-example .accordion input[type="radio"]:checked + .baffle { 
 
         height: 16.8rem 
 
        } 
 
        .accordion-example .accordion input[type="radio"]:checked + .baffle label { 
 
         background: #eee; 
 
         color: inherit; 
 
         box-shadow: inset 0 -1px rgba(0, 0, 0, .15); 
 
         font-weight: 300 
 
        } 
 
        .accordion-example .accordion input[type="radio"]:checked + .baffle:not(:first-of-type) label { 
 
         border-radius: 0 
 
        } 
 
        .accordion-example .accordion input[type="radio"]:not(:checked) + .baffle + input[type="radio"]:not(:checked) + .baffle label { 
 
         box-shadow: inset 0 1px rgba(0, 0, 0, .15); 
 
        } 
 
        .accordion-example ::-webkit-scrollbar { 
 
         width: .9375rem 
 
        } 
 
        .accordion-example ::-webkit-scrollbar-thumb { 
 
         background: #849cb1; 
 
         border: solid #eee; 
 
         border-width: .375rem .375rem .375rem 0; 
 
         border-radius: 0 .375rem .375rem 0 
 
        } 
 
        .accordion-example ::-webkit-scrollbar-thumb:window-inactive { 
 
         background: #aaa 
 
        }
<div class="accordion-example"> 
 
        <div class="accordion"> 
 
         <input type="radio" id="radio-option-1" name="accordion-radios" checked> 
 
         <div class="baffle"> 
 
          <label for="radio-option-1">Accordion</label> 
 
          <div class="baffle-inner"> 
 
           Accordions (from 19th century German Akkordion, from Akkord - “musical chord, concord of sounds”) are a family of box-shaped musical instruments of the bellows-driven free-reed aerophone type, colloquially referred to as a squeezebox. A person who plays the accordion is called an accordionist. The concertina and bandoneón are related; the harmonium and American reed organ are in the same family. 
 
          </div> 
 
         </div> 
 
         <input type="radio" id="radio-option-2" name="accordion-radios"> 
 
         <div class="baffle"> 
 
          <label for="radio-option-2">Lorem</label> 
 
          <div class="baffle-inner"> 
 
           <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tempus bibendum arcu non sodales. Aenean consequat viverra velit sed elementum. Sed id neque eu quam ultricies blandit ut a lacus. Maecenas et feugiat turpis. Suspendisse nec sem massa. Nullam aliquam sem nibh, non pretium ante posuere vitae. Pellentesque rutrum lacinia enim, eget ornare felis egestas vel. Mauris ullamcorper, ex sit amet pellentesque facilisis, tellus nulla sodales mauris, eu euismod ligula leo in diam. Morbi at leo sit amet est suscipit imperdiet at ac nibh. Fusce ex nisi, rutrum sed sollicitudin eget, rutrum id sapien. </p> 
 
          </div> 
 
         </div> 
 
         <input type="radio" id="radio-option-3" name="accordion-radios"> 
 
         <div class="baffle"> 
 
          <label for="radio-option-3">ipsum</label> 
 
          <div class="baffle-inner"> 
 
           Suspendisse sit amet lorem tempor, feugiat mauris quis, vehicula ante. Maecenas quis mauris quis tortor hendrerit bibendum et sed orci. Donec semper vel risus in scelerisque. Duis consectetur molestie dolor, eu aliquet ipsum maximus et. Ut massa sem, facilisis convallis nisi vel, posuere ullamcorper dolor. Donec accumsan ligula ornare ante convallis ornare. Donec lectus nibh, pharetra eget accumsan ac, vehicula quis elit. Nulla at mi ac metus ornare vehicula. Suspendisse ac metus maximus, semper est sed, gravida nisl. Nunc finibus lectus non magna congue malesuada. Cras auctor volutpat convallis. Pellentesque. 
 
          </div> 
 
         </div> 
 
        </div> 
 
       </div>

Ich hoffe, es hilft.

BEARBEITEN: Wegen der unerklärten Bitte von Dave Alperovich, einen passenden Code zum Thema Höhe und dynamischen Inhalt zu haben, poste ich den folgenden Code.

.accordion input[type="checkbox"], .accordion input[type="radio"] { 
 
    position:absolute; 
 
    left:-9999em 
 
} 
 

 
.accordion .baffle { 
 
    position:relative; 
 
    overflow:hidden; 
 
    height:100% 
 
} 
 

 
.accordion label { 
 
    display:block; 
 
    text-align:center; 
 
    padding:1em; 
 
    cursor:pointer; 
 
    height:100%; 
 
    background:#00bfa5; 
 
    color:#000; 
 
    font-weight:300; 
 
    letter-spacing:.13em; 
 
    text-transform:uppercase 
 
} 
 

 
.accordion label:hover { 
 
    background:#1de9b6 
 
} 
 

 
.accordion .baffle-inner { 
 
    padding:0 1.25em; 
 
    height:0; 
 
    opacity:0; 
 
    -webkit-transition:all 500ms ease-in-out; 
 
    -o-transition:all 500ms ease-in-out; 
 
    transition:all 500ms ease-in-out 
 
} 
 

 
.accordion > .baffle > input[type="checkbox"]:checked ~ .baffle-inner, .accordion > .baffle > input[type="radio"]:checked ~ .baffle-inner{ 
 
    padding:1.25em; 
 
    height:100%; 
 
    margin-bottom: 20px; 
 
    opacity:1 
 
} 
 

 
.accordion > .baffle > input[type="checkbox"]:checked ~ label, .accordion > .baffle > input[type="radio"]:checked ~ label { 
 
    background:#eee; 
 
    box-shadow:inset 0 -1px rgba(0,0,0,.4); 
 
    font-weight:300 
 
} 
 
.accordion > .baffle > input[type="checkbox"]:checked ~ label:hover, .accordion > .baffle > input[type="radio"]:checked ~ label:hover { 
 
    background:#1de9b6 
 
}
<div class="accordion"> 
 
    <div class="baffle"> 
 
     <input id="checkbox-option-1" type="checkbox" checked="checked" name="accordion-checkboxs"> 
 
     <label for="checkbox-option-1">Accordion</label> 
 
     <div class="baffle-inner"> 
 
      Accordions (from 19th century German Akkordion, from Akkord - “musical chord, concord of sounds”) are a family of box-shaped musical instruments of the bellows-driven free-reed aerophone type, colloquially referred to as a squeezebox. A person who plays the accordion is called an accordionist. The concertina and bandoneón are related; the harmonium and American reed organ are in the same family. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dignissim felis in lacinia vulputate. Vestibulum suscipit, lacus id tempus sagittis, ex orci molestie turpis, nec pharetra ligula arcu ac nisi. Donec in nisi arcu. Aenean non nisl purus. Fusce pretium lorem eget dui sollicitudin, eu gravida felis egestas. Vivamus orci tellus, efficitur at interdum vitae, ultricies quis urna. Sed ipsum eros, fermentum ornare ultrices vel, pharetra vitae metus. Sed ex metus, consectetur at tellus eget, porttitor molestie dolor. Duis nec metus non est tincidunt consectetur. Curabitur vel turpis sit amet leo fermentum cursus. Cras ligula erat, lobortis ut purus et, accumsan vestibulum lectus. Fusce sed nisl nisl. Aenean eget dolor lacinia, interdum ante id, fringilla orci. Cras eu porttitor est. 
 

 
Fusce dignissim lectus quis ligula aliquet pretium. Vestibulum consequat risus orci, ac consectetur dolor finibus quis. Aliquam erat volutpat. Proin nunc quam, suscipit eget elementum eu, rhoncus in tortor. Aenean vitae lacinia lorem, maximus elementum urna. Vivamus vitae posuere libero, a fermentum lorem. Duis placerat laoreet ipsum, et malesuada lacus aliquam vitae. 
 

 
Proin ut mauris ipsum. Suspendisse potenti. Mauris diam erat, ornare vitae tellus eget, elementum fringilla nunc. Maecenas eleifend enim non arcu blandit ullamcorper. Vivamus blandit dictum nulla, accumsan finibus leo blandit in. Curabitur nec tellus a nulla cursus semper. Sed fermentum velit quis pulvinar pellentesque. 
 
     </div> 
 
    </div> 
 
    <div class="baffle"> 
 
     <input id="checkbox-option-2" type="checkbox" name="accordion-checkboxs"> 
 
     <label for="checkbox-option-2">Construction</label> 
 
     <div class="baffle-inner"> 
 
      Accordions have many configurations and types. What may be technically possible to do with one accordion could be impossible with another: 
 
      <br>The accordion is a free reed instrument and is in the same family as other instruments such as the sheng and khaen. The sheng and khaen are both much older than the accordion and this type of reed did inspire the kind of free reeds in use in the accordion as we know it today.The accordion’s basic form is believed to have been invented in Berlin in 1822 by Christian Friedrich Ludwig Buschmann, although one instrument has been recently discovered that appears to have been built earlier. 
 
     </div> 
 
    </div> 
 
    <div class="baffle"> 
 
     <input id="checkbox-option-3" type="checkbox" name="accordion-checkboxs"> 
 
     <label for="checkbox-option-3">History</label> 
 
     <div class="baffle-inner"> 
 
      <p>The accordion is a free reed instrument and is in the same family as other instruments such as the sheng and khaen. The sheng and khaen are both much older than the accordion and this type of reed did inspire the kind of free reeds in use in the accordion as we know it today.</p> 
 
      <p>The accordion’s basic form is believed to have been invented in Berlin in 1822 by Christian Friedrich Ludwig Buschmann, although one instrument has been recently discovered that appears to have been built earlier.</p> 
 
     </div> 
 
    </div> 
 
</div>

Es ist eine Bearbeitung des ersten. Ich verwende Kontrollkästchen anstelle von Optionsfeldern und verwende eine nicht fixierte Höhe. Dies ist der Beweis dafür, dass es möglich ist.

Wenn Sie es nützlich finden, +1.

+0

Ich stimme zu, dass, wenn Sie ein Problem mit CSS lösen können, sollten Sie, aber wie behandelt dies das Problem der eingebetteten Akkordeons? Soweit ich sehen kann, wäre Ihre feste Höhe für dynamische Daten viel schlechter, auch wenn Sie keine verschachtelten Akkordeons berücksichtigen. –

+0

Offensichtlich sollten Sie wechselnde Breite und Höhe von 0 bis 100% verwenden. Testen Sie einfach Varianten des Codes und es wird so funktionieren, wie Sie es möchten. –

+0

Von Ihrer Antwort und Ihrer Antwort vermute ich, dass Sie das Beispiel des OP nicht verstanden haben und was die Aufgabe des OP schwierig macht. Wenn Sie eine dynamische Größe von Akkordeon haben, ist die Herausforderung, reines CSS zu verwenden, großartig. Das OP-Problem beschäftigt sich mit einem Akkorder dynamischer Daten mit verschachtelten Akkorden variabler Größe. Ihr Beispiel ist das Gegenteil. Es ist fest und einfach. ** Sie sind noch neu bei StackOverflow, scheinen aber sehr hilfsbereit zu sein. Ich fürchte, Sie sind begieriger zu helfen als das Problem zu verstehen. ** –