/** * @desc 一个轮播插件 * @author mxsyx (zsimline@163.com) * @version 1.0.0 */ class lb { constructor(options) { this.lbbox = document.getelementbyid(options.id); this.lbitems = this.lbbox.queryselectorall('.lb-item'); this.lbsigns = this.lbbox.queryselectorall('.lb-sign li'); this.lbctrll = this.lbbox.queryselectorall('.lb-ctrl')[0]; this.lbctrlr = this.lbbox.queryselectorall('.lb-ctrl')[1]; // 当前图片索引 this.curindex = 0; // 轮播盒内图片数量 this.numitems = this.lbitems.length; // 是否可以滑动 this.status = true; // 轮播速度 this.speed = options.speed || 600; // 等待延时 this.delay = options.delay || 3000; // 轮播方向 this.direction = options.direction || 'left'; // 是否监听键盘事件 this.moniterkeyevent = options.moniterkeyevent || false; // 是否监听屏幕滑动事件 this.monitertouchevent = options.monitertouchevent || false; this.handleevents(); this.settransition(); } // 开始轮播 start() { const event = { srcelement: this.direction == 'left' ? this.lbctrlr : this.lbctrll }; const clickctrl = this.clickctrl.bind(this); // 每隔一段时间模拟点击控件 this.interval = setinterval(clickctrl, this.delay, event); } // 暂停轮播 pause() { clearinterval(this.interval); } /** * 设置轮播图片的过渡属性 * 在文件头内增加一个样式标签 * 标签内包含轮播图的过渡属性 */ settransition() { const styleelement = document.createelement('style'); document.head.appendchild(styleelement); const stylerule = `.lb-item {transition: left ${this.speed}ms ease-in-out}` styleelement.sheet.insertrule(stylerule, 0); } // 处理点击控件事件 clickctrl(event) { if (!this.status) return; this.status = false; if (event.srcelement == this.lbctrlr) { var fromindex = this.curindex, toindex = (this.curindex + 1) % this.numitems, direction = 'left'; } else { var fromindex = this.curindex; toindex = (this.curindex + this.numitems - 1) % this.numitems, direction = 'right'; } this.slide(fromindex, toindex, direction); this.curindex = toindex; } // 处理点击标志事件 clicksign(event) { if (!this.status) return; this.status = false; const fromindex = this.curindex; const toindex = parseint(event.srcelement.getattribute('slide-to')); const direction = fromindex < toindex ? 'left' : 'right'; this.slide(fromindex, toindex, direction); this.curindex = toindex; } // 处理滑动屏幕事件 touchscreen(event) { if (event.type == 'touchstart') { this.startx = event.touches[0].pagex; this.starty = event.touches[0].pagey; } else { // touchend this.endx = event.changedtouches[0].pagex; this.endy = event.changedtouches[0].pagey; // 计算滑动方向的角度 const dx = this.endx - this.startx const dy = this.starty - this.endy; const angle = math.abs(math.atan2(dy, dx) * 180 / math.pi); // 滑动距离太短 if (math.abs(dx) < 10 || math.abs(dy) < 10) return ; if (angle >= 0 && angle <= 45) { // 向右侧滑动屏幕,模拟点击左控件 this.lbctrll.click(); } else if (angle >= 135 && angle <= 180) { // 向左侧滑动屏幕,模拟点击右控件 this.lbctrlr.click(); } } } // 处理键盘按下事件 keydown(event) { if (event && event.keycode == 37) { this.lbctrll.click(); } else if (event && event.keycode == 39) { this.lbctrlr.click(); } } // 处理各类事件 handleevents() { // 鼠标移动到轮播盒上时继续轮播 this.lbbox.addeventlistener('mouseleave', this.start.bind(this)); // 鼠标从轮播盒上移开时暂停轮播 this.lbbox.addeventlistener('mouseover', this.pause.bind(this)); // 点击左侧控件向右滑动图片 this.lbctrll.addeventlistener('click', this.clickctrl.bind(this)); // 点击右侧控件向左滑动图片 this.lbctrlr.addeventlistener('click', this.clickctrl.bind(this)); // 点击轮播标志后滑动到对应的图片 for (let i = 0; i < this.lbsigns.length; i++) { this.lbsigns[i].setattribute('slide-to', i); this.lbsigns[i].addeventlistener('click', this.clicksign.bind(this)); } // 监听键盘事件 if (this.moniterkeyevent) { document.addeventlistener('keydown', this.keydown.bind(this)); } // 监听屏幕滑动事件 if (this.monitertouchevent) { this.lbbox.addeventlistener('touchstart', this.touchscreen.bind(this)); this.lbbox.addeventlistener('touchend', this.touchscreen.bind(this)); } } /** * 滑动图片 * @param {number} fromindex * @param {number} toindex * @param {string} direction */ slide(fromindex, toindex, direction) { if (direction == 'left') { this.lbitems[toindex].classname = "lb-item next"; var fromclass = 'lb-item active left', toclass = 'lb-item next left'; } else { this.lbitems[toindex].classname = "lb-item prev"; var fromclass = 'lb-item active right', toclass = 'lb-item prev right'; } this.lbsigns[fromindex].classname = ""; this.lbsigns[toindex].classname = "active"; settimeout((() => { this.lbitems[fromindex].classname = fromclass; this.lbitems[toindex].classname = toclass; }).bind(this), 50); settimeout((() => { this.lbitems[fromindex].classname = 'lb-item'; this.lbitems[toindex].classname = 'lb-item active'; this.status = true; // 设置为可以滑动 }).bind(this), this.speed + 50); } }