Skip to content

Instantly share code, notes, and snippets.

@klihelp
Last active September 18, 2018 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klihelp/ccf854c6c3d356e3af131670642f6925 to your computer and use it in GitHub Desktop.
Save klihelp/ccf854c6c3d356e3af131670642f6925 to your computer and use it in GitHub Desktop.
Fill Space Up
/**
* Fill Space Up
* ver 0.1.0
*
* Repeater to fillup remaining screen space in the line.
* @TD Make it work for row and column, initial alignment of horizontally or vertically
* @TD Make calculations with js, without wrapping elements into div
*
* use:
* fill_space_up('.item');
* fill_space_up({item:'.item'});
* fill_space_up({reference:'.reference',item:'.item'});
*
* Test:
* https://jsfiddle.net/guht49La/454/
*/
var fill_space_up = function(params) {
var ver = '0.1.0'
// @TD validate params
// params item or string
if ( typeof params === 'string' ) {
params = { item: params }
}
if ( ! params.hasOwnProperty('item') ) {
//return false
}
// Print info with grobal print_log() or silence locally
var silent_log = 1,
print_log = function(log){
if (silent_log) {
return;
}
if (log !== 'undefined' && log) {
console.log(log)
}
}
var
// @TD typechecking for strings, than classes and ids
//@TD find all containers automatically
//and run
$items,
$container,
$wrap,
$reference,
vars = [],
reference_height,
reference_outerHeight,
container_height,
items_height,
space_height,
init = function() {
prepare_items()
measure()
test_init()
init_cloning()
},
get_items = function() {
return params.hasOwnProperty('container') ? $(params.item, params.container) : $(params.item)
},
set_items = function() {
$items = get_items()
},
set_wrap = function() {
$wrap = $container
if ( params.hasOwnProperty('container') ) {
//@TD check container has the wrap class, otherwise look for wrap
if ( $items.parents(params.container).length ) {
$wrap = $items.parents(params.container)
}
}
},
set_container = function() {
$container = $items.parent().addClass('js_container')
},
set_reference = function() {
if ( params.hasOwnProperty('reference') ){
$reference = $(params.reference)
return
}
// @TD make it work for items in different containers
/* if ( typeof $cont !== "undefined" && $cont.length && $cont.height() >= sum_heights($items) ) {
$reference = $cont
return
}
*/
var $ref = $items.parent()
// reference can be calculated to the closest tallest parent
$container.parents().each(function () {
var
$this = $(this)
$parent = $(this).parent()
if ( $parent.height() > $this.outerHeight(true) ){
$ref = $parent
return false
}
if ( $parent.get().tagName == 'body' ) {
return false
}
});
$reference = $ref
},
get_container_wrap_outer = function() {
var $outer = 0
if ( $container.outerHeight(true) > $container.height() ) {
$outer = $container.outerHeight(true) - $container.height()
}
if ( ! $wrap.is($container) ){
if ( $wrap.outerHeight(true) > $wrap.height() ) {
$outer =+ $wrap.outerHeight(true) - $wrap.height()
}
}
return $outer
},
set_vars = function() {
container_height = get_elem_innerHeight($container)
reference_height = $reference.outerHeight(false) - get_container_wrap_outer()
},
prepare_items = function() {
set_items()
$items.addClass('original')
$items.wrapAll('<div class="js_wrap_items" style="display:block;padding:0;margin:0;">')
set_container()
set_wrap()
set_reference()
set_vars()
},
sum_heights = function( $nodes ) {
var height = 0
$nodes.each( function(){
height += $(this).outerHeight(true)
})
return height
},
get_elem_innerHeight = function( $elem ) {
var height = $elem.height(),
collapsed_margin_bottom
//@TD get collapsed top and bottom margins
//var collapsed_margin_bottom = parseInt($elem.children().last().css("margin-bottom"))
//var collapsed_margin_bottom = collapsed_margin_bottom ? collapsed_margin_bottom : parseInt($elem.children().last().children().last().css("margin-bottom"))
//print_log('collapsed_margin ' + collapsed_margin_bottom)
//print_log($elem.children().last())
//print_log($elem)
if ( collapsed_margin_bottom ){
height += collapsed_margin_bottom
}
return height
},
measure = function(print) {
var
old_items_height = items_height,
old_space_height = space_height
// @TD callculate items height with collapsed margins
// items_height = sum_heights(get_items());
items_height = $container.height();
space_height = reference_height - items_height;
container_height = get_elem_innerHeight($container)
if (print !== 0) {
print_log('> Now Space ' + space_height + ' / was ' + (old_space_height || space_height));
print_log('> Now Items ' + sum_heights(get_items()) + ' / was ' + (old_items_height || items_height));
print_log('----');
}
},
init_cloning = function() {
clone_if_has_space()
},
intelligent_cloning = function() {
if (!repeat_container()) {
repeat_items()
measure()
}
},
clone_if_has_space = function() {
intelligent_cloning()
},
repeat_container = function() {
if (reference_height < items_height) {
return false;
}
//* @TD remove class .original from the cloned items
var
html = $container.html(),
count = Math.floor( (reference_height - items_height ) / items_height)
console.log(count)
console.log(reference_height)
console.log(items_height)
for (var i = 0; i < count; i++) {
$container.append(html)
}
measure()
$container.data('repeated', ($container.data('repeated') || 0) + count || 1);
print_log('> Re-added items x' + $container.data('repeated'));
},
repeat_items = function() {
if ( reference_height < items_height || space_height < 0) {
return false;
}
if ($('.nospace', $items).length >= $items.length) {
$('.nospace', $items).removeClass('.nospace')
return false
}
var nr = 0
$items.each(function(index) {
$this = $(this)
print_log('space_height - '+ space_height)
if (space_height < $this.outerHeight(true)) {
$this.addClass('nospace')
return;
}
//$this.clone().appendTo($container);
$container.append( $this.clone().addClass('copy').removeClass('original') )
nr++
print_log('> readded item #' + index);
measure(0)
})
print_log('> Re-added '+ nr +' items');
},
END_OF_FUNCTIONS
test_init = function() {
print_log('Reference class: ' + ( params.hasOwnProperty('reference') ? params.reference : $reference.attr("class")) );
print_log('Container class: ' + ( params.hasOwnProperty('container') ? params.container : $container.attr("class")) );
print_log('Items class: ' + params.item);
print_log('Items lenght: ' + $items.length);
print_log('Reference height: ' + reference_height);
print_log('Container height: ' + container_height);
print_log('Items height: ' + sum_heights($items) );
print_log('Space height: ' + reference_height + '-' + sum_heights($items) + ' = ' + space_height);
print_log('----');
}
return init()
}
/**
* Fill Space Up
* ver 0.1.0
*
* Repeater to fillup remaining screen space in the line.
* @TD Make it work for row and column, initial alignment of horizontally or vertically
* @TD Make calculations with js, without wrapping elements into div
* use:
* fill_space_up('.item');
* fill_space_up({item:'.item'});
* fill_space_up({reference:'.reference',item:'.item'});
*
* Test:
* https://jsfiddle.net/guht49La/454/
*
*/
var fill_space_up=function(e){"string"==typeof e&&(e={item:e}),e.hasOwnProperty("item");var t,n,r,a,i,o,s,c=function(){return e.hasOwnProperty("container")?$(e.item,e.container):$(e.item)},h=function(){var e;u(n),i=a.outerHeight(!1)-(e=0,n.outerHeight(!0)>n.height()&&(e=n.outerHeight(!0)-n.height()),r.is(n)||r.outerHeight(!0)>r.height()&&(e=+r.outerHeight(!0)-r.height()),e)},p=function(e){var t=0;return e.each(function(){t+=$(this).outerHeight(!0)}),t},u=function(e){var t=e.height();return t},l=function(e){o=n.height(),s=i-o,u(n),0!==e&&p(c())},g=function(){f()},f=function(){d()||(v(),l())},d=function(){if(i<o)return!1;var e=n.html(),t=Math.floor((i-o)/o);console.log(t),console.log(i),console.log(o);for(var r=0;r<t;r++)n.append(e);l(),n.data("repeated",(n.data("repeated")||0)+t||1),n.data("repeated")},v=function(){if(i<o||s<0)return!1;if($(".nospace",t).length>=t.length)return $(".nospace",t).removeClass(".nospace"),!1;t.each(function(e){$this=$(this),s<$this.outerHeight(!0)?$this.addClass("nospace"):(n.append($this.clone().addClass("copy").removeClass("original")),0,l(0))})};return test_init=function(){e.hasOwnProperty("reference")?e.reference:a.attr("class"),e.hasOwnProperty("container")?e.container:n.attr("class"),e.item,t.length,p(t),p(t)},function(){(t=c()).addClass("original"),t.wrapAll('<div class="js_wrap_items" style="display:block;padding:0;margin:0;">'),n=t.parent().addClass("js_container"),r=n,e.hasOwnProperty("container")&&t.parents(e.container).length&&(r=t.parents(e.container)),function(){if(e.hasOwnProperty("reference"))a=$(e.reference);else{var r=t.parent();n.parents().each(function(){var e=$(this);return $parent=$(this).parent(),$parent.height()>e.outerHeight(!0)?(r=$parent,!1):"body"!=$parent.get().tagName&&void 0}),a=r}}(),h()}(),l(),test_init(),void g()};
// DOCUMENT RUN
setTimeout(function() {
$(document).ready(function() {
// Call
//fill_space_up('.item');
fill_space_up({
reference:'.reference',
item:'.item'
});
})
}, 0)
<div class="reference"></div>
<div class="wrap">
<div class="list">
<div class="item"><div class="frame">1</div></div>
<div class="item"><div class="frame">2</div></div>
<div class="item"><div class="frame">3</div></div>
<div class="item"><div class="frame last-ad">
<div class="ad">4</div>
</div></div>
</div>
</div>
html, body{
min-height:100vh;
}
.item {
width: 60%;
border:5px solid blue;
margin-bottom:5px;
padding:10px;
overflow: hidden;
position:relative;
display:block;
}
.frame{
height:30px;
background:rgba(0,0,0,0.3);
text-align: center;
font-size: large;
}
.list .original{background: yellow;}
.item:nth-child(4n){
background: lightgreen;
}
.item:nth-child(4n+1){
background: orange;
}
.item:nth-child(4n+2){
background: lightblue;
}
.copy{opacity:0.40;border-colour: purple;}
.reference{float:left;position:absolute;width:50px; height:160vh; background:lightpink;}
.wrap{min-height:80vh; margin:5px 50px; border:1px dashed blue;}
.list{background:rgba(150,240,c,0.5);owerflow:10;}
/* for collapsed margin testing*/
.last-ad{
padding: 2px;
margin-bottom:15px;
}
.last-ad .ad{
background:gray;
margin-bottom:10px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment