提交 37dde3aa 编写于 作者: fly丶知秋's avatar fly丶知秋

WIP: 优化轮播图组件

上级 a26c8f12
......@@ -32,6 +32,6 @@
cursor: pointer;
}
.indicator-item[active] {
.indicator-item[data-active] {
background-color: #409eff;
}
import { Component, Host, h, Element, State, Prop, Watch } from '@stencil/core';
import { getBrotherElements } from '../../utils/utils';
import { Component, Host, h, Element, State, Prop, Watch, writeTask } from '@stencil/core';
import { findElementsDownward, getBrotherElements } from '../../utils/utils';
@Component({
tag: 'ivy-carousel',
......@@ -8,6 +8,9 @@ import { getBrotherElements } from '../../utils/utils';
})
export class IvyCarousel {
@Element() root: HTMLElement;
@State() slotEl: Element;
@State() slotChildren: HTMLElement[] = [];
@State() carouselItemList: NodeListOf<Element>;
......@@ -26,15 +29,15 @@ export class IvyCarousel {
const className = target.getAttribute('class');
console.log(nodeName, className);
if (nodeName === 'A' && className === 'indicator-item') {
const index = target.getAttribute('index');
const index = target.getAttribute('data-index');
const wrap = this.root.shadowRoot.querySelector('.wrap');
const children = wrap.children;
console.log(wrap, index, children);
(wrap as any).style.transform = `translateX(-${(Number(index) / children.length) * 100}%)`;
target.setAttribute('active', '');
target.setAttribute('data-active', '');
const itemList = getBrotherElements(target);
itemList.forEach(c => {
c.removeAttribute('active');
c.removeAttribute('data-active');
});
}
}
......@@ -44,52 +47,54 @@ export class IvyCarousel {
<Host>
<div class="wrap"></div>
<div class="wrap__hide">
<slot></slot>
<slot ref={el => (this.slotEl = el)}></slot>
</div>
<div class="indicator">
<slot name="indicator">
<div class="indicator-default" onClick={this.handlerClick.bind(this)}></div>
<div class="indicator-default" onClick={this.handlerClick.bind(this)}>
{this.slotChildren.map((_c, i) => {
if (Number(this.defaultActive) == i + 1) {
return <a data-active data-index={i + 1} class="indicator-item"></a>;
} else {
return <a data-index={i + 1} class="indicator-item"></a>;
}
})}
</div>
</slot>
</div>
</Host>
);
}
componentDidLoad() {
const carouselItemList = this.root.querySelectorAll('ivy-carousel-item');
const len = carouselItemList.length;
const firstChild: any = carouselItemList.item(0).cloneNode(true);
const lastChild: any = carouselItemList.item(len - 1).cloneNode(true);
console.log(carouselItemList, firstChild, lastChild);
const tmpBox = document.createElement('div');
const itemFlex = (1 / (len + 2)) * 100;
firstChild.style.flex = `0 0 ${itemFlex}%`;
lastChild.style.flex = `0 0 ${itemFlex}%`;
tmpBox.appendChild(firstChild);
carouselItemList.forEach(c => {
c.style.flex = `0 0 ${itemFlex}%`;
tmpBox.appendChild(c);
});
tmpBox.appendChild(lastChild);
const wrap = this.root.shadowRoot.querySelector('.wrap');
if (wrap) {
(wrap as any).style.width = `${(carouselItemList.length + 2) * 100}%`;
wrap.innerHTML = tmpBox.innerHTML;
(wrap as any).style.transform = `translateX(-${(Number(this.defaultActive) / (len + 2)) * 100}%)`;
}
componentWillLoad() {
writeTask(() => {
this.slotChildren = findElementsDownward(this.root, 'ivy-carousel-item');
// this.slotChildren.forEach(c => {
// console.log(c.assignedSlot);
// });
// const tmp = (this.slotEl as any).assignedElements();
// console.log(tmp);
const carouselItemList = this.root.querySelectorAll('ivy-carousel-item');
const len = carouselItemList.length;
const firstChild: any = carouselItemList.item(0).cloneNode(true);
const lastChild: any = carouselItemList.item(len - 1).cloneNode(true);
const tmpBox = document.createElement('div');
const itemFlex = (1 / (len + 2)) * 100;
firstChild.style.flex = `0 0 ${itemFlex}%`;
lastChild.style.flex = `0 0 ${itemFlex}%`;
tmpBox.appendChild(firstChild);
carouselItemList.forEach(c => {
c.style.flex = `0 0 ${itemFlex}%`;
tmpBox.appendChild(c);
});
const indicatorDefault = this.root.shadowRoot.querySelector('.indicator-default');
if (indicatorDefault) {
let str = '';
for (let i = 0; i < len; i++) {
if (Number(this.defaultActive) == i + 1) {
str += `<a active index="${i + 1}" class="indicator-item"></a>`;
} else {
str += `<a index="${i + 1}" class="indicator-item"></a>`;
}
tmpBox.appendChild(lastChild);
const wrap = this.root.shadowRoot.querySelector('.wrap');
if (wrap) {
(wrap as any).style.width = `${(carouselItemList.length + 2) * 100}%`;
wrap.innerHTML = tmpBox.innerHTML;
(wrap as any).style.transform = `translateX(-${(Number(this.defaultActive) / (len + 2)) * 100}%)`;
}
indicatorDefault.innerHTML = str;
}
});
}
}
......@@ -54,27 +54,19 @@
<div style="min-height: 200px"> </div>
<div class="margin-top">
<ivy-pager class="pager"></ivy-pager>
<ivy-button id="btn">更改进度条进度</ivy-button>
</div>
<div style="min-height: 200px">
<ivy-progress value="30" id="progress1"></ivy-progress>
<ivy-progress value="50" class="margin-top"></ivy-progress>
<ivy-progress value="70" class="margin-top"></ivy-progress>
<ivy-progress value="100" class="margin-top"></ivy-progress>
<div style="height: 200px;"></div>
<div>
<ivy-carousel>
<ivy-carousel-item>1</ivy-carousel-item>
<ivy-carousel-item>2</ivy-carousel-item>
<ivy-carousel-item>3</ivy-carousel-item>
<ivy-carousel-item>4</ivy-carousel-item>
</ivy-carousel>
</div>
<div style="min-height: 200px">
<ivy-progress value="70" color="blue"></ivy-progress>
<ivy-progress value="70" color="#afedf4" class="margin-top"></ivy-progress>
<ivy-progress value="70" color="green" class="margin-top"></ivy-progress>
<ivy-progress value="70" color="red" class="margin-top"></ivy-progress>
</div>
<div style="min-height: 200px">
<ivy-progress value="70" color="blue" show-text></ivy-progress>
<ivy-progress value="70" color="#afedf4" show-text class="margin-top"></ivy-progress>
<ivy-progress value="70" color="green" show-text class="margin-top"></ivy-progress>
<ivy-progress value="70" color="red" show-text class="margin-top"></ivy-progress>
</div>
</body>
<script>
......@@ -85,10 +77,7 @@
console.log(this.pager)
})
const valueList = [10, 30, 50, 70, 90, 100]
document.querySelector('#btn').addEventListener('click', () => {
document.querySelector('#progress1').setValue(Math.floor(Math.random() * 100))
})
</script>
......
export function format(first: string, middle: string, last: string): string {
return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');
export type ScrollElement = HTMLElement | Window;
const defaultRoot = window;
function isElement(node: Element) {
const ELEMENT_NODE_TYPE = 1;
return node.tagName !== 'HTML' && node.tagName !== 'BODY' && node.nodeType === ELEMENT_NODE_TYPE;
}
/**
......@@ -152,6 +157,20 @@ export const findBrothersElements = (self: HTMLElement, nodeName: string, except
return res;
};
/**
* 获取slot的子元素
* @param slot slot 元素
* @param tag 筛选的元素名称
* @returns
*/
export const getAssignedElements = (slot: HTMLSlotElement, tag?: string) => {
const tmp = slot.assignedElements();
if (tag) {
return tmp.filter(c => c.tagName.toLowerCase() === tag);
}
return tmp;
};
/**
* 颜色叠加
* @param {String} c1 颜色1-HEX格式
......@@ -175,3 +194,38 @@ export const colorBlend = (c1: string, c2: string, ratio: number): string => {
b = '' + (b || 0).toString(16);
return `#${r}${g}${b}`;
};
export const throttle = (func: Function, delay = 0, atLeast: number = 200) => {
let timer: any = null;
let lastRun = 0;
return (...args: any) => {
const now = +new Date();
if (timer) {
clearTimeout(timer);
}
if (now - lastRun > atLeast) {
lastRun = now;
func.apply(this, args);
} else {
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
}
};
};
const overflowScrollReg = /scroll|auto/i;
// 获取滚动的父元素
export function getScrollParent(el: Element, root: ScrollElement | undefined = defaultRoot) {
let node = el;
while (node && node !== root && isElement(node)) {
const { overflowY } = window.getComputedStyle(node);
if (overflowScrollReg.test(overflowY)) {
return node;
}
node = node.parentNode as Element;
}
return root;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册