UNPKG

6.96 kBJavaScriptView Raw
1/*
2Copyright 2013-2015 ASIAL CORPORATION
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6 http://www.apache.org/licenses/LICENSE-2.0
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12*/
13
14import onsElements from '../ons/elements.js';
15import util from '../ons/util.js';
16import internal from '../ons/internal/index.js';
17import BaseElement from './base/base-element.js';
18import { LazyRepeatDelegate, LazyRepeatProvider } from '../ons/internal/lazy-repeat.js';
19
20/**
21 * @element ons-lazy-repeat
22 * @category list
23 * @description
24 * [en]
25 * Using this component a list with millions of items can be rendered without a drop in performance.
26 * It does that by "lazily" loading elements into the DOM when they come into view and
27 * removing items from the DOM when they are not visible.
28 * [/en]
29 * [ja]
30 * このコンポーネント内で描画されるアイテムのDOM要素の読み込みは、画面に見えそうになった時まで自動的に遅延され、
31 * 画面から見えなくなった場合にはその要素は動的にアンロードされます。
32 * このコンポーネントを使うことで、パフォーマンスを劣化させること無しに巨大な数の要素を描画できます。
33 * [/ja]
34 * @codepen QwrGBm
35 * @tutorial vanilla/Reference/lazy-repeat
36 * @seealso ons-list
37 * [en]The `<ons-list>` element is used to render a list.[/en]
38 * [ja]`<ons-list>`要素はリストを描画するのに使われます。[/ja]
39 * @example
40 * <script>
41 * window.addEventListener('load', function() {
42 * var lazyRepeat = document.querySelector('#list');
43 * lazyRepeat.delegate = {
44 * createItemContent: function(i, template) {
45 * var dom = template.cloneNode(true);
46 * dom.innerText = i;
47 *
48 * return dom;
49 * },
50 * countItems: function() {
51 * return 10000000;
52 * },
53 * destroyItem: function(index, item) {
54 * console.log('Destroyed item with index: ' + index);
55 * }
56 * };
57 * });
58 * </script>
59 *
60 * <ons-list id="list">
61 * <ons-lazy-repeat>
62 * <ons-list-item></ons-list-item>
63 * </ons-lazy-repeat>
64 * </ons-list>
65 */
66export default class LazyRepeatElement extends BaseElement {
67
68 connectedCallback() {
69 // not very good idea and also not documented
70 if (this.hasAttribute('delegate')) {
71 this.delegate = window[this.getAttribute('delegate')];
72 }
73 }
74
75 /**
76 * @property delegate
77 * @type {Object}
78 * @description
79 * [en]Specify a delegate object to load and unload item elements.[/en]
80 * [ja]要素のロード、アンロードなどの処理を委譲するオブジェクトを指定します。[/ja]
81 */
82
83 /**
84 * @property delegate.createItemContent
85 * @type {Function}
86 * @description
87 * [en]
88 * This function should return a `HTMLElement`.
89 *
90 * To help rendering the element, the current index and a template is supplied as arguments. The template is the initial content of the `<ons-lazy-repeat>` element.
91 * [/en]
92 * [ja]
93 * この関数は`HTMLElement`を返してください。
94 * 要素を生成しやすくするために、現在のアイテムのインデックスとテンプレートが引数に渡されます。
95 * このテンプレートは、`<ons-lazy-repeat>`要素のコンテンツが渡されます。
96 * [/ja]
97 */
98
99 /**
100 * @property delegate.countItems
101 * @type {Function}
102 * @description
103 * [en]Should return the number of items in the list.[/en]
104 * [ja]リスト内のアイテム数を返してください。[/ja]
105 */
106
107 /**
108 * @property delegate.calculateItemHeight
109 * @type {Function}
110 * @description
111 * [en]
112 * Should return the height of an item. The index is provided as an argument.
113 *
114 * This is important when rendering lists where the items have different height.
115 *
116 * The function is optional and if it isn't present the height of the first item will be automatically calculated and used for all other items.
117 * [/en]
118 * [ja]
119 * アイテムの高さ(ピクセル)を返してください。アイテムのインデックス値は引数で渡されます。
120 * この関数は、それぞれのアイムが違った高さを持つリストをレンダリングする際に重要です。
121 * この関数はオプショナルです。もしこの関数が無い場合には、
122 * 最初のアイテムの高さが他のすべてのアイテムの高さとして利用されます。
123 * [/ja]
124 */
125
126 /**
127 * @property delegate.destroyItem
128 * @type {Function}
129 * @description
130 * [en]
131 * This function is used called when an item is removed from the DOM. The index and DOM element is provided as arguments.
132 *
133 * The function is optional but may be important in order to avoid memory leaks.
134 * [/en]
135 * [ja]
136 * この関数は、あるアイテムがDOMツリーから除かれた時に呼び出されます。
137 * アイテムのインデックス値とDOM要素が引数として渡されます。
138 * この関数はオプショナルですが、各アイテムの後処理が必要な場合にはメモリーリークを避けるために重要です。
139 * [/ja]
140 */
141
142 set delegate(userDelegate) {
143 this._lazyRepeatProvider && this._lazyRepeatProvider.destroy();
144
145 if (!this._templateElement && this.children[0]) {
146 this._templateElement = this.removeChild(this.children[0]);
147 }
148
149 const delegate = new LazyRepeatDelegate(userDelegate, this._templateElement || null);
150 this._lazyRepeatProvider = new LazyRepeatProvider(this.parentElement, delegate);
151 }
152
153 get delegate() { // eslint-disable-line getter-return
154 util.throw('No delegate getter');
155 }
156
157 /**
158 * @method refresh
159 * @signature refresh()
160 * @description
161 * [en]Refresh the list. Use this method when the data has changed.[/en]
162 * [ja]リストを更新します。もしデータが変わった場合にはこのメソッドを使ってください。[/ja]
163 */
164 refresh() {
165 this._lazyRepeatProvider && this._lazyRepeatProvider.refresh();
166 }
167
168 attributeChangedCallback(name, last, current) {}
169
170 disconnectedCallback() {
171 if (this._lazyRepeatProvider) {
172 this._lazyRepeatProvider.destroy();
173 this._lazyRepeatProvider = null;
174 }
175 }
176
177}
178
179internal.LazyRepeatDelegate = LazyRepeatDelegate;
180internal.LazyRepeatProvider = LazyRepeatProvider;
181
182onsElements.LazyRepeat = LazyRepeatElement;
183customElements.define('ons-lazy-repeat', LazyRepeatElement);