Dynamic aligning grid (w-2w)

by Alexey Zuev

HTML

<div class="layout">
    <button id="start">Перестроить</button>
    <div id="info"></div>
    <div class="container-wrapper">
        <div class="container">
            <div class="item" data-format="2w">1</div>
            <div class="item">2</div>
            <div class="item" data-format="2w">3</div>
            <div class="item">4</div>
            <div class="item">5</div>
            <div class="item" data-format="2w">6</div>
            <div class="item" data-format="2w">7</div>
            <div class="item">8</div>
            <div class="item">9</div>
            <div class="item" data-format="2w">10</div>
            <div class="item" data-format="2w">11</div>
            <div class="item">12</div>
            <div class="item" data-format="2w">13</div>
            <div class="item">14</div>
        </div>
    </div>

</div>

CSS

body {
    margin: 0;
    background: #fff;
    font-family: sans-serif;
}
.layout {
    width: 1000px;
    margin: auto;
}
.container {
    margin-left: -10px;
    font-size: 0;
}
.container:after {
    content:"";
    display: table;
    clear: both;
}
.item {
    float: left;
    width: 242.5px;
    height: 200px;
    line-height: 200px;
    margin-bottom: 10px;
    background: #222;
    margin-left: 10px;
    text-align: center;
    color: #fff;
    font-size: 3rem;
}
[data-format="2w"] {
    width: 495px;
}
#info {
    margin: 10px 0;
}
button {
    padding: 5px 10px;
    margin: 10px 0;
    background: #4CAF50;
    border: none;
    color: #fff;
    font-weight: bold;
    text-transform: uppercase;
    cursor: pointer;
}

JavaScript

document.getElementById('start').addEventListener('click', run);

function run() {
    var container = document.querySelector('.container'),
        children = container.children,
        items = Array.prototype.slice.call(children),
        info = document.getElementById('info');

    items.forEach(function (item) {
        item.weight = (item.dataset.format && item.dataset.format == '2w') ? 2 : 1;
    });

    var index = 0,
        sum = 0,
        weight,
        from, to,
        removed;

    while (index < items.length) {
        weight = items[index].weight;

        if (sum + weight <= 4) {
            sum += weight;
        } else if (!to) {
            to = index;
        }

        if (sum == 4) {
            sum = 0;
            if (to) {
                from = index;

                removed = items.splice(from, 1);
                items.splice(to, 0, removed[0]);
                container.insertBefore(children[from], children[to]);
                container.insertBefore(children[to + 1], children[from]);

                log('Смена ' + (from + 1) + ' с ' + (to + 1));

                index = to + 1;
                to = null;
                continue;
            }
        }
        index++;
    }

    function log(text) {
        info.appendChild(document.createTextNode(text));
        info.appendChild(document.createElement('br'));
    }
}