2015-05-15 10 views
7

Sto usando una direttiva di fisarmonica angolare per nascondere/mostrare il contenuto.La fisarmonica angolare non espande l'altezza

Il problema che sto affrontando è che l'altezza del contenitore del contenuto non cambia.

Ecco un plunker: http://plnkr.co/edit/oWXrqoJpaYPDbe4TwT3c?p=preview

Se si fa clic su Visualizza più, si può vedere come il contenuto è nascosto piuttosto che l'altezza della show-cambiare lavoro.

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); 
     } 
    } 
}); 

Se i ispezionare l'elemento di mostra di posti di lavoro, posso vederlo ha un'altezza iniziale di 312px. Se rimuovo questo, allora funziona come previsto.

+0

questo potrebbe essere risolto con css e animazioni angolari se non si è basata sulla logica css per avvolgere le righe dopo 3 elementi. Altrimenti, la risposta di Christina è la migliore soluzione che troverai. –

risposta

6

Come già detto Giliar, il problema è che si dispone di un altezza fissa che non consente il vostro elemento section per ottenere automaticamente la sua altezza per adattarsi a tutti i suoi contenuti (tra cui la fisarmonica recentemente ampliato). La soluzione che posso proporre a questo (che è anche più o meno quello che fa Bootstrap per quanto posso dire)

  1. Impostare l'altezza section s' al auto quando l'animazione è finito, in modo che se div annidati sono espansi lo section si espande correttamente.
  2. Reimpostare un'altezza fissa su section quando l'utente tenta di chiuderla, prima di impostare l'altezza su 0, in modo che l'animazione di chiusura funzioni correttamente.

a fare la prima parte si può solo definire una funzione che consente di regolare l'altezza s' il section-auto e chiamarlo dopo l'animazione espansione è terminata.

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'; 
    } 
} 

Poiché l'animazione espandere prende 0,7 secondi si può chiamare la funzione adjustHeightFunc con un timeout di 0,8 secondi (ottengo questo non è davvero ottimale, dal momento che se si cambia la durata dell'animazione si dovrà anche a cambiare questo timeout, ma è la soluzione migliore che ho trovato finora, ogni altro suggerimento è benvenuto).Così, alla fine della funzione onClick si può avere:

$timeout(adjustHeightFunc, 800); 

di fare la seconda parte è quello di non impostare l'altezza s' il section-0 quando la sezione dovrebbe essere crollato, ma per sempre impostarlo all'altezza dei suoi contenuti. Dopo aver fatto ciò, e se la sezione deve essere compressa, si chiama una funzione separata che utilizza $ timeout con valore 0 (in modo che venga eseguita in un ciclo di digest separato) che imposta l'altezza della sezione su 0, innescando così il collasso animazione. La funzione onClick diventa quindi qualcosa di simile:

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); 
}); 

Vedere le updated Plunker.

EDIT: Come risulta dai commenti di impostazione del closeAccordionFunc da eseguire con timeout 0 non funziona bene con tutti i browser. Una soluzione per questo è dichiarare una classe CSS che imposterà l'altezza dell'elemento a auto (usando !important per sovrascrivere l'altezza impostata direttamente sull'elemento) e utilizzare il servizio $animate di Angular per aggiungere/rimuovere questa classe all'elemento ed eseguire il closeAccordionFunc dopo la classe è stata rimossa. La funzione di aggiornamento onClick quindi è:

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); 
    } 
}); 

Vedi anche in Plunker.

+0

grazie, questo è quasi arrivato.L'unico problema è che al secondo clic di Mostra altro, i contenuti rilasciati scompaiono, piuttosto che scorrere verso l'alto. –

+0

@OamPsy Ne sei sicuro? Questo in realtà è gestito dalla seconda parte della mia risposta sopra e posso vedere la fisarmonica scivolare nel mio Plunker. Quale browser utilizzate? – Christina

+0

