美文网首页
组件之路---固钉组件

组件之路---固钉组件

作者: hsay | 来源:发表于2018-01-22 11:23 被阅读0次

固钉组件的作用是将页面元素固定在可视区域之内。

恩!是这样

需求

固钉的基本功能就是将元素固定在页面的特定位置,即使存在滚动条的情况下,固钉元素仍然可以固定在设定的位置。

这里位置固定所指的参考有两种情况:

  1. 元素相对窗口固定位置。
  2. 元素相对于父容器固定位置。

常规情况下,我们使用的是元素相对于窗口位置固定,这里直接使用fixed布局就可以了,但是对于第二种需求就不容易实现了,这也是固钉组件主要实现的功能。

预备知识

pageYOffset pageXOffset

pageYOffset pageXOffset是window的属性,表示整个页面滚动过的值,可以使用body元素的scrollTop属性替代。

scrollTop scrollLeft

scrollTop scrollLeft是Element的属性,表示一个具有属性的元素滚动过的值。

offsetTop offsetLeft

要想解释offsetTop 以及 offsetLeft的值,需要理解offsetParent的概念。
offsetParent可以返回距离当前元素最近的采用定位(position属性值为fixed、relative或者absolute)祖先元素。
如果祖先元素中没有采用定位的元素,则返回body对象。
offsetTop/offsetLeft返回值表示当前元素上边缘/左边缘距离offsetParent返回元素的距离的数值,单位是像素。

总结:scroll是与滚动相关的属性,offset是与offsetParent相关的属性值

innerHeight

innerHeight为window的属性,指窗口的大小(不包含工具条与滚动条)。

clientHeight

clientHeight这个属性是只读属性,对于没有定义CSS或者内联布局盒子的元素为0,同时它是元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距。
clientHeight 可以通过 CSS height + CSS padding - 水平滚动条高度.

offsetHeight

在IE6,IE7,IE8以及最新的的FF, Chrome中,在元素上都是offsetHeight = clientHeight + 滚动条 + 边框。

scrollHeight

这个高度与滚动条无关,是内容的实际高度。

计算方式 :scrollHeight = topPadding + bottomPadding + 内容margix box的高度。

总结:clientHeight与scrollHeight与滚动条有关,前者与设置的height有关,后者与元素所占据的实际高度有关

fixed布局

fixed布局是我们通常采用的实现元素固定在窗口的特定位置,如下图所示:


image

但是如果我们想实现基于任意父容器的固钉呢?即使其固定在父容器的指定位置,而不是单纯的固定在窗口的指定位置,如下图所示:


fixedToContainer.gif

实现原理

其实实现第二种需求的固钉仍然是基于fixed布局的,只不过我们这里加入的事件监听,动态的设置元素的top/bottom等值,以在视觉效果上实现相对于父元素的位置固定。

事件列表

events = [
    'resize',
    'scroll',
    'touchstart',
    'touchmove',
    'touchend',
    'pageshow',
    'load',
  ];

固钉组件组件要监听如上列表中列出的事件,由以上事件触发位置更新。

注意:这里监听事件的元素应该是固钉的容器元素target,若不指定target,会默认为body。

位置更新

以实现距离容器组件顶部为settingTop px为例,说明何时进行位置更新,以及如何位置更新。

const scrollTop = getScrollTop(targetNode);
const elemOffset = getOffset(affixNode, targetNode);
//elemOffset表示固钉的位置,包括父容器滚动过的值
const targetRect = getTargetRect(targetNode);
//targetRect是基于getBoundingClientRect得到的元素位置信息
//getBoundingClientRect方法返回元素的大小及其相对于视口的位置

if (scrollTop > elemOffset.top - settingTop) {
      // Fixed Top
      const width = elemOffset.width;
      const top = targetRect.top + settingTop;
      //即根据父容器的位置和设置的参数确定固钉的实际位置。
      this.setAffixStyle(e, {
        position: 'fixed',
        top,
        left: targetRect.left + elemOffset.left,
        width,
      });
}

这里有一个问题,即该如何去理解判断条件呢?

scrollTop > elemOffset.top - settingTop

其实可以将判断条件改写为:

elemOffset.top - scrollTop < settingTop

即页面向上滚动之后elemOffset.top - scrollTop(即固钉相对于父元素顶部的距离)小于预设值settingTop,发生位置更新。

同理,如果设置的参数是settingBottom,也可以以同样的思路分析。

总结

固钉实现的思路仍然是基于fixed布局,只不过我们为了实现相对于任意父元素的位置固定,引入了事件监听以及位置更新。理解位置更新的机制,关键是理解本文中涉及到的各种距离到底指的是什么。

相关文章

  • 组件之路---固钉组件

    固钉组件的作用是将页面元素固定在可视区域之内。 需求 固钉的基本功能就是将元素固定在页面的特定位置,即使存在滚动条...

  • 固钉小组件

    自制固钉小组件,支持上下左右定位 用法 Attributes 参数说明类型可选值默认值bottom距离窗口底部达到...

  • 力软未来产品发展方向

    集成更多组件、更多业务化子系统 《力软敏捷开发框架》后续将会集成更多的底层组件,如缓存管理、队列管理、钉钉组件、企...

  • iOS组件化文章汇总

    iOS应用架构谈 组件化方案 APP组件化之路 我所理解的组件化之路 iOS 组件化方案探索 围观神仙打架,反革命...

  • 钉钉图表组件

    基于f2的 如果有需要的在下边留言,基于浏览数量来决定是否写这个,同时还会详细介绍一些f2 的 配置,g2的也可以

  • 学习笔记 - iOS 组件化方案

    一、蘑菇街 App 的组件化之路 二、iOS应用架构谈 组件化方案 三、蘑菇街 App 的组件化之路·续 四、iO...

  • iOS 组件化

    参考:蘑菇街 App 的组件化之路蘑菇街 App 的组件化之路·续 iOS应用架构谈 组件化方案在现有工程中实施基...

  • 微信小程序性能优化实践

    历史回顾: 微信小程序自定义组件 - 表格组件来啦 通过微信小程序来实现 “钉钉打卡” 记一次微信小程序项目分包,...

  • 路由组件化

    撸一个简单路由RouteriOS 组件化与路由的本质App 的组件化之路

  • 组件化(一):搭建远程私有库

    组件化学习之路文章集合: 组件化(二):远程私有库的升级+依赖 组件化的话,我们一般都通过cocoapods库集成...

网友评论

      本文标题:组件之路---固钉组件

      本文链接:https://www.haomeiwen.com/subject/asxlaxtx.html