@egjs/flicking
Version:
Everyday 30 million people experience. It's reliable, flexible and extendable carousel.
107 lines (86 loc) • 2.67 kB
text/typescript
/*
* Copyright (c) 2015 NAVER Corp.
* egjs projects are licensed under the MIT license
*/
import { DIRECTION } from "../../constants/values";
import { circulateIndex } from "../../utils";
import Panel, { PanelOptions } from "./Panel";
import VirtualElementProvider from "./provider/VirtualElementProvider";
/**
* Options for creating a {@link VirtualPanel}
*/
export interface VirtualPanelOptions extends PanelOptions {
/** A provider instance that returns the actual html element */
elementProvider: VirtualElementProvider;
}
/**
* A slide data component that holds information of a single HTMLElement
*/
class VirtualPanel extends Panel {
protected _elProvider: VirtualElementProvider;
protected _cachedInnerHTML: string | null;
/**
* `HTMLElement` that panel's referencing
* @readonly
*/
public get element(): HTMLElement {
return this._elProvider.element;
}
/**
* Cached innerHTML by the previous render function
* @readonly
*/
public get cachedInnerHTML(): string | null {
return this._cachedInnerHTML;
}
/**
* A number for indexing which element it will be rendered on
* @readonly
*/
public get elementIndex(): number {
const flicking = this._flicking;
const virtualElCount = flicking.panelsPerView + 1;
const panelCount = flicking.panelCount;
let index = this._index;
if (this._toggled) {
// To prevent element duplication
index = this._toggleDirection === DIRECTION.NEXT ? index + panelCount : index - panelCount;
}
return circulateIndex(index, virtualElCount);
}
/**
* @param options - {@link VirtualPanelOptions}
*/
public constructor(options: VirtualPanelOptions) {
super(options);
options.elementProvider.init(this);
this._elProvider = options.elementProvider;
this._cachedInnerHTML = null;
}
public cacheRenderResult(result: string) {
this._cachedInnerHTML = result;
}
public uncacheRenderResult() {
this._cachedInnerHTML = null;
}
public render() {
const flicking = this._flicking;
const { renderPanel, cache } = flicking.virtual;
const element = this._elProvider.element;
const newInnerHTML = this._cachedInnerHTML || renderPanel(this, this._index);
if (newInnerHTML === element.innerHTML) return;
element.innerHTML = newInnerHTML;
if (cache) {
this.cacheRenderResult(newInnerHTML);
}
}
public increaseIndex(val: number) {
this.uncacheRenderResult();
return super.increaseIndex(val);
}
public decreaseIndex(val: number) {
this.uncacheRenderResult();
return super.decreaseIndex(val);
}
}
export default VirtualPanel;