当前位置: 首页 > news >正文

花店电子商务网站建设课题设计福州网站建设电话

花店电子商务网站建设课题设计,福州网站建设电话,站长之家网址ip查询,深圳画册设计印刷公司前言 原打算借鉴 vant-sticky 源码#xff0c;实现业务需求的某个功能#xff0c;第一眼看以为看懂了#xff0c;拿来用的时候#xff0c;才发现一知半解。看第二遍时#xff0c;对不起#xff0c;是我肤浅了。这里侧重分析实现原理#xff0c;其他部分不拓展开来…前言 原打算借鉴 vant-sticky 源码实现业务需求的某个功能第一眼看以为看懂了拿来用的时候才发现一知半解。看第二遍时对不起是我肤浅了。这里侧重分析实现原理其他部分不拓展开来否则像滚雪球越滚越多了。一边读源码一边学习使用技巧吧这里记录下心得感悟和大家共勉。 接下来会分析这三个的源码实现因为项目用的 Vue2故参考 Vant2 的 v2.12.54 版本 而该版本未实现 Vant3 的吸底距离功能故不做分析同学们交给你们啦。 如果只关注实现原理不关注每个部分实现细节的话可以跳到 onScroll 滚动事件部分。 项目启动和调试 clone 项目 git clone https://github.com/youzan/vant.git切换版本 git checkout v2.12.54安装和启动项目 npm run bootstrap npm run dev调试过程中可以打印些计算值帮助理解 源码分析 找到 vant-sticky 目录后开始我们的源码分析吧 html 部分 render() {const { fixed } this;const style {height: fixed ? ${this.height}px : null,};return (div style{style} // 1// bem({ fixed }) 生成 vant-sticky--fixeddiv class{bem({ fixed })} style{this.style} // 2{this.slots()}/div/div);}1 为包裹元素 用于占位因为内部元素 class‘vant-sticky–fixed’ 是用 fixed 实现的会脱离文档流。 2 class 和 style 都是根据 fixed 去决定是否展示。如下可见 class‘vant-sticky–fixed’ 内容是固定的而 style 是计算属性动态变化的。 因此这里学习到的两个 技巧 是 元素使用 fixed 时为了不影响滚动效果布局错乱可以包裹一个父元素去保持占位。由同个变量去控制一个元素的样式变化而静态的样式放到 class 里动态的放到 style 里。 css 部分 import ../style/var;.van-sticky {--fixed {position: fixed;top: 0;right: 0;left: 0;z-index: sticky-z-index; // sticky-z-index: 99;} }import ‘…/style/var’ 定义了 less 变量sticky-z-index: 99; computed: {style() {// 意味着 fixed 改变的同时 style 也改变了if (!this.fixed) {// 也就不设置 style 了因为是动态响应 dom 元素的return;}const style {};if (isDef(this.zIndex)) {// 修改层级vant 默认在 vant-sticky--fixed 里变量定义为 99这里通过传参修改style.zIndex this.zIndex; }if (this.offsetTopPx this.fixed) {style.top ${this.offsetTopPx}px; // 通过设置 top来设置偏移量}if (this.transform) {style.transform translate3d(0, ${this.transform}px, 0);}return style;},},初始的生命周期部分 created 生命周期 created() {// compatibility: https://caniuse.com/#featintersectionobserver// vant2 使用 SSR 写的故有 isServer 是否在服务器运行的判断// window.IntersectionObserver ie11 不支持if (!isServer window.IntersectionObserver) {this.observer new IntersectionObserver(// entries是一个数组每个成员都是一个 IntersectionObserverEntry 对象// 有几个被观察的成员就有几个对象(entries) {// 每次元素进入可视区 或 离开可视区时 触发if (entries[0].intersectionRatio 0) {this.onScroll();}},// root 属性指定目标元素所在的容器节点即根元素{ root: document.body });}},window.IntersectionObserver 自动观察元素是否可见本质是目标元素与视口产生一个交叉区只有线程空闲下来才会执行观察器 详见 阮一峰的 IntersectionObserver API 使用教程 后续会用到虽然把 IntersectionObserver 相关部分全都注释掉也不影响使用。 // 用法 this.observer new IntersectionObserver(callback, option)// 开始观察 this.observer.observe(this.$el);// 停止观察 this.observer.unobserve(this.$el);// 关闭观察器 this.observer.disconnect();通过 mixins混入生命周期函数 mounted、activated、deactivated、beforeDestroy 以绑定和取消监听事件 mixins: [BindEventMixin(function (bind, isBind) { // 1 BindEventMixin 建议先看下面的说明部分再往下看if (!this.scroller) {this.scroller getScroller(this.$el); // getScroller 从当前元素一直向上找到带有滚动属性的元素}// IntersectionObserver 的对象if (this.observer) {// 当绑定时isBind 为 true开始观察// 当取消监听时isBind 为 false停止观察const method isBind ? observe : unobserve; this.observer[method](this.$el);}// bind 即为 on addEventListenerbind(this.scroller, scroll, this.onScroll, true);this.onScroll();}),],1 简单分析下 BindEventMixin 实现如下 import { on, off } from ../utils/dom/event;let uid 0; // 入参 handler 是个函数 export function BindEventMixin(handler) {const key binded_${uid}; // 记录绑定function bind() {if (!this[key]) { // 没有绑定handler.call(this, on, true); // 把 on即 addEventListener传给 handler,第三个参数是告知 handler 当前状态是否绑定this[key] true; // 标记绑定}}function unbind() {if (this[key]) { // 绑定了则取消监听事件handler.call(this, off, false); // 把 off 即 removeEventListener 传给 handlerthis[key] false; // 标记w未绑定}}// 通过 mixins混入生命周期函数以绑定和取消监听事件return {mounted: bind, activated: bind,deactivated: unbind,beforeDestroy: unbind,}; }因此这里学习到的 技巧 是我们也可以通过 mixins 的方式去自动的绑定和取消监听事件。前提是符合这些生命周期需要一开始载入便监听的但 watch 某个数据变化去手动的监听和取消监听就不太适用了。当然也可以依据情况改造下函数。 props 和 data 部分 简单看下传值和变量定义部分 props: {zIndex: [Number, String], // 吸顶时的 z-indexcontainer: null, // 容器对应的 HTML 节点类型 ElementoffsetTop: { // 吸顶时与顶部的距离支持 px vw vh rem 单位默认 pxtype: [Number, String],default: 0,},},data() {return {fixed: false,height: 0, // 元素本身高度transform: 0, // 偏移量只在有容器且展示吸底效果时有用到};},onScroll 滚动事件部分 先搞清楚几个概念 scrollTop 为 滚动的距离 window.scrollTop: getBoundingClientRect():其提供了元素的大小及其相对于视口的位置 el.getBoundingClientRect().top: 可以发现在向上滚动的过程中window.scrollTop 不断增加el.getBoundingClientRect().top 不断减少。而增加的部分刚好等于减少的部分。 如果元素的顶部超出视口那么 el.getBoundingClientRect().top 为负值window.scrollTop 还是不断增加。 可以得出在滚动的过程中 el.getBoundingClientRect().top window.scrollTop 的值始终是不变的也就是元素初始的位置到视口顶部的距离此时 window.scrollTop 为 0。 接下来是重中之重的 onScroll 滚动事件部分先从 1、2 开始讲起 offsetHeight一个元素本身的高度 paddingborder滚动条不包括伪元素 因此在上面的基础上加上 el.offsetHeight也就是元素的初始位置的底部到视口顶部的距离 el.getBoundingClientRect().top window.scrollTop el.offsetHeight 实现原理 scrollTop offsetTopPx topToPageTop 当页面滚动距离 偏移量 大于 目标元素一开始距离顶部的距离时目标元素设置 fixed 属性吸顶。至于偏移量通过设置 top 属性去偏移。 当页面滚动距离 偏移量 小于 目标元素一开始距离定都的距离时意味着滚回去了那么移除 fixed 属性 methods: {onScroll() {// 判断当前元素及祖先元素是否隐藏了隐藏了就不需要滚动了if (isHidden(this.$el)) {return;}this.height this.$el.offsetHeight; // 当前元素的高度可用于占位一直不变的// offsetTopPx() 方法将 px vw vh rem 单位传值转换为 pxconst { container, offsetTopPx } this;// window 滚动的距离 window.scrollTopconst scrollTop getScrollTop(window);// getElementTop() 返回 el.getBoundingClientRect().top window.scrollTop// 上面分析过保持不变也就是 元素一开始与顶部的距离const topToPageTop getElementTop(this.$el);const emitScrollEvent () {this.$emit(scroll, {scrollTop,isFixed: this.fixed,});};// 先注释掉该部分后面讲解目前的部分足够实现 1 2 效果// if (container) {// ... // }// 当滚动距离达到指定上限页面滚动的距离偏移 元素一开始与顶部的距离 // offsetTopPx 偏移会用设置 top 来解决if (scrollTop offsetTopPx topToPageTop) {this.fixed true; // 设置 fixed 属性目标元素视口吸顶this.transform 0; // 重置因吸底容器效果而产生的偏移 transform后面会提到。} else {// 当滚回顶部时取消 fixedthis.fixed false;}emitScrollEvent();},}接下来分析 3 指定容器的情况。 有点特殊的是目标元素到达视口顶部时需要吸顶。而视口顶部到容器底部的距离小于目标元素时应该吸底容器如下图。 而在该特殊情况出现之前页面滚动偏移距离超出元素一开始到视口顶部距离时吸顶这部分和容器没有关系。代码实现和 1 2 部分相同 如果在容器和元素之间再放个元素是否也有吸底效果呢 div refcontainer styleheight: 150px; background-color: #fffvan-button typewarning假容器/van-buttonvan-sticky :containercontainer :offset-top20van-button typewarning stylemargin-left: 215px指定容器/van-button/van-sticky看样子这一版并不支持上述情况。因此默认目标元素一开始的位置是在容器边缘。下面的源码分析也就排除这一情况了。 实现原理 scrollTop offsetTopPx this.height bottomToPageTop 当页面滚动距离 偏移 目标元素高度超出了容器一开始的底部到视口顶部的距离 如果超出部分小于元素高度则展示吸底效果。设置 fixed 吸顶在通过 transfom 向上移动超出的距离以达到吸底容器的效果。 如果完全超出元素高度则消除所有静态、动态样式回到原样。 下面部分代码便是上述特殊吸底情况的分析。 if (container) {// 借鉴上面的分析排除不支持的情况后// el.getBoundingClientRect().top window.scrollTop 一开始目标元素到视口顶部的距离// 加上 container.offsetHeight 容器自身的高度为容器一开始从底部到视口顶部的距离const bottomToPageTop topToPageTop container.offsetHeight;// 页面滚动的距离偏移目标元素的高度 容器一开始从底部到顶部的距离// 意味着如果保持 fixed 的状态目标元素会超出容器底部这时候应该让它吸底if (scrollTop offsetTopPx this.height bottomToPageTop) {// 目标元素超出底部的距离 目标元素高度 页面滚动距离 - 容器一开始的底部到顶部的距离// 为什么不考虑偏移呢因为此时视觉上已经超出容器底部了不需要管偏移而是要吸附容器底部了const distanceToBottom this.height scrollTop - bottomToPageTop;// 超出距离 元素高度// 没有全部超出元素吸底展示if (distanceToBottom this.height) {// 给个 fixed 吸顶通过调整 transform 往上移动使得 视觉上元素到了容器的底部this.fixed true;// 需往上移动的距离为超出的距离 top 值的大小抵消掉 top 值因为原先的 top 值还在this.transform -(distanceToBottom offsetTopPx);} else {// 完全超出解除 fixed// 意味着 classvan-sticky--fixed 删除动态的 style 返回 {} this.fixed false;}emitScrollEvent();return;}在理解了上述原理后为我们的业务增效吧。动手之前多思考生搬硬套不可取。
http://www.hkea.cn/news/14569160/

