Скрипт динамической ширины

Кол-во колонок:

Ширина блоков:  

Блок №1

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium adipisci amet asperiores assumenda consequuntur distinctio d

Блок №2

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium adipisci amet asperiores assumenda consequuntur distinctio d

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium adipisci amet asperiores assumenda consequuntur distinctio d

Блок №3

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Блок №4

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Блок №5

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Блок №6

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium adipisci amet asperiores assumenda consequuntur distinctio d

Блок №7

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos eos error nemo neque quam rem vero voluptate? Assumenda, beatae iusto nam possimus suscipit temporibus voluptatem voluptatum. Adipisci animi autem veritatis?

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium adipisci amet asperiores assumenda consequuntur distinctio d

Иногда в задачах front-end разработки требуется равномерно распределить блоки и отступы между ними по ширине родительского контейнера. В качестве блоков могут использоваться, к примеру, карточки товаров на странице каталога или список фотографии в фотоблоге в несколько колонок. Понятно, что возможно сделать это версткой и без всяких скриптов, что даже предпочтительнее в некоторых случаях, но есть несколько ситуации для которых данный скрипт будет иметь ценность:

  • В связи с тем, что после последнего блока в текущем ряду требуется вставлять очищающий обтекание элемент (clearfix), в самом скрипте, выводящим верстку блоков необходимо предусмотреть данное обстоятельство. В зависимости от количества колонок потребуется вычислять последний элемент в каждом ряду и выводить clearfix, что иногда бывает немного утомительно. Теперь об этом можно забыть и при загрузке страницы скрипт будет сам формировать правильную верстку страницы

  • Следующая причина, в котором главная ценность, это динамика. Допустим, вам потребовалось динамически изменить количество колонок на странице (как в примере: см. «Демонстрация»), в таком случае, в зависимости от количества колонок, которое нужно сгенерировать, скрипт сам будет вычислять ширину каждого блока так, чтобы они равномерно распределились по ширине родительского блока и проставлять clearfix после последнего в текущем ряду блока. Обтекание отменяется и в самом конце, после всех блоков

Возможно сколько угодно делать колонок, главное чтобы они не превысили количество блоков, иначе скрипт не сработает, а выдаст ошибку, которая будет зарегистрирована в консоли:

Error flexibleWidth.js __line 27: The number of columns _ generated by the large number of items ._ per page

Также, если имеются блоки с таким же классом за пределами родительского контейнера, то будет ошибка:

Error flexibleWidth.js __line 20: Number of child elements ._ in container [object HTMLDivElement] It does not coincide with the total number of data items per page

Все элементы с идентифицирующим классом должны быть внутри родительского контейнера.

Пример верстки блоков и вызов

Установка

Не требует jQuery

<script src="...flexibleWidth.js"></script>

HTML, CSS, JS

<div id="item__container">       <!-- родительский контейнер (необязательно) -->
   <div class="item__div">         <!-- основной блок -->
      <div>                                   <!-- вспомогательный блок -->
         ...                                      <!-- содержимое -->
      </div>
   </div>
   ...
</div>
.item__div {
   margin-bottom: 30px;
}
.item__div>div {
   border: 1px solid;
   margin: 0 15px;
   padding: 15px;
}
window.onload = function () { _$_('item__div', 3); }       // бьем блоки на 3 колонки

Если на странице уже имеется событие загрузки, то нужно просто включить в него вызов $('className', count);

FAQ

  • Как задать равномерные отступы между блоками?
  • Здесь также ничего сложного нет: в каждом блоке создаем div и задаем ему внешние отступы, например margin:0 15px, для красоты можно сделать рамку с внутренними отступами padding
  • Как это работает?
  • Механизм такой: так как каждый блок нарезается на определенную ширину, выраженную в %, то внутренний divс внешними отступами будет создавать смещение от внешних границ блока тем самым создавая одинаковые отступы. Ширина каждого блока так же будет одинакова для всех. Подробнее можно разобрать demo

Исходный код