sì, fai clic su Mostra altro una volta e il contenuto scorre verso il basso. Fai nuovamente clic su Mostra altro e il contenuto scompare all'istante anziché rallentare lo scorrimento. Usinf FF e Chrome. –

6

Se l'intenzione è tale che la direttiva del contenuto del cursore scorri verso l'alto e verso il basso, nascondendo/mostrando il contenuto mentre si fa clic sul pulsante, sembra che funzioni ... bene?

Ok, capisco cosa sta succedendo. Bene, quindi il problema sembra essere che ha un'altezza fissa di 300 px. Puoi sovrascriverlo in altezza: auto; ma ciò interromperà l'animazione scorrevole del contenitore, perché le transizioni necessitano di valori rigidi per l'inizio e la fine delle transizioni. Ora, ci sono almeno due modi per risolvere questo:

  • È possibile rielaborarlo per farlo funzionare con altezza massima. Vedi Animating max-height with CSS transitions
  • Si può fare in modo che l'animazione scorrevole del contenitore quando l'espansione è terminata, impostare una classe su quella che sovrascrive l'altezza e quando si fa clic sul pulsante "Mostra i miei lavori >>", calcola la nuova altezza del contenitore e lo assegna al contenitore in linea. A proposito, questo problema è un po 'difficile da risolvere. :-)
+0

No. Aprire il plunker. Fai clic su Mostra i miei lavori. Fai clic su Mostra altro da un articolo nella riga superiore. Osserva che la seconda fila viene spinta sotto. –

+0

Ho usato altezza massima invece di altezza. Questo non è l'uso a meno che non vogliate sopravvalutarlo grossolanamente (come ho fatto io). Funzionano quasi allo stesso modo. L'altezza massima può darti un effetto simile e dare comunque spazio ad una crescita superiore a ... se ne hai abbastanza. Ma poi il problema diventa reazione ritardata su hide. Questo è un approccio molto peggiore del ritardo di Christina/ –

1

Penso che la codifica abbia senso solo se si riesce a scrivere di meno e si fa di più (ok, è il motto di jQuery, ma è buono). Seguendo quell'ideologia ho una sola fisarmonica che penso davvero che possa essere utile. L'ho già pubblicato here. È basato sul materiale here. L'ideea principale è l'utilità dei pulsanti di opzione (può anche essere effettuata con caselle di controllo). Penso che fare un codice AngularJS per questo sia molto pesante. Il codice è:

    .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>

spero che aiuta.

MODIFICA: A causa della richiesta incalcolabile di Dave Alperovich di avere un codice appropriato sul problema dell'altezza e del contenuto dinamico, inserisco il seguente codice.

.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>

Si tratta di una modifica del primo. Uso le caselle di controllo anziché i pulsanti di opzione e utilizzo un'altezza non fissa. Questa è la prova che può essere fatto.

Se lo trovi utile, +1.

+0

Concordo sul fatto che se è possibile risolvere un problema con i CSS, dovresti farlo, ma in che modo questo risolve il problema dei fisarmonicisti incorporati? Per quanto posso vedere, la tua altezza fissa sarebbe molto peggio per i dati dinamici, anche senza contare gli accordian annidati. –

+0

Ovviamente, è necessario utilizzare la modifica della larghezza e dell'altezza da 0 a 100%. Basta testare le varianti del codice e funzionerà nel modo desiderato. –

+0

Dalla vostra risposta e risposta, sospetto che non abbiate compreso l'esempio del PO e che cosa rende difficile il compito dell'OP. Quando hai dimensioni dinamiche di accordian, la sfida di usare puro CSS è grande. Il problema dell'OP riguarda un accordian di dati dinamici con fisarmoniche annidate di dimensioni variabili. Il tuo esempio è il contrario. È fisso e semplice. ** Sei ancora nuovo in StackOverflow ma sembra molto desideroso di aiutare. Temo che tu sia più desideroso di aiutare che capire il problema. ** –