1
+ const adjectives = [ "pretty" , "large" , "big" , "small" , "tall" , "short" , "long" , "handsome" , "plain" , "quaint" , "clean" , "elegant" , "easy" , "angry" , "crazy" , "helpful" , "mushy" , "odd" , "unsightly" , "adorable" , "important" , "inexpensive" , "cheap" , "expensive" , "fancy" ] ;
2
+ const colours = [ "red" , "yellow" , "blue" , "green" , "pink" , "brown" , "purple" , "brown" , "white" , "black" , "orange" ] ;
3
+ const nouns = [ "table" , "chair" , "house" , "bbq" , "desk" , "car" , "pony" , "cookie" , "sandwich" , "burger" , "pizza" , "mouse" , "keyboard" ] ;
4
+ const lengths = [ adjectives . length , colours . length , nouns . length ] ;
5
+ function * _random ( n ) {
6
+ for ( let max of lengths ) {
7
+ const arr = new Array ( n ) ;
8
+ for ( i = 0 ; i < n ; i ++ ) arr [ i ] = Math . round ( Math . random ( ) * 1000 ) % max ;
9
+ yield arr
10
+ }
11
+ }
12
+ const data = [ ] , nTemplates = ( n ) => 10 , tbody = document . getElementsByTagName ( 'tbody' ) [ 0 ] ;
13
+ let index = 1 , i , lbl , selected ;
14
+
15
+ function create ( n = 1000 ) {
16
+ if ( data . length < n ) { set ( data . length ) ; append ( n - data . length ) }
17
+ else {
18
+ set ( data . length ) ;
19
+ if ( data . length > n ) {
20
+ data . length = n ;
21
+ const rg = document . createRange ( ) ;
22
+ rg . setStartBefore ( tbody . children [ n ] ) ;
23
+ rg . setEndAfter ( tbody . lastElementChild ) ;
24
+ rg . deleteContents ( ) ;
25
+ }
26
+ }
27
+ }
28
+ function set ( n ) {
29
+ const indices = tbody . querySelectorAll ( 'td:first-child' ) ;
30
+ const labels = tbody . querySelectorAll ( 'a.lbl' ) ;
31
+ const [ r1 , r2 , r3 ] = _random ( n ) ;
32
+ for ( i = 0 ; i < n ; i ++ ) {
33
+ indices [ i ] . firstChild . nodeValue = index ++ ;
34
+ labels [ i ] . firstChild . nodeValue = data [ i ] = `${ adjectives [ r1 [ i ] ] } ${ colours [ r2 [ i ] ] } ${ nouns [ r3 [ i ] ] } ` ;
35
+ }
36
+ }
37
+ function append ( n = 1000 ) {
38
+ const [ r1 , r2 , r3 ] = _random ( n ) , nt = nTemplates ( n ) ; let j = 0 ;
39
+ const itemTemplate = document . getElementById ( 'itemTemplate' ) . content ;
40
+ while ( nt >= itemTemplate . children . length * 2 ) itemTemplate . appendChild ( itemTemplate . cloneNode ( true ) ) ;
41
+ while ( nt > itemTemplate . children . length ) itemTemplate . appendChild ( itemTemplate . firstElementChild . cloneNode ( true ) ) ;
42
+
43
+ const ids = Array . prototype . map . call ( itemTemplate . querySelectorAll ( 'td:first-child' ) , i => i . firstChild )
44
+ const labels = Array . prototype . map . call ( itemTemplate . querySelectorAll ( 'a.lbl' ) , i => i . firstChild ) ;
45
+
46
+ while ( ( n -= nt ) >= 0 ) {
47
+ for ( i = 0 ; i < nt ; i ++ , j ++ ) {
48
+ ids [ i ] . nodeValue = index ++ ;
49
+ data . push ( labels [ i ] . nodeValue = `${ adjectives [ r1 [ j ] ] } ${ colours [ r2 [ j ] ] } ${ nouns [ r3 [ j ] ] } ` )
50
+ }
51
+ tbody . appendChild ( itemTemplate . cloneNode ( true ) ) ;
52
+ }
53
+ }
54
+ function update ( ) {
55
+ const labels = tbody . querySelectorAll ( 'a.lbl' ) , length = labels . length ;
56
+ for ( i = 0 ; i < length ; i += 10 ) labels [ i ] . firstChild . nodeValue = data [ i ] += ' !!!' ;
57
+ }
58
+ function clear ( ) { data . length = 0 ; tbody . textContent = '' }
59
+
60
+ function swap ( ) {
61
+ if ( data . length < 999 ) return ;
62
+ [ data [ 1 ] , data [ 998 ] ] = [ data [ 998 ] , data [ 1 ] ] ;
63
+ const [ id1 , lbl1 ] = tbody . children [ 1 ] . querySelectorAll ( 'td:first-child, a.lbl' ) ;
64
+ const [ id998 , lbl998 ] = tbody . children [ 998 ] . querySelectorAll ( 'td:first-child, a.lbl' ) ;
65
+ [ id1 . firstChild . nodeValue , id998 . firstChild . nodeValue ] = [ id998 . firstChild . nodeValue , id1 . firstChild . nodeValue ] ;
66
+ [ lbl1 . firstChild . nodeValue , lbl998 . firstChild . nodeValue ] = [ lbl998 . firstChild . nodeValue , lbl1 . firstChild . nodeValue ]
67
+ }
68
+ tbody . onclick = ( e ) => {
69
+ e . preventDefault ; e . stopPropagation ;
70
+ if ( e . target . matches ( 'a.lbl' ) ) {
71
+ const element = e . target . parentNode . parentNode ;
72
+ if ( element === selected ) selected . className = selected . className ? "" : "danger" ;
73
+ else {
74
+ if ( selected ) selected . className = "" ;
75
+ element . className = "danger" ; selected = element
76
+ }
77
+ } else if ( e . target . matches ( 'span.remove' ) ) { let temp ;
78
+ const element = e . target . parentNode . parentNode . parentNode ;
79
+ data . splice ( Array . prototype . indexOf . call ( tbody . children , element ) , 1 ) ;
80
+ tbody . removeChild ( element ) ;
81
+ }
82
+ }
83
+ for ( let [ key , fn ] of Object . entries ( {
84
+ run : create , runlots : ( ) => create ( 10000 ) ,
85
+ add : append , update, clear, swaprows : swap
86
+ } ) ) document . getElementById ( key ) . onclick = ( e ) => { e . stopPropagation ( ) , fn ( ) }
0 commit comments