;
(function () {
    var version = 1.0;
    /*
     * main function flexibleWidth()
     * @param {string} c         Class elements
     * @param {number} cols      Number generated columns
     * @return {number}          Number processed items elementsLength
     * */
    function flexibleWidth(c, cols) {
        var elements = document.getElementsByClassName(c),
            elementsLength = elements.length,
            container = elements[0].parentNode,
            clears = document.getElementsByClassName('flexiblewidth__clear' + c);
        for (var i = 0, j = 0; i < container.childNodes.length; i++) {
            if (container.childNodes[i].className !== c)
                continue;
            j++;
        }
        if (elementsLength !== j) {
            console.log('Error flexibleWidth.js __line 20: Number of child elements .'
            + c
            + ' in container '
            + container
            + ' It does not coincide with the total number of data items per page');
            return;
        } else if (cols > j) {
            console.log('Error flexibleWidth.js __line 27: The number of columns ' + cols +
            ' generated by the large number of items .' + c + ' per page');
            return;
        } else {
            container.style.overflow = 'hidden';
            if (clears.length) {
                while (clears.length > 0) {
                    for (var i = 0; i < clears.length; i++) container.removeChild(clears[i]);
                }
                for (var i = 0; i < j; i++) reset(elements, i);
            }
            for (var i = 0; i < j; i++) {
                if (cols) {
                    if (i && i < (j - 1) && cols != 1) {
                        var clear = document.createElement("div"),
                            beforeE = elements[i * cols],
                            clearfix = container.insertBefore(clear, beforeE || null);
                        cl(clearfix, c);
                    }
                }
                calc(elements, i, cols);
            }
            if (cols && cols != 1 && cols >= 4) {
                if (!clears.length) {
                    for (var i = 1; i < cols - 1; i++) rm(container);
                } else {
                    for (var i = 2; i < cols - 1; i++) rm(container);
                }
                if (j / cols < 2) {
                    if (j - cols <= 1) rm(container); else for (var i = 0; i <= 1; i++) rm(container);
                } else {
                    if (!clears.length) {
                        for (var i = 0; i <= 2; i++) rm(container);
                    } else {
                        for (var i = 0; i <= 1; i++) rm(container);
                    }
                }
            }
            if (container.lastChild.className === 'flexiblewidth__clear' + c)
                clearMe('flexiblewidth__clear' + c, container);
            if (cols && cols != 1) {
                clearfix = container.insertBefore(document.createElement("div"), elements.lastChild || null);
                cl(clearfix, c);
            }
            return j;
        }
    }

    /*
     * make flexibility width
     * */
    function calc(elements, i, cols) {
        elements[i].style.width = 100 / cols + '%';
        if (cols && cols != 1)
            elements[i].style.float = 'left';
    }

    function reset(elements, i) {
        elements[i].style.width = '';
        elements[i].style.float = 'none';
    }

    /*
     * create clear
     * */
    function cl(el, cl) {
        el.style.clear = 'both';
        el.className = 'flexiblewidth__clear' + cl;
    }

    /*
     * remove last clear
     * */
    function rm(container) {
        var lastClear = container.lastChild;
        container.removeChild(lastClear);
    }

    /*
     * remove all last clear
     * */
    function clearMe(cl, el) {
        while (el.lastChild.className === cl)
            rm(el);
    }

    /*
     * exports to the global object
     * call:
     * _$_(class, column)
     *  *************************
     * */
    window._$_ = flexibleWidth;
})();

Github »



Похожие заметки:

Удобная разработка с livereload, установка browser-sync

Livereload — «живая» перезагрузка страниц в браузере, при изменении в файлах проекта. Обычно очень удобно при разработке нового проекта, когда постоянно вносятся и тестируются изменения, особенно если дебажим во многих вкладках и браузерах сразу

Открыть здесь

1561

Верстка

Услуги » верстка страниц сайта

Открыть здесь

279


Перед тем как писать комментарии, рекомендую ознакомиться:

Markdown синтаксис »

Оформление кода »

Нужна аватарка »

Комментарии