2015-05-15 3 views
7

Я использую угловую аккордеонную директиву, чтобы скрыть/показать содержимое.Угловой Аккордеон, не увеличивающий высоту

Проблема, с которой я столкнулся, заключается в том, что высота контейнера контента не меняется.

Вот plunker: http://plnkr.co/edit/oWXrqoJpaYPDbe4TwT3c?p=preview

Если нажать на Show Более того, вы можете увидеть, как содержимое скрыто, а не высоту шоу-рабочих мест меняется.

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

Если я проверить элемент шоу-рабочих мест, я могу видеть, что это имеет начальную высоту 312px. Если я удалю это, то он работает так, как ожидалось.

+0

это можно решить с помощью css и Angular animations, если вы не полагались на css-логику, чтобы обернуть ваши строки после трех элементов. В противном случае ответ Кристины - лучшее решение, которое вы найдете. –

ответ

6

Как Giliar уже говорилось, проблема заключается в том, что у вас есть фиксированная высота, которая не позволяет ваш section элемент автоматически получать его высоту, чтобы соответствовать все его содержание (в том числе вновь расширил аккордеона). Решение, которое я могу предложить это (что также довольно много, что делает Bootstrap, насколько я могу сказать)

  1. Установите section «с Высотой до auto когда анимация закончена, так что, если вложенные дивы расширены section будет правильно расширяться.
  2. Заново установите фиксированную высоту в section, когда пользователь попытается закрыть ее, , прежде чем установить ее высоту на 0, чтобы анимация закрытия работала правильно.

Для первой части можно просто определить функцию, которая регулирует высоту section «s, чтобы auto и назвать его после расширения анимация закончена.

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

Поскольку расширение анимация занимает 0,7 секунды, вы можете просто вызвать функцию adjustHeightFunc с тайм-аутом 0,8 секунды (я это на самом деле не является оптимальным, так как если вы изменить продолжительность анимации вы также должны измените этот тайм-аут, но это лучшее решение, которое я нашел до сих пор, любые другие предложения приветствуются).Так, в конце вашей функции OnClick вы можете иметь:

$timeout(adjustHeightFunc, 800); 

Чтобы сделать вторую часть, чтобы не установить высоту section «s 0, когда секция должна быть свернута, но всегда устанавливать его на высоту его содержания. После того, как вы это сделаете, и если раздел должен быть свернут, вы вызываете отдельную функцию, используя $ timeout со значением 0 (чтобы он выполнялся в отдельном цикле дайджеста), который устанавливает высоту раздела в 0, тем самым вызывая крах анимация. Поэтому Ваша функция OnClick становится чем-то вроде этого:

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

ВИДЕТЬ updated Plunker.

РЕДАКТИРОВАТЬ: Как выясняется из комментариев, настройка closeAccordionFunc, выполняемая с таймаутом 0, не очень хорошо работает со всеми браузерами. Обходным путем для этого является объявление класса CSS, который установит высоту элемента в auto (с использованием !important, чтобы переопределить высоту, установленную непосредственно на элементе) и использовать услугу Angular $animate для добавления/удаления этого класса в элемент и выполнения closeAccordionFunc после класс удален. Таким образом, обновленный onClick функция:

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

Посмотри также in Plunker.

+0

спасибо, это почти что.Единственная проблема заключается в том, что при втором нажатии кнопки «Показать больше» выпавшее содержимое исчезает, а не ускоряется. –

+0

@OamPsy Вы уверены? Это фактически обрабатывается второй частью моего ответа выше, и я вижу, как аккордеон скользит вверх в моем Plunker. Какой браузер вы используете? – Christina

+0

yup, нажмите «Показать еще один раз», и содержимое сместится вниз. Нажмите снова на том же Show More, и содержимое моментально исчезнет, ​​а не замедляется. Usinf FF и Chrome. –

6

Если ваше намерение состоит в том, чтобы слайдер-контент-указатель скользил вверх и вниз, скрывая/показывая содержимое при нажатии кнопки, кажется, что он работает ... хорошо?

Хорошо, я вижу, что происходит. Хорошо, поэтому проблема заключается в том, что она имеет фиксированную высоту 300 пикселей. Вы можете переопределить его на высоту: auto ;, но это разрушит скользящую анимацию контейнера - потому что переходы требуют жестких значений для начала и конца переходов. Теперь есть как минимум два способа решить эту проблему:

  • Вы можете переделать его, чтобы он работал с максимальной высотой. См. Animating max-height with CSS transitions
  • Вы можете сделать это так, чтобы скользящая анимация контейнера при завершении расширения задала класс на переопределении высоты, а при нажатии кнопки «Показать мои вакансии >>» она вычисляет новую высоту контейнер и назначает его контейнеру inline. Кстати, эта проблема немного сложна. :-)
+0

№ Открыть плункер. Нажмите «Показать мои вакансии». Нажмите «Показать больше» из элемента в верхней строке. Обратите внимание, что второй ряд подталкивается под ним. –

+0

Я использовал максимальную высоту вместо высоты. Это не использование, если вы не хотите сильно переоценить его (как я). Они работают почти так же. Максимальная высота может дать вам аналогичный аффект и по-прежнему дает возможность выходить за пределы ... если вы надела достаточно. Но тогда проблема становится отсроченной реакцией на шкуру. Это гораздо худший подход, чем задержка Кристины/ –

1

Я думаю, что кодирование имеет смысл только в том случае, если вы можете писать меньше и делать больше (хорошо, это девиз jQuery, но он хороший). После этого ideea у меня есть css только аккордеон, что я действительно думаю, что это может быть полезно. Я уже разместил его here. Он основан на материале here. Основной идеей является утилита радиокнопок (она также может быть сделана с помощью флажков). Я думаю, что создание кода AngularJS для этого очень тяжелое. Код:

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

Я надеюсь, что это помогает.

EDIT: Из-за невыполненного запроса Дейва Алперовича получить соответствующий код по вопросу о высоте и динамическом содержимом, отправлю следующий код.

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

Это редактирование первого. Я использую флажки вместо переключателей и использую нефиксированную высоту. Это доказательство того, что это можно сделать.

Если вы сочтете это полезным, +1.

+0

Я согласен, что если вы можете решить проблему с CSS, вам следует, но как это касается проблемы встроенных аккордов? Насколько я вижу, ваша фиксированная высота будет намного хуже для динамических данных, даже без учета вложенных аккордов. –

+0

Очевидно, что вы должны использовать изменение ширины и высоты от 0 до 100%. Просто проверьте варианты кода, и он будет работать так, как вы хотите. –

+0

Из вашего ответа и ответа я подозреваю, что вы не поняли пример OP и что делает задачу OP сложной задачей. Когда у вас есть динамический размер гармоники, проблема использования чистого CSS велика. Проблема OP связана с гармоникой динамических данных с вложенными гармониками переменного размера. Ваш пример противоположный. Он фиксирован и прост. ** Вы все еще новичок в StackOverflow, но, похоже, очень хотите помочь. Я боюсь, что вы больше хотите помочь, чем понять проблему. ** –

Смежные вопросы