element query

by phloe

HTML

<div class="test large"></div>
<div class="test medium"></div>
<div class="test small"></div>
<div class="test small"></div>

CSS

.test {
    width: 40%;
    min-height: 100px;
    min-width: 20px;
    background-color: green;
    position: relative;
    float: left;
    margin: 10px;
}

.small {
    width: 20%;
}
.large {
    width: 80%;
}

.test[data-size=medium] {
    background-color: red;
}

.test[data-size=large] {
    background-color: blue;
}

JavaScript

// https://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/user/client/ui/ResizeLayoutPanel.java?r=11480

var elements = document.querySelectorAll(".test");
var i = 0;
var l = elements.length;

while (i < l) {
    listen(elements[i++], "data-size", {100: "medium", 300: "large"});
}


function listen (element, attr, sizes) {
    var lastWidth = -1;
    var expandable = document.createElement("div");
    var expandableInner = expandable.appendChild(expandable.cloneNode());
    expandableInner.style.height = "10px";
    expandable.style.cssText = "width: 100%; height: 100%; position: absolute; visibility: hidden; overflow: scroll; z-index: -1;";
    expandable.onscroll = check;
    
    var collapsible = expandable.cloneNode(true);
    collapsible.onscroll = check;
    var collapsibleInner = collapsible.childNodes[0];
    collapsibleInner.style.width = "200%";
    
    var widths = [];
    for (var width in sizes) {
        widths.push(width);
    }
    widths.sort();
    
    element.appendChild(expandable);
    element.appendChild(collapsible);
    
    setTimeout(check, 0);
    
    function check () {
        var width = element.offsetWidth;
        expandableInner.style.width = width + 100 + "px";
        expandable.scrollLeft = width + 100;
        collapsible.scrollLeft = collapsible.scrollWidth + 100;
        if (width != lastWidth) {
            var i = 0;
            var label = "";
            while (widths[i] < width) {
                label = sizes[widths[i++]];
            }
            
            element.setAttribute(attr, label);
            lastWidth = width;
        }
    }
}