Created
November 17, 2015 10:38
-
-
Save anonymous/d61c9e19f68d0855c9f7 to your computer and use it in GitHub Desktop.
JS Bin // source http://jsbin.com/secaq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<script src="https://rawgit.com/lhorie/mithril.js/next/mithril.js"></script> | |
<script id="jsbin-javascript"> | |
// noprotect | |
function occluder(children) { | |
var childrenHeights; | |
var containerHeight; | |
var viewport, offset; | |
var ready = false; | |
var dom, container; | |
var occlusion = []; | |
function scroller(el, isInit) { | |
if (!isInit) { | |
el.addEventListener("scroll", scroll); | |
viewport = el.offsetHeight; | |
} | |
} | |
function setup(el, isInit) { | |
dom = Array.prototype.slice.call(el.childNodes); | |
childrenHeights = []; | |
containerHeight = 0; | |
for (var height, i = 0; i < el.childNodes.length; i++) { | |
height = el.childNodes[i].getBoundingClientRect().height; | |
childrenHeights.push(height); | |
containerHeight += height; | |
} | |
ready = true; | |
console.log("REDRAW!!!!"); | |
( requestAnimationFrame || setTimeout )( m.redraw ); | |
} | |
function scroll(e) { | |
offset = e.target.scrollTop; | |
var newOcclusion = calculateOcclusion(); | |
if (newOcclusion[newOcclusion.length - 1] != occlusion[occlusion.length - 1] || newOcclusion[0] != occlusion[0]) { | |
occlusion = newOcclusion; | |
console.time("redraw"); | |
update(); | |
console.timeEnd("redraw"); | |
} | |
} | |
function restart() { | |
ready = false; | |
m.redraw(true); | |
} | |
function view(template) { | |
console.log("READY", ready); | |
if (ready) { | |
return m("", {config: setContainer, style: {position: "relative", height: containerHeight + "px"}}) | |
} else { | |
return m("", {config: setup}, children.map(template)); | |
} | |
} | |
function setContainer(el) { | |
console.log("Set container to", el); | |
container = el; | |
update(); | |
} | |
function update() { | |
var inner = document.createElement("div"); | |
inner.style.position = "relative"; | |
inner.style.top = offset + "px"; | |
container.style.top = "-" + topOffset() + "px"; | |
for (var i = 0; i < occlusion.length; i++) { | |
inner.appendChild(dom[occlusion[i]]); | |
} | |
container.innerHTML = ""; | |
container.appendChild(inner); | |
} | |
function calculateOcclusion() { | |
var past = 0; | |
var shown = []; | |
for (var i = 0; i < children.length; i++) { | |
var height = childrenHeights[i]; | |
if (offset >= past + height) { | |
past += height; | |
} else if(past < offset + viewport) { | |
past += height; | |
shown.push(i); | |
} else { | |
break; | |
} | |
} | |
return shown; | |
} | |
function occlusionStyle() { | |
return { | |
position: "relative", | |
height: containerHeight + "px", | |
top: "-" + topOffset() + "px" | |
}; | |
} | |
function topOffset() { | |
var past = 0; | |
for (var i = 0; i < childrenHeights.length; i++) { | |
if (past + childrenHeights[i] > offset) { | |
return offset - past; | |
} else { | |
past += childrenHeights[i]; | |
} | |
} | |
} | |
return { | |
view: view, | |
restart: restart, | |
scroller: scroller | |
}; | |
} | |
var items = [] | |
for(var i = 0; i < 5000; i++) { | |
items.push({ | |
title: 'Foo Bar ' + i | |
}) | |
} | |
var app = { | |
controller: function() { | |
return { | |
occlusion: occluder(items) | |
} | |
}, | |
view: function(scope) { | |
console.log("VIEW"); | |
return m(".scroller", { | |
config: scope.occlusion.scroller, | |
style: {overflow: "auto", height: "500px"} | |
}, scope.occlusion.view(function(item) { | |
return m("", item.title); | |
}) | |
) | |
} | |
} | |
m.mount(document.body, app); | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">// noprotect | |
function occluder(children) { | |
var childrenHeights; | |
var containerHeight; | |
var viewport, offset; | |
var ready = false; | |
var dom, container; | |
var occlusion = []; | |
function scroller(el, isInit) { | |
if (!isInit) { | |
el.addEventListener("scroll", scroll); | |
viewport = el.offsetHeight; | |
} | |
} | |
function setup(el, isInit) { | |
dom = Array.prototype.slice.call(el.childNodes); | |
childrenHeights = []; | |
containerHeight = 0; | |
for (var height, i = 0; i < el.childNodes.length; i++) { | |
height = el.childNodes[i].getBoundingClientRect().height; | |
childrenHeights.push(height); | |
containerHeight += height; | |
} | |
ready = true; | |
console.log("REDRAW!!!!"); | |
( requestAnimationFrame || setTimeout )( m.redraw ); | |
} | |
function scroll(e) { | |
offset = e.target.scrollTop; | |
var newOcclusion = calculateOcclusion(); | |
if (newOcclusion[newOcclusion.length - 1] != occlusion[occlusion.length - 1] || newOcclusion[0] != occlusion[0]) { | |
occlusion = newOcclusion; | |
console.time("redraw"); | |
update(); | |
console.timeEnd("redraw"); | |
} | |
} | |
function restart() { | |
ready = false; | |
m.redraw(true); | |
} | |
function view(template) { | |
console.log("READY", ready); | |
if (ready) { | |
return m("", {config: setContainer, style: {position: "relative", height: containerHeight + "px"}}) | |
} else { | |
return m("", {config: setup}, children.map(template)); | |
} | |
} | |
function setContainer(el) { | |
console.log("Set container to", el); | |
container = el; | |
update(); | |
} | |
function update() { | |
var inner = document.createElement("div"); | |
inner.style.position = "relative"; | |
inner.style.top = offset + "px"; | |
container.style.top = "-" + topOffset() + "px"; | |
for (var i = 0; i < occlusion.length; i++) { | |
inner.appendChild(dom[occlusion[i]]); | |
} | |
container.innerHTML = ""; | |
container.appendChild(inner); | |
} | |
function calculateOcclusion() { | |
var past = 0; | |
var shown = []; | |
for (var i = 0; i < children.length; i++) { | |
var height = childrenHeights[i]; | |
if (offset >= past + height) { | |
past += height; | |
} else if(past < offset + viewport) { | |
past += height; | |
shown.push(i); | |
} else { | |
break; | |
} | |
} | |
return shown; | |
} | |
function occlusionStyle() { | |
return { | |
position: "relative", | |
height: containerHeight + "px", | |
top: "-" + topOffset() + "px" | |
}; | |
} | |
function topOffset() { | |
var past = 0; | |
for (var i = 0; i < childrenHeights.length; i++) { | |
if (past + childrenHeights[i] > offset) { | |
return offset - past; | |
} else { | |
past += childrenHeights[i]; | |
} | |
} | |
} | |
return { | |
view: view, | |
restart: restart, | |
scroller: scroller | |
}; | |
} | |
var items = [] | |
for(var i = 0; i < 5000; i++) { | |
items.push({ | |
title: 'Foo Bar ' + i | |
}) | |
} | |
var app = { | |
controller: function() { | |
return { | |
occlusion: occluder(items) | |
} | |
}, | |
view: function(scope) { | |
console.log("VIEW"); | |
return m(".scroller", { | |
config: scope.occlusion.scroller, | |
style: {overflow: "auto", height: "500px"} | |
}, scope.occlusion.view(function(item) { | |
return m("", item.title); | |
}) | |
) | |
} | |
} | |
m.mount(document.body, app); | |
</script></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// noprotect | |
function occluder(children) { | |
var childrenHeights; | |
var containerHeight; | |
var viewport, offset; | |
var ready = false; | |
var dom, container; | |
var occlusion = []; | |
function scroller(el, isInit) { | |
if (!isInit) { | |
el.addEventListener("scroll", scroll); | |
viewport = el.offsetHeight; | |
} | |
} | |
function setup(el, isInit) { | |
dom = Array.prototype.slice.call(el.childNodes); | |
childrenHeights = []; | |
containerHeight = 0; | |
for (var height, i = 0; i < el.childNodes.length; i++) { | |
height = el.childNodes[i].getBoundingClientRect().height; | |
childrenHeights.push(height); | |
containerHeight += height; | |
} | |
ready = true; | |
console.log("REDRAW!!!!"); | |
( requestAnimationFrame || setTimeout )( m.redraw ); | |
} | |
function scroll(e) { | |
offset = e.target.scrollTop; | |
var newOcclusion = calculateOcclusion(); | |
if (newOcclusion[newOcclusion.length - 1] != occlusion[occlusion.length - 1] || newOcclusion[0] != occlusion[0]) { | |
occlusion = newOcclusion; | |
console.time("redraw"); | |
update(); | |
console.timeEnd("redraw"); | |
} | |
} | |
function restart() { | |
ready = false; | |
m.redraw(true); | |
} | |
function view(template) { | |
console.log("READY", ready); | |
if (ready) { | |
return m("", {config: setContainer, style: {position: "relative", height: containerHeight + "px"}}) | |
} else { | |
return m("", {config: setup}, children.map(template)); | |
} | |
} | |
function setContainer(el) { | |
console.log("Set container to", el); | |
container = el; | |
update(); | |
} | |
function update() { | |
var inner = document.createElement("div"); | |
inner.style.position = "relative"; | |
inner.style.top = offset + "px"; | |
container.style.top = "-" + topOffset() + "px"; | |
for (var i = 0; i < occlusion.length; i++) { | |
inner.appendChild(dom[occlusion[i]]); | |
} | |
container.innerHTML = ""; | |
container.appendChild(inner); | |
} | |
function calculateOcclusion() { | |
var past = 0; | |
var shown = []; | |
for (var i = 0; i < children.length; i++) { | |
var height = childrenHeights[i]; | |
if (offset >= past + height) { | |
past += height; | |
} else if(past < offset + viewport) { | |
past += height; | |
shown.push(i); | |
} else { | |
break; | |
} | |
} | |
return shown; | |
} | |
function occlusionStyle() { | |
return { | |
position: "relative", | |
height: containerHeight + "px", | |
top: "-" + topOffset() + "px" | |
}; | |
} | |
function topOffset() { | |
var past = 0; | |
for (var i = 0; i < childrenHeights.length; i++) { | |
if (past + childrenHeights[i] > offset) { | |
return offset - past; | |
} else { | |
past += childrenHeights[i]; | |
} | |
} | |
} | |
return { | |
view: view, | |
restart: restart, | |
scroller: scroller | |
}; | |
} | |
var items = [] | |
for(var i = 0; i < 5000; i++) { | |
items.push({ | |
title: 'Foo Bar ' + i | |
}) | |
} | |
var app = { | |
controller: function() { | |
return { | |
occlusion: occluder(items) | |
} | |
}, | |
view: function(scope) { | |
console.log("VIEW"); | |
return m(".scroller", { | |
config: scope.occlusion.scroller, | |
style: {overflow: "auto", height: "500px"} | |
}, scope.occlusion.view(function(item) { | |
return m("", item.title); | |
}) | |
) | |
} | |
} | |
m.mount(document.body, app); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment