Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!doctype html>
<head>
<meta charset="UTF-8">
<!-- <script src="detect-element-resize.js"></script>  <!-- NOTE: This Script in the JavaScript Tab --> 
<!-- <script src="jquery.min.js"></script>             <!-- No jQuery needed -->
<style>
.flex{ display: -webkit-flex; display: -ms-flexbox; display: flex; }
.wrap{ -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap;}
.cont {
  border: 1px solid grey;
  margin: auto;
  width: 448px;
  padding-right: 0;
  padding-bottom: 0;
  /*flex-direction: column;height: 225px;align-content: flex-start;*/
}
.controls{
  width: 500px; 
  margin: auto;
  justify-content: space-around;
  text-align: center;
}
.elem {
  border: 1px solid blue;
  text-align:center;
  /* float: left;  /* Can Float it, or use Flexbox, either way */
}
input{
 width: 25px; color: blue;
}
#resizableBorder{
 resize: horizontal;
 overflow: auto;
}
</style>
<style id="jsManipulated">
.elem {
    height: 100px;
    width: 100px;
    line-height: 100px;
    margin-right: 10px;
    margin-bottom: 10px;
}
.cont {
    padding-top: 10px;
    padding-left: 10px;
}
</style>
</head>
<body>
<br> 
<div class="flex controls">
    <a target="_blank" href="https://stackoverflow.com/questions/29125444/equal-number-of-element-per-row-with-flexbox">StackOverflow</a>
  <button id="adder">(+) add item</button>
  <button id="remover">(-) remove item</button>
  <span> Box Size: 
    <input id="sizer" type="text" value="100" boxCountlength="3" onkeypress='return event.charCode > 47 && event.charCode < 58'>
  </span>
  <span> Padding: 
    <input id="padder" type="text" value="10" boxCountlength="3" >
</div>
<br><hr><br>
<div id="resizableBorder" class="cont flex wrap">
  <div class="elem"> 1</div><div class="elem"> 2</div><div class="elem"> 3</div>
  <div class="elem"> 4</div><div class="elem"> 5</div><div class="elem"> 6</div>
  <div class="elem"> 7</div><div class="elem"> 8</div><div class="elem"> 9</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function(){
  
  var boxCount = 9;
  var boxWidth = 100;
  var boxBorderWidth = 10;
  var adder = document.getElementById('adder');
  var remover = document.getElementById('remover');
  var sizer = document.getElementById('sizer');
  var padder = document.getElementById('padder');
  var flexParent = document.getElementsByClassName('cont')[0];
  var styleEle = document.getElementById('jsManipulated');
  var resizableBorder = document.getElementById('resizableBorder');
  
  function addItem(){
    console.log("add");
    var newItem = document.createElement('div');
    newItem.className += 'elem';
    newItem.innerHTML = ++boxCount;
    flexParent.appendChild( newItem );
    repaint();
  }
  function removeItem(){
    console.log("remove");
    if(boxCount != 0){
        --boxCount;
        //flexParent.removeChild(flexParent.lastChild);
    var position = flexParent.children.length -1;
    if( flexParent.children[position].className == "resize-triggers"){ --position; } //ignore resize-triggers div.
        flexParent.removeChild( flexParent.children[ position ] );
        repaint();
    }
  }
  function resizeBoxes(event) {
    if( event.keyCode > 47 && event.keyCode < 58){ boxWidth = this.value; } 
    else if( event.keyCode == 40 ){ boxWidth = --this.value;  }
    else if( event.keyCode == 38 ){ boxWidth = ++this.value; }
    else { 
        console.log('non-numeric keypress ignored: '+event.keyCode); 
        return;
        }
    updateBoxStyles( boxWidth, boxBorderWidth);
  }
  function repadBoxes(event) {
    if( event.keyCode > 47 && event.keyCode < 58){ boxBorderWidth= this.value; } 
    else if( event.keyCode == 40 ){ boxBorderWidth = --this.value; }
    else if( event.keyCode == 38 ){ boxBorderWidth = ++this.value;}
    else { 
        console.log('non-numeric keypress ignored: '+event.keyCode); 
        return;
        }
    updateBoxStyles( boxWidth, boxBorderWidth);
  }
  function updateBoxStyles( size, edge ){
    styleEle.innerHTML = 
    ".elem { height: "
    +size+"px; width: "
    +size+"px; line-height: "
    +size+"px; margin-right: "
    +edge+"px; margin-bottom: "
    +edge+"px;} .cont { padding-top: "
    +edge+"px; padding-left: "
    +edge+"px;}"
    repaint();
  }
  /* LISTENERS */
  window.onresize = repaint; //Only needed if 'width' of container is a percentage ex: '.cont{width:60%}'
  adder.addEventListener('click', addItem );
  remover.addEventListener('click', removeItem );
  sizer.addEventListener('keyup', resizeBoxes );
  padder.addEventListener('keyup', repadBoxes );
  addResizeListener( resizableBorder, repaint); //using the 'detect-element-resize.js library'
  
  /** Most Important Function Called Everytime Anything Changes, in order to keep elements to the left using 'margin-right' **/
  repaint(); //initial resize on pageload;
  function repaint() {
      console.log('repaint');
      var elementWidth = 2- -boxWidth- -boxBorderWidth; // 2 because: border is 1px*2, '- -' because '+' causes string concatination.
      var elements = document.getElementsByClassName('elem');
      var count = elements.length;
      var parentWidth = parseInt( window.getComputedStyle( flexParent).getPropertyValue('width') );
      var rowsCount = Math.ceil( count / Math.floor(parentWidth/elementWidth) );
      var perRow = Math.floor( count / rowsCount);
      var extra = count % rowsCount;
      for (var i=0, ele; ele = elements[i]; i++) {
      ele.style["margin-right"] = "";
      }
      if( rowsCount == Infinity || rowsCount == 0){ return; }//when elementWidth < parentWidth or Zero Boxes
      var allPrevRowsTotal = 0;
      for (var i = 1; i <= rowsCount && rowsCount > 1; i++) {
      var perThisRow = perRow;
      if( extra != 0){ --extra; perThisRow++; }
      elements[ allPrevRowsTotal + perThisRow - 1 ].style["margin-right"] = parentWidth - (perThisRow * elementWidth) +"px";
      allPrevRowsTotal += perThisRow;
      }
  }
});
</script>
</body>
 
/**
* Detect Element Resize
*
* https://github.com/sdecima/javascript-detect-element-resize
* Sebastian Decima
*
* version: 0.5.3
**/
(function () {
    var attachEvent = document.attachEvent,
        stylesCreated = false;
    
    if (!attachEvent) {
        var requestFrame = (function(){
            var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
                                function(fn){ return window.setTimeout(fn, 20); };
            return function(fn){ return raf(fn); };
        })();
        
        var cancelFrame = (function(){
            var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
                                   window.clearTimeout;
          return function(id){ return cancel(id); };
        })();
        function resetTriggers(element){
            var triggers = element.__resizeTriggers__,
                expand = triggers.firstElementChild,
                contract = triggers.lastElementChild,
                expandChild = expand.firstElementChild;
            contract.scrollLeft = contract.scrollWidth;
            contract.scrollTop = contract.scrollHeight;
            expandChild.style.width = expand.offsetWidth + 1 + 'px';
            expandChild.style.height = expand.offsetHeight + 1 + 'px';
            expand.scrollLeft = expand.scrollWidth;
            expand.scrollTop = expand.scrollHeight;
        };
        function checkTriggers(element){
            return element.offsetWidth != element.__resizeLast__.width ||
                         element.offsetHeight != element.__resizeLast__.height;
        }
        
        function scrollListener(e){
            var element = this;
            resetTriggers(this);
            if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
            this.__resizeRAF__ = requestFrame(function(){
                if (checkTriggers(element)) {
                    element.__resizeLast__.width = element.offsetWidth;
                    element.__resizeLast__.height = element.offsetHeight;
                    element.__resizeListeners__.forEach(function(fn){
                        fn.call(element, e);
                    });
                }
            });
        };
        
        /* Detect CSS Animations support to detect element display/re-attach */
        var animation = false,
            animationstring = 'animation',
            keyframeprefix = '',
            animationstartevent = 'animationstart',
            domPrefixes = 'Webkit Moz O ms'.split(' '),
            startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
            pfx  = '';
        {
            var elm = document.createElement('fakeelement');
            if( elm.style.animationName !== undefined ) { animation = true; }    
            
            if( animation === false ) {
                for( var i = 0; i < domPrefixes.length; i++ ) {
                    if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
                        pfx = domPrefixes[ i ];
                        animationstring = pfx + 'Animation';
                        keyframeprefix = '-' + pfx.toLowerCase() + '-';
                        animationstartevent = startEvents[ i ];
                        animation = true;
                        break;
                    }
                }
            }
        }
        
        var animationName = 'resizeanim';
        var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
        var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
    }
    
    function createStyles() {
        if (!stylesCreated) {
            //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
            var css = (animationKeyframes ? animationKeyframes : '') +
                    '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
                    '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
                head = document.head || document.getElementsByTagName('head')[0],
                style = document.createElement('style');
            
            style.type = 'text/css';
            if (style.styleSheet) {
                style.styleSheet.cssText = css;
            } else {
                style.appendChild(document.createTextNode(css));
            }
            head.appendChild(style);
            stylesCreated = true;
        }
    }
    
    window.addResizeListener = function(element, fn){
        if (attachEvent) element.attachEvent('onresize', fn);
        else {
            if (!element.__resizeTriggers__) {
                if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
                createStyles();
                element.__resizeLast__ = {};
                element.__resizeListeners__ = [];
                (element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
                element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
                                                                                        '<div class="contract-trigger"></div>';
                element.appendChild(element.__resizeTriggers__);
                resetTriggers(element);
                element.addEventListener('scroll', scrollListener, true);
                
                /* Listen for a css animation to detect element display/re-attach */
                animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
                    if(e.animationName == animationName)
                        resetTriggers(element);
                });
            }
            element.__resizeListeners__.push(fn);
        }
    };
    
    window.removeResizeListener = function(element, fn){
        if (attachEvent) element.detachEvent('onresize', fn);
        else {
            element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
            if (!element.__resizeListeners__.length) {
                    element.removeEventListener('scroll', scrollListener);
                    element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
            }
        }
    }
})();
Output

This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account

Dismiss x
public
Bin info
anonymouspro
0viewers