您好,欢迎来到爱问旅游网。
搜索
您的当前位置:首页使用ES6做出全屏滚动插件

使用ES6做出全屏滚动插件

来源:爱问旅游网

6.2 改造 PC 端滚动事件

通过上述说明,我们已经知道截流函数可以通过限定滚动事件触发频率提升性能,同时,设置在 延迟时间开始阶段立即调用滚动事件的回调函数 并不会牺牲用户体验。

截流函数上文已经定义好,使用起来就很简单了:

// 设置截流函数
let handleMouseWheel = utils.throttle(this.scrollMouse, this, this.DELAY, true);
// 鼠标滚轮监听,火狐鼠标滚动事件不同其他
if (navigator.userAgent.toLowerCase().indexOf('firefox') === -1) {
 document.addEventListener('mousewheel', handleMouseWheel);
} else {
 document.addEventListener('DOMMouseScroll', handleMouseWheel);
}

上面这部分代码是写在 class 的 init 方法中,所以截流函数的上下文(context)传入的是 this ,表示当前 class 实例。

7)其他

7.1 导航按钮

为了简化 html 结构,导航按钮通过 js 创建。这里的难点在于 如何实现点击不同按钮实现对应页面的跳转并更新对应按钮的样式 。

解决的思路是:

  1. 页面跳转:页面个数和导航按钮的个数一致,所以点击第 i 个按钮也就是跳转到第 i 个页面,而第 i 个页面对应的容器 top 值恰好是 -(i * this.viewHeight)

  2. 更改样式:更改样式即先删除所有按钮的选中样式,然后给当前点击的按钮添加选中样式。

// 创建右侧点式导航
createNav() {
 const nav = document.createElement('p');
 nav.className = 'nav';
 this.container.appendChild(nav);
 // 有几页,显示几个点
 for (let i = 0; i < this.pagesNum; i++) {
 nav.innerHTML += '<p class="nav-dot"><span></span></p>';
 }
 const navDots = document.querySelectorAll('.nav-dot');
 this.navDots = Array.prototype.slice.call(navDots);
 // 添加初始样式
 this.navDots[0].classList.add('active');
 // 添加点式导航点击事件
 this.navDots.forEach((el, i) => {
 el.addEventListener('click', event => {
 // 页面跳转
 this.currentPosition = -(i * this.viewHeight);
 this.turnPage(this.currentPosition);
 // 更改样式
 this.navDots.forEach(el => {
 utils.deleteClassName(el, 'active');
 });
 event.target.classList.add('active');
 });
 });
}

7.2 自定义参数

得当的自定义参数可以增加插件的灵活性。

参数通过构造函数传入,并通过 Object.assign() 进行参数合并:

constructor(options) {
 // 默认配置
 const defaultOptions = {
 isShowNav: true,
 delay: 150,
 definePages: () => {},
 };
 // 合并自定义配置
 this.options = Object.assign(defaultOptions, options);
}

7.3 窗口尺寸改变时更新数据

浏览器窗口尺寸改变的时候,需要重新获取可视区、页面元素高度,并重新确定容器当前的 top 值。

同时,为了避免不必要的性能开支,这里使用了防抖动函数。

// window resize 时重新获取位置
getNewPosition() {
 this.viewHeight = document.documentElement.clientHeight;
 this.container.style.height = this.viewHeight + 'px';
 let activeNavIndex;
 this.navDots.forEach((e, i) => {
 if (e.classList.contains('active')) {
 activeNavIndex = i;
 }
 });
 this.currentPosition = -(activeNavIndex * this.viewHeight);
 this.turnPage(this.currentPosition);
}
handleWindowResize(event) {
 // 设置防抖动函数
 utils.debounce(this.getNewPosition, this, event, this.DELAY);
}
// 窗口尺寸变化时重置位置
window.addEventListener('resize', this.handleWindowResize.bind(this));

7.4 兼容性

这里的兼容性主要指两个方面:一是不同浏览器对同一行为定义了不同 API,比如上文提到的获取鼠标滚动信息的 API Firefox 和其他浏览器不一样;第二点就是 ES6 新语法、新 API 的兼容处理。

对于 class、箭头函数这类新语法的转换,通过 babel 就可完成,鉴于本插件代码量很小,都处于可控的状态,并没有引入 babel 提供的 polyfill 方案,因为新 API 只有 Object.assign() 需要做兼容处理,单独写个 polyfill 就好,如下:

// polyfill Object.assign
polyfill() {
 if (typeof Object.assign != 'function') {
 Object.defineProperty(Object, 'assign', {
 value: function assign(target, varArgs) {
 if (target == null) {
 throw new TypeError('Cannot convert undefined or null to object');
 }
 let to = Object(target);
 for (let index = 1; index < arguments.length; index++) {
 let nextSource = arguments[index];
 if (nextSource != null) {
 for (let nextKey in nextSource) {
 if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
 to[nextKey] = nextSource[nextKey];
 }
 }
 }
 }
 return to;
 },
 writable: true,
 configurable: true,
 });
 }
},

引用自: MDN-Object.assign()

因为本插件只兼容到 IE10,所以不打算对事件做兼容处理,毕竟IE9 都支持 addEventListener 了。

7.5 通过惰性载入进一步优化性能

在 5.1 中写的 getWheelDelta 函数每次执行都需要检测是否支持 event.wheelDelta ,实际上,浏览器只需在第一次加载时检测,如果支持,接下来都会支持,再做检测是没必要的。

并且这个检测在页面的生命周期中会执行很多次,这种情况下可以通过 惰性载入 技巧进行优化,如下:

getWheelDelta(event) {
 if (event.wheelDelta) {
 // 第一次调用之后惰性载入,无需再做检测
 this.getWheelDelta = event => event.wheelDelta;
 // 第一次调用使用
 return event.wheelDelta;
 } else {
 // 兼容火狐
 this.getWheelDelta = event => -event.detail;
 return -event.detail;
 }
},

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

使用JS判断字符串中包含内容方法总结

JS+HTML5实绑定鼠标事件的粒子动画

Copyright © 2019- awee.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务