• 22 Follow Along Link Highliter 中文指南
    • 挑战任务
    • 实现效果
    • 相关知识
    • 编程思路
    • 过程指南

    22 Follow Along Link Highliter 中文指南

    本篇作者:©大史快跑Dashrun——Chinasoft Frontend Developer

    简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 22 篇。完整指南在 GitHub,喜欢请 Star 哦♪(^∇^*)

    创建时间:2017-09-12
    最后更新:2017-09-16

    挑战任务

    初始文档index-start.html提供了一组使用<ul><li>标签包裹的导航标签。本次的编程挑战任务是完成如下动画效果:当鼠标移动至某个对应标签上时,为标签添加一个白色的背景框,高亮表示该标签被选中,当鼠标移动至其他标签后,白色背景框不消失,而是直接跟随鼠标平移至新的标签,实现效果见下图展示。

    实现效果

    结果展示

    相关知识

    Element.getBoundingClientRect()
    Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
    返回值是一个DOMRect对象,这个对象是由该元素的getClientRects()方法返回的一组矩形的集合, 即:是与该元素相关的CSS边框集合。DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
    DOMRect相关属性:

    Attribute Type Description
    bottom float Y 轴,相对于视口原点(viewport origin)矩形盒子的底部。只读。
    height float 矩形盒子的高度(等同于 bottom 减 top)。只读。
    left float X 轴,相对于视口原点(viewport origin)矩形盒子的左侧。只读。
    right float X 轴,相对于视口原点(viewport origin)矩形盒子的右侧。只读。
    top float Y 轴,相对于视口原点(viewport origin)矩形盒子的顶部。只读。
    width float 矩形盒子的宽度(等同于 right 减 left)。只读。
    x float X轴横坐标,矩形盒子左边相对于视口原点(viewport origin)的距离。只读。
    y float Y轴纵坐标,矩形盒子顶部相对于视口原点(viewport origin)的距离。只读。

    编程思路

    1.生成一个绝对定位的块元素,在后续改变其topleft坐标值移动至对应标签处,来呈现不同标签被激活的效果;
    2.鼠标移动至<li>标签后,使用Element.getBoundingClientRect()方法获得该标签的位置信息;
    3.将获得的<li>topleft值赋给绝对定位块元素,使其移动至被激活的标签,位于标签文字下方。

    过程指南

    1.生成绝对定位块元素

    1. var activeBackground = document.createElement('span');
    2. activeBackground.setAttribute('class','highlight');
    3. document.body.appendChild(activeBackground);
    4. //避免第一次激活时跳动,如果没有此句,可以看到第一次标签被激活时,块元素会从左上角移动至对应标签处。
    5. activeBackground.style.display = 'none';

    2.使用Element.getBoundingClientRect()方法获得对应标签的位置信息

    1. function lightOn(e){
    2. var activeLink = e.target.getBoundingClientRect();
    3. var coords = {
    4. height:activeLink.height,
    5. width:activeLink.width,
    6. left:window.pageXOffset + activeLink.left,
    7. top: window.pageYOffset + activeLink.top
    8. }
    9. activeBackground.style.height = `${coords.height}px`;
    10. activeBackground.style.width = `${coords.width}px`;
    11. activeBackground.style.left = `${coords.left}px`;
    12. activeBackground.style.top = `${coords.top}px`;
    13. activeBackground.style.display = 'inline';
    14. }

    3.将点亮函数与标签的鼠标移入事件绑定

    1. //监听鼠标移入事件及鼠标移出事件
    2. for(var i = 0; i < len; i++){
    3. oLi[i].onmouseenter = lightOn;
    4. }