相关文章:

  • 网站访问流量怎么赚钱wordpress标题图标
  • 网站建立的公司wordpress邮件样式美化
  • 免费个人网站+上传定制网站开发公司排名
  • 专业建设 验收 网站南阳企业网站建设公司
  • 建设门户网站费用牙科医院网站设计怎么做
  • 如何申请自己的个人网站好看的html页面
  • 有免费的网站服务器吗优化推广网站怎么做
  • 咸阳专业网站开发哪家好企业培训公司
  • 个人主题网站设计论文2021拉新推广佣金排行榜
  • 怎么欣赏一个网站设计图在网站后台备案号怎么改
  • 网站建设导航图图库php大型网站开发
  • h5网站案例无障碍环境建设 网站
  • 网站建设公司的成本有哪些内容在网站中设置网站地图
  • 外贸仿牌网站建设做鞋子有什么好网站好
  • 珠海市外贸网站建设公司高级网站开发工程师考试题
  • 网站开发技术语言大千科技网站建设
  • 做资格核查在哪个网站中国建设银行网站查询密码是什么意思
  • 工程业绩在建设厅网站都能查到微信微网站统计
  • 孝感做网站公司游戏优化大师官网
  • 安徽省公共资源交易中心网站电商一共有什么平台
  • 长春搜索引擎网站推广线下推广引流渠道
  • 中国未来巨型空间站网站建设与开发课程内容
  • 老外做牛排的视频网站网站建设公司推荐q479185700顶上
  • node做网站后台西安企业模板建站
  • 石家庄网推公司郑州seo顾问
  • 东莞网站建设求职简历网站设置右击不了如何查看源代码
  • 东莞建网站的公查公司的网站有哪些
  • 网站建设与管理知识点互联网保险公司有哪几家
  • 微网站建设正规公司宿州高端网站建设公司哪家好
  • 服装网站网络建设和硬件资源商贸公司起名大全最新