2017-06-13 59 views
0

我在頁面底部顯示彼此相鄰的多個div元素。具有動態寬度的元素的動態數量,直到填滿兩行

這些元素的數量和它們的寬度是未知的 - 這意味着我不提前知道它們,因爲它們根據一些其他規則動態加載。

我想要實現的是僅顯示這些元素的兩行,並且一旦其他元素在第三行中斷開,只顯示一些指示符,表示有更多元素可以擴展。

我不想在那裏有任何滾動條。

enter image description here

我使用jQuery和knockout.js。

當屏幕尺寸發生變化時,元件應重新組織。

JS

// all the elements representing the divs 
self.tags = ko.observableArray(); 
// disaplayed elements 
self.tagsPreview = ko.observableArray() 

HTML

<div id="tagsContainer"> 
    <!-- ko foreach: { data: tagsPreview, as: 'tag' } --> 
     <div data-bind="text: tag.title" class="tag"></div>    
    <!-- /ko --> 
</div> 

CSS

#tagsContainer .tag { 
    box-sizing: border-box; 
    display: inline-block;  
    height: 30px;  
    margin-top: 4px; 
    margin-right: 1px; 
    padding: 5px;   
} 

我不知道如何計算或找出應分配給tagsPreview觀察到的元素。有什麼建議麼?我不認爲這可以通過CSS來完成

回答

1

只需使用flexbox進行佈局,您可以在一半的位置獲得。

顯示溢出指示符是計算有多少行,也就是說有多少個不同的值在這些項目之間。

除了在afterRender中使用setMoreTags之外,您還希望在任何時候調整容器的大小時將其設置爲運行。

const names = ['one', 'two', 'three', 'four', 'five golden rings', 'six', 'seven', 'eight', 'nine', 'ten', 
 
    'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen' 
 
]; 
 
const vm = { 
 
    // all the elements representing the divs 
 
    tags: ko.observableArray([]), 
 
    moreTags: ko.observable(false), 
 
    setMoreTags: function() { 
 
    // Count how many different tops there are among the tags 
 
    // If more than two, moreTags is true 
 
    const tags = document.querySelectorAll('#tagsContainer .tag'); 
 
    const tops = {}; 
 
    
 
    for (const t of tags) { 
 
     tops[t.getBoundingClientRect().top] = true; 
 
    } 
 
    vm.moreTags(Object.keys(tops).length > 2); 
 
    } 
 
}; 
 

 
ko.applyBindings(vm); 
 

 
const i = setInterval(() => { 
 
    if (names.length) { 
 
    vm.tags.push({ 
 
     title: names.shift() 
 
    }); 
 
    } else { 
 
    clearInterval(i); 
 
    } 
 
}, 500);
#tagsContainer { 
 
    background-color: #eee; 
 
    display: flex; 
 
    flex-flow: row wrap; 
 
    max-height: 68px; 
 
    overflow: hidden; 
 
    position: relative; 
 
    width: 300px; 
 
} 
 

 
#tagsContainer .tag { 
 
    border: thin solid blue; 
 
    box-sizing: border-box; 
 
    height: 30px; 
 
    margin-top: 4px; 
 
    margin-right: 1px; 
 
    padding: 5px; 
 
} 
 

 
#tagsContainer .more-indicator { 
 
    background-color: red; 
 
    color: white; 
 
    font-size: 18px; 
 
    position: absolute; 
 
    bottom: 0; 
 
    right: 0; 
 
    padding: 5px; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<div id="tagsContainer"> 
 
    <!-- ko foreach: { data: tags, as: 'tag', afterRender: setMoreTags } --> 
 
    <div data-bind="text: tag.title" class="tag"></div> 
 
    <!-- /ko --> 
 
    <!-- ko if: moreTags --> 
 
    <div class="more-indicator">...</div> 
 
    <!-- /ko --> 
 
</div>

+0

謝謝!這是很棒的解決方案。我花了一段時間才弄明白它的工作原理,特別是我必須瞭解Flexbox佈局,但我喜歡它! – Martin

相關問題