@@ -0,0 +1,399 @@
<!DOCTYPE html>
< html >
< head >
< meta charset ="utf-8 ">
< title > Ember Virtual List Component</ title >
< link rel ="stylesheet " href ="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css ">
< script src ="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js "> </ script >
< script src ="http://builds.emberjs.com/tags/v1.13.5/ember-template-compiler.js "> </ script >
< script src ="http://builds.emberjs.com/tags/v1.13.5/ember.debug.js "> </ script >
< style id ="jsbin-css ">
/* Put your CSS here */
html , body {
margin : 20px ;
box-sizing : border-box;
}
h1 , h2 {
font-weight : normal;
}
.x-virtual-list__container {
width : 300px ;
height : 500px ;
outline : 1px solid black;
overflow : scroll;
position : relative;
}
.x-virtual-list__scroller {
position : absolute;
background-color : blue;
width : 100% ;
}
.x-virtual_list__item {
position : absolute;
outline : 1px solid white;
height : 40px ;
width : calc (100% - 10px );
line-height : 40px ;
padding-left : 10px ;
color : white;
background-color : green;
}
</ style >
</ head >
< body >
< script type ="text/x-handlebars ">
< h1 > Scroll Scroll</ h1 >
{ { outlet } }
</ script >
< script type ="text/x-handlebars " id ="components/x-virtual-list-item ">
{ { item . name } }
</ script >
< script type ="text/x-handlebars " id ="components/x-virtual-list ">
< div class = "x-virtual-list__container" >
< div class = "x-virtual-list__scroller" style = { { scrollerStyle} } >
{ { #each visibleRows key = 'rowKey' as | row | } }
< div class = "x-virtual_list__item" style = { { row . style} } > { { component itemComponent item = row . item } } </ div >
{ { / e a c h } }
</div >
< / div >
< div >
< p > scroll offset: { { scrollOffset} } </ p >
< p > visible elements: { { visibleRows . length} } </ p >
< p > start offset: { { startOffset} } </ p >
< p > end offset: { { endOffset} } </ p >
< p > start index: { { startIndex} } </ p >
< p > end index: { { endIndex} } </ p >
</ div >
</ script >
< script type ="text/x-handlebars " data-template-name ="index ">
{ { x - virtual - list items = model } }
</ script >
< script id ="jsbin-javascript ">
App = Ember . Application . create ( ) ;
App . Router . map ( function ( ) {
// put your routes here
} ) ;
App . IndexRoute = Ember . Route . extend ( {
model : function ( ) {
var people = [
'Bill' ,
'Zach' ,
'Seung' ,
'Kapil' ,
'Tom' ,
'Ren' ,
'George' ,
'Ed' ,
'Ben' ,
'Curtis' ,
'Allie' ,
'Tao' ,
'David' ,
'Gian' ,
'Clifton' ,
'Richard' ,
'Max' ,
'Tony' ,
'Kiran' ,
'Mike' ,
'Brian' ,
'Joe' ,
'Matt' ,
'Alex' ,
'Jeremy' ,
'Travis'
] ;
var items = [ ] ;
for ( var i = 0 ; i < 1000 ; i ++ ) {
var person = people [ Math . floor ( Math . random ( ) * people . length ) ] ;
items . push ( {
name : ( i + 1 ) + ". " + person
} ) ;
}
return items ;
}
} ) ;
App . XVirtualListComponent = Ember . Component . extend ( {
rowHeight : 40 ,
scrollOffset : 0 ,
containerHeight : 0 ,
itemComponent : 'x-virtual-list-item' ,
visibleRows : function ( ) {
var rowHeight = this . get ( 'rowHeight' ) ;
var startIndex = this . get ( 'startIndex' ) ;
var endIndex = this . get ( 'endIndex' ) ;
return this . get ( 'items' ) . slice ( startIndex , endIndex ) . map ( function ( item , i ) {
var index = i + startIndex ;
var top = ( rowHeight * index ) ;
return {
rowKey : index ,
item : item ,
style : new Ember . Handlebars . SafeString ( "top: " + top + "px;" )
} ;
} ) ;
} . property ( 'items' , 'rowHeight' , 'startIndex' , 'endIndex' ) ,
startOffset : function ( ) {
return Math . abs ( this . get ( 'scrollOffset' ) ) / this . get ( 'rowHeight' ) ;
} . property ( 'scrollOffset' , 'containerHeight' , 'rowHeight' ) ,
endOffset : function ( ) {
return ( Math . abs ( this . get ( 'scrollOffset' ) ) + this . getWithDefault ( 'containerHeight' , 0 ) ) / this . get ( 'rowHeight' ) ;
} . property ( 'scrollOffset' , 'containerHeight' , 'rowHeight' ) ,
startIndex : function ( ) {
return Math . floor ( this . get ( 'startOffset' ) ) ;
} . property ( 'startOffset' ) ,
endIndex : function ( ) {
return Math . ceil ( this . get ( 'endOffset' ) ) ;
} . property ( 'endOffset' ) ,
scrollerStyle : function ( ) {
var height = this . get ( 'items.length' ) * this . get ( 'rowHeight' ) ;
var style = "height: " + height + "px" ;
return new Ember . Handlebars . SafeString ( style ) ;
} . property ( 'items.length' , 'rowHeight' ) ,
hookupScroll : function ( ) {
var component = this ;
this . outer ( ) . bind ( 'scroll' , function ( ) {
Ember . run . once ( component , function ( ) {
var containerOffset = this . outer ( ) . offset ( ) . top ;
var scrollerOffset = this . inner ( ) . offset ( ) . top ;
var scrollOffset = scrollerOffset - containerOffset ;
this . set ( 'scrollOffset' , scrollOffset ) ;
} ) ;
} ) ;
} . on ( 'didInsertElement' ) ,
readySetGo : function ( ) {
Ember . run . later ( this , function ( ) {
this . set ( 'containerHeight' , this . outer ( ) . height ( ) ) ;
} ) ;
} . on ( 'didInsertElement' ) ,
outer : function ( ) {
return this . $ ( ) . find ( '.x-virtual-list__container' ) ;
} ,
inner : function ( ) {
return this . $ ( ) . find ( '.x-virtual-list__scroller' ) ;
}
} ) ;
</ script >
< script id ="jsbin-source-html " type ="text/html "> < ! DOCTYPE html >
< html >
< head >
< meta charset = "utf-8" >
< title > Ember Virtual List Component</ title >
< link rel = "stylesheet" href = "http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css" >
< script src = "http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" > < \/script >
< script src = "http://builds.emberjs.com/tags/v1.13.5/ember-template-compiler.js" > < \/script >
< script src = "http://builds.emberjs.com/tags/v1.13.5/ember.debug.js" > < \/script >
</ head >
< body >
< script type = "text/x-handlebars" >
< h1 > Scroll Scroll</ h1 >
{ { outlet} }
< \/script >
< script type = "text/x-handlebars" id = "components/x-virtual-list-item" >
{ { item . name} }
< \/script >
< script type = "text/x-handlebars" id = "components/x-virtual-list" >
< div class = "x-virtual-list__container" >
< div class = "x-virtual-list__scroller" style = { { scrollerStyle} } >
{ { #each visibleRows key = 'rowKey' as | row | } }
< div class = "x-virtual_list__item" style = { { row . style} } > { { component itemComponent item = row . item } } </ div >
{ { / e a c h } }
</div >
< / div >
< div >
< p > scroll offset: { { scrollOffset} } </ p >
< p > visible elements: { { visibleRows . length} } </ p >
< p > start offset: { { startOffset} } </ p >
< p > end offset: { { endOffset} } </ p >
< p > start index: { { startIndex} } </ p >
< p > end index: { { endIndex} } </ p >
</ div >
< \/script >
< script type = "text/x-handlebars" data-template-name = "index" >
{ { x- virtual - list items = model } }
< \/script >
</ body >
</ html >
</ script >
< script id ="jsbin-source-css " type ="text/css "> /* Put your CSS here */
html , body {
margin : 20 px ;
box - sizing : border - box ;
}
h1 , h2 {
font - weight : normal ;
}
. x - virtual - list__container {
width: 300 px ;
height: 500 px ;
outline: 1 px solid black ;
overflow: scroll ;
position: relative ;
}
. x - virtual - list__scroller {
position: absolute ;
background - color : blue ;
width: 100 % ;
}
. x - virtual_list__item {
position: absolute ;
outline: 1 px solid white ;
height: 40 px ;
width: calc ( 100 % - 10 px ) ;
line - height : 40 px ;
padding - left : 10 px ;
color: white ;
background - color : green ;
} </ script >
< script id ="jsbin-source-javascript " type ="text/javascript "> App = Ember . Application . create ( ) ;
App . Router . map ( function ( ) {
// put your routes here
} ) ;
App . IndexRoute = Ember . Route . extend ( {
model : function ( ) {
var people = [
'Bill' ,
'Zach' ,
'Seung' ,
'Kapil' ,
'Tom' ,
'Ren' ,
'George' ,
'Ed' ,
'Ben' ,
'Curtis' ,
'Allie' ,
'Tao' ,
'David' ,
'Gian' ,
'Clifton' ,
'Richard' ,
'Max' ,
'Tony' ,
'Kiran' ,
'Mike' ,
'Brian' ,
'Joe' ,
'Matt' ,
'Alex' ,
'Jeremy' ,
'Travis'
] ;
var items = [ ] ;
for ( var i = 0 ; i < 1000 ; i ++ ) {
var person = people [ Math . floor ( Math . random ( ) * people . length ) ] ;
items . push ( {
name : ( i + 1 ) + ". " + person
} ) ;
}
return items ;
}
} ) ;
App . XVirtualListComponent = Ember . Component . extend ( {
rowHeight : 40 ,
scrollOffset : 0 ,
containerHeight : 0 ,
itemComponent : 'x-virtual-list-item' ,
visibleRows : function ( ) {
var rowHeight = this . get ( 'rowHeight' ) ;
var startIndex = this . get ( 'startIndex' ) ;
var endIndex = this . get ( 'endIndex' ) ;
return this . get ( 'items' ) . slice ( startIndex , endIndex ) . map ( function ( item , i ) {
var index = i + startIndex ;
var top = ( rowHeight * index ) ;
return {
rowKey : index ,
item : item ,
style : new Ember . Handlebars . SafeString ( "top: " + top + "px;" )
} ;
} ) ;
} . property ( 'items' , 'rowHeight' , 'startIndex' , 'endIndex' ) ,
startOffset : function ( ) {
return Math . abs ( this . get ( 'scrollOffset' ) ) / this . get ( 'rowHeight' ) ;
} . property ( 'scrollOffset' , 'containerHeight' , 'rowHeight' ) ,
endOffset : function ( ) {
return ( Math . abs ( this . get ( 'scrollOffset' ) ) + this . getWithDefault ( 'containerHeight' , 0 ) ) / this . get ( 'rowHeight' ) ;
} . property ( 'scrollOffset' , 'containerHeight' , 'rowHeight' ) ,
startIndex : function ( ) {
return Math . floor ( this . get ( 'startOffset' ) ) ;
} . property ( 'startOffset' ) ,
endIndex : function ( ) {
return Math . ceil ( this . get ( 'endOffset' ) ) ;
} . property ( 'endOffset' ) ,
scrollerStyle : function ( ) {
var height = this . get ( 'items.length' ) * this . get ( 'rowHeight' ) ;
var style = "height: " + height + "px" ;
return new Ember . Handlebars . SafeString ( style ) ;
} . property ( 'items.length' , 'rowHeight' ) ,
hookupScroll : function ( ) {
var component = this ;
this . outer ( ) . bind ( 'scroll' , function ( ) {
Ember . run . once ( component , function ( ) {
var containerOffset = this . outer ( ) . offset ( ) . top ;
var scrollerOffset = this . inner ( ) . offset ( ) . top ;
var scrollOffset = scrollerOffset - containerOffset ;
this . set ( 'scrollOffset' , scrollOffset ) ;
} ) ;
} ) ;
} . on ( 'didInsertElement' ) ,
readySetGo : function ( ) {
Ember . run . later ( this , function ( ) {
this . set ( 'containerHeight' , this . outer ( ) . height ( ) ) ;
} ) ;
} . on ( 'didInsertElement' ) ,
outer : function ( ) {
return this . $ ( ) . find ( '.x-virtual-list__container' ) ;
} ,
inner : function ( ) {
return this . $ ( ) . find ( '.x-virtual-list__scroller' ) ;
}
} ) ; </ script > </ body >
</ html >