第一章-JavaScript基础进阶part4:PC端常见特效实现原理

news2024/11/26 12:51:21

文章目录

  • 一、元素偏移量offset
    • 1.1 offset常用属性
    • 1.2 offset与style的区别
    • 1.3 案例
  • 二、元素可视区client
    • 2.1 常用client属性
    • 2.2 client应用-flexible.js核心原理
  • 三、元素滚动scroll
    • 3.1 scroll系列常用属性
    • 3.2 mouseover和mouseenter的区别
  • 四、动画函数封装
    • 4.1 动画实现原理
    • 4.2 动画函数封装
    • 4.3 缓动动画

一、元素偏移量offset

1.1 offset常用属性

offset 翻译过来就是偏移量,我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等.它可以

  • 获得元素距离带有定位父元素的位置(offsetLeft,offsetTop)
  • 获得元素自身的大小( 宽度高度)(offsetWidth,offsetHeight)
  • 注意:返回的数值都不带单位
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .father{
            width:300px;
            height: 300px;
            margin: 200px;
            background: pink;
            position: relative;
        }
        .child{
            width: 200px;
            height: 200px;
            background: purple;
            margin: 40px;
            padding:10px;
            border: 2px solid red;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="child"></div>
    </div>
    <script>
        var father = document.querySelector(".father")
        var child = document.querySelector(".child")
        // 1.获取相对偏移量。注意:如果父元素没有定位,则默认返回相对body的偏移量
        // 当父元素.father有position:relative属性时,返回40,0;当你元素没有定位时返回240,200
        console.log(child.offsetLeft,child.offsetTop)

        // 2.获取自身大小(包含padding,border,width)
        console.log(child.offsetWidth, child.offsetHeight)  // 224 224

        // 3.获取具有定位的父元素(当父元素没有定位时默认为body)
        console.log(child.offsetParent) // .father有position:relative时,返回.father。
    </script>
</body>
</html>

1.2 offset与style的区别

1、offset

  • offset 可以得到任意样式表中的width,height样式值(内嵌,行内,外链样式)
  • offset 系列获得的数值是没有单位的(数值型)
  • offsetWidth包含padding+border+width
  • offsetWidth 等属性是只读属性,只能获取不能赋值
  • 总结:想要获取元素大小位置,用offset更合适

2、style

  • style 只能得到行内样式表中的样式值
  • style.width获得的是带有单位的字符串
  • style.width获得不包含padding和border的值
  • style.width 是可读写属性,可以获取也可以赋值
  • 想要给元素更改值,则需要用style改变
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .box {
            width: 200px;
            height: 200px;
            background: purple;
            margin: 40px;
            padding: 10px;
            border: 2px solid red;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <script>
        var box = document.querySelector(".box")
        let offsetWidth = box.offsetWidth
        let styleWidth = box.style.width
        // 1、因为style只能获取到行内样式的width值,所以此处输出224,空
        // 2、因为offset包含padding,border,width值,所以此处返回为200+10+10+2+2 = 224
        console.log(offsetWidth,styleWidth)
    </script>
</body>
</html>

1.3 案例

1、拖拽元素

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        width: 200px;
        height: 200px;
        background: pink;
        position: absolute;
        left: 0;
        top: 0;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <script>
      var box = document.querySelector(".box");

      // 鼠标按下,获取坐标
      box.addEventListener("mousedown", function (e) {
        box.addEventListener("mousemove", move);
      });
      function move(e) {
        // 示例1、获取鼠标在box内的坐标
        var pageX = e.pageX;
        var pageY = e.pageY;
        var offsetX = this.offsetLeft;
        var offsetY = this.offsetTop;
        var x = pageX - offsetX;
        var y = pageY - offsetY;
        this.innerHTML = "鼠标在盒内坐标(x,y):(" + x + "," + y + ")";

        // 示例2、拖拽实现 —— 绝对定位+动态定位赋值,默认鼠标在盒子居中位置
        var posLeft = pageX - box.offsetWidth / 2;
        var posTop = pageY - box.offsetHeight / 2;
        this.style.left = posLeft + "px";
        this.style.top = posTop + "px";
      }

      box.addEventListener("mouseup", function (e) {
        box.removeEventListener("mousemove", move);
      });
    </script>
  </body>
</html>

二、元素可视区client

2.1 常用client属性

client: 翻译过来是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6708420a63764e8d837e9f0bb234ffc5.png

2.2 client应用-flexible.js核心原理

1、立即执行函数
- 立即执行函数最大的作用是独立创建了一个作用域,里面的所有变量都是局部变量,不会有命名冲突的情况
- 创建独立作用域,避免命名冲突

// 1、具名函数直接调用
function fn(){
  console.log("执行了")
}
fn()

// 2、方式2.1 (Fun)()
(function(a,b){
  console.log(a+b)
})(1,2)

// 3、方式2.2 (Fun()())
(function(a,b){
  console.log(a+b)
}(3,4))

2、pageshow事件

  • 与onload事件相比,pageshow事件在页面显示时触发,且无论页面是否来自缓存都会触发(onload在firefox中如果有缓存页面数据,不会触发)。
  • pageshow会在load事件后触发
  • 根据事件对象中的persisted来判断 是否是缓存中的页面触发的。
  • pageshow事件,是给window对象添加的
// 立即执行函数 (function() {})() 或者 (function() {} ())
// 主要作用:创建一个独立的作用域,里面所有的变量都是局部变量,避免了命名冲突问题
// 立即执行函数不需要调用,立马能够自己执行
(function flexible (window, document) {
  // 获取html的根元素
  var docEl = document.documentElement
  // dpr 是物理像素比
  var dpr = window.devicePixelRatio || 1

  // adjust body font size 设置body的字体大小
  function setBodyFontSize () {
    // 如果页面中有body这个元素,就设置body的字体大小
    if (document.body) {
      document.body.style.fontSize = (12 * dpr) + 'px'
    }
    else {
      // 如果页面中没有body这个元素,则等着页面的主要DOM元素加载完毕再去设置body的字体大小
      document.addEventListener('DOMContentLoaded', setBodyFontSize)
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10  设置html元素的文字大小
  function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // reset rem unit on page resize  当页面尺寸大小发生变化的时候,要重新设置下rem的大小
  window.addEventListener('resize', setRemUnit)
  // pageshow 是重新加载页面触发的事件
  window.addEventListener('pageshow', function (e) {
    // e.persisted 返回的是true,就是说如果这个页面是从缓存取过来的页面,也需要重新计算一下rem的大小
    if (e.persisted) {
      setRemUnit()
    }
  })

  // detect 0.5px supports  有些移动端的浏览器不支持0.5像素的写法
  if (dpr >= 2) {
    var fakeBody = document.createElement('body')
    var testElement = document.createElement('div')
    testElement.style.border = '.5px solid transparent'
    fakeBody.appendChild(testElement)
    docEl.appendChild(fakeBody)
    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines')
    }
    docEl.removeChild(fakeBody)
  }
}(window, document))

三、元素滚动scroll

3.1 scroll系列常用属性

在这里插入图片描述

  • 页面被卷去的上侧距离 : window.pageYOffset
  • 页面被卷去的左侧距离 :window.pageXOffset
  • 滚动事件:window.onscroll 或window.addEventListener(“scroll”,fun)

1、offsetHeight,clientHeight,scrollHeight的区别
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div class="box" style="width:200px;height:200px;background: pink;border:6px solid blue;padding:10px">
    一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box一段超长文本超出box
  </div>
  <script>
    var box = document.querySelector(".box")
    let oh = box.offsetHeight // padding+border+height
    let ch = box.clientHeight // padding+height
    let sh = box.scrollHeight // padding+contentHeight
    // 输出:232 220 304
    console.log(oh,ch,sh)
  </script>
</body>
</html>

2、scroll的兼容性问题

  • 当页面声明了doctype时,被卷去的头部通过:document.documentElement.scrollTop获取
  • 当页面没声明doctype时,使用document.body.scrollTop
  • 在IE9以后,通过window.pageYOffset和window.pageXOffset获取
function getScroll(){
  return {
    left :window.pageXOffset ||document.documentElement.scrollLeft||document.body.scrollLeft,
    top:window.pageYOffset || document.documentElement.scrollTop||document.body.scrollTop,
  }
}

3、使用场景

  • offset属性:常用于获取元素的位置
  • client属性:获取元素大小
  • scroll属性:用于获取滚动距离

3.2 mouseover和mouseenter的区别

  • 当鼠标移动到元素上时就会触发mouseenter事件
  • mouseover鼠标经过自身盒子会触发,经过子例子还会触发。mouseenter只会经过自身盒子触发(因为mouseenter不会冒泡)
  • mouseenter对应mouseleave
  • mouseover对应mouseout

四、动画函数封装

4.1 动画实现原理

核心原理:通过定时器setInterval()不断移动盒子位置
实现盒子移动动画:

  1. 获得例子当前位置
  2. 让例子在当前位置加上1个移动距离
  3. 利用定时器不断重复这个操作
  4. 加一个结束定时器的条件
  5. 注意此元素需要绝对定位,才能使用用element.style.left控制移动
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        width: 100px;
        height: 100px;
        background: pink;
        position: absolute;
        left: 0;
        top: 0;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <script>
      var box = document.querySelector(".box");
      var timer = setInterval(() => {
        if(box.offsetLeft>=500){
          clearInterval(timer)
        }
        let left = box.offsetLeft + 1;
        box.style.left = left + "px";
      });
    </script>
  </body>
</html>

4.2 动画函数封装

  1. 设置函数目标对象
  2. 确定目标位置
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .big {
        width: 200px;
        height: 200px;
        background: pink;
        position: absolute;
        left: 0;
        top: 0;
      }
      .small {
        width: 100px;
        height: 100px;
        background: blue;
        position: absolute;
        left: 0;
        top: 220px;
      }
    </style>
  </head>
  <body>
    <div class="big">big</div>
    
    <div class="small"><button>small开始动画</button></div>
    <script>
      // 1、封装动画函数
      //  elObj -> 要实现动画的元素对象, target:停止动画的距离
      function animate(elObj, target) {
        // 如果元素对象有定时器,需要先清理,防止重复创建定时器
        if (elObj.timer) {
          clearInterval(elObj.timer);
        }
        // 持续设置元素左边距
        elObj.timer = setInterval(() => {
          if (elObj.offsetLeft > target) {
            clearInterval(elObj.timer);
          }
          elObj.style.left = elObj.offsetLeft + 1 + "px";
        }, 5);
      }
      var big = document.querySelector(".big");
      var small = document.querySelector(".small");
      var btn = document.querySelector("button");
      btn.addEventListener("click", function () {
        animate(small, 300);
      });
      animate(big, 400);
    </script>
  </body>
</html>

4.3 缓动动画

原理:

  • 缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
  2. 核心算法:(目标值-现在的位置)/ 10 做为每次移动的距离步长
  3. 停止的条件是:让当前盒子位置等于目标位置就停止定时器
    注意:动画步长需要取整,步长大于0时向上取整,小于0时向下取整
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .big {
        width: 200px;
        height: 200px;
        background: pink;
        position: absolute;
        left: 0;
        top: 0;
      }
      
    </style>
  </head>
  <body>
    <div class="big">big</div>
    <script>
      // 1、缓动动画原理:随时时间增加,移动距离减少
      function animate(elObj, target) {
        // 如果元素对象有定时器,需要先清理,防止重复创建定时器
        if (elObj.timer) {
          clearInterval(elObj.timer);
        }
        // 持续设置元素左边距
        elObj.timer = setInterval(() => {
          // 步长值,用于控制每次移动距离 
          var step = (target - elObj.offsetLeft)/10
          if (elObj.offsetLeft == target) {
            clearInterval(elObj.timer);
          }
          elObj.style.left = elObj.offsetLeft + step + "px";
        }, 15);
      }
      var big = document.querySelector(".big");
    
      animate(big, 1200);
    </script>
  </body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/847930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JNI之Java实现远程打印

打印机是最常见的办公设备了。一般情况下如果需要实现打印&#xff0c;可通过前端print.js包来完成。但是&#xff0c;如果要实现智能办公打印&#xff0c;就可以使用JNI技术、封装接口、远程调用实现完成。 导包 jacob&#xff1a;Java COM Bridge <dependency><g…

python实现简单的爬虫功能

前言 Python是一种广泛应用于爬虫的高级编程语言&#xff0c;它提供了许多强大的库和框架&#xff0c;可以轻松地创建自己的爬虫程序。在本文中&#xff0c;我们将介绍如何使用Python实现简单的爬虫功能&#xff0c;并提供相关的代码实例。 如何实现简单的爬虫 1. 导入必要的…

7 个最佳Node.js日志记录库和聚合器

日志记录是软件测试的重要组成部分。当我们知道错误是什么以及代码中出现问题的确切行时&#xff0c;调试应用程序要容易得多。 在本文中&#xff0c;我们将探讨与 Node.js 中的日志记录相关的各种概念&#xff0c;包括七个流行的日志记录库和聚合器&#xff0c;您可以使用它们…

【Linux进阶之路】进程(上)

文章目录 前言一、操作系统加载过程二、进程1.基本概念2.基本信息①运行并观察进程②创建子进程③僵尸与孤儿进程&#xff08;父子进程衍生出来的问题&#xff09;1. 僵尸进程&#xff08;Zombie状态&#xff09;2. 孤儿进程 3.基本状态①操作系统的状态&#xff08;统一&#…

计算机视觉--距离变换算法的实战应用

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 计算机视觉CV是人工智能一个非常重要的领域。 在本次的距离变换任务中&#xff0c;我们将使用D4距离度量方法来对图像进行处理。通过这次实验&#xff0c;我们可以更好地理解距离度量在计算机视觉中的应用。希望大家对计算…

栈和队列(二) 队列操作详解及栈与队列的相互实现

文章目录 四、队列1、什么是队列2、队列的基本操作Queue.hQueue.c初始化队列队尾入队列队头出队列获取队列头部元素获取队列队尾元素获取队列中有效元素个数检测队列是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果非空返回0销毁队列 五、设计循环队列六、栈与队列的…

virt-manager上安装ubuntu22.04虚拟机

文章目录 前言一、镜像下载二、 virt-manager新建机器2.1 选择安装来源类型2.2 选择ISO文件2.3 设置CPU数量和内存容量2.4 设置硬盘容量2.5 设置虚拟机类型&#xff0c;勾选配置按钮2.6 修改硬盘驱动类型2.7 修改网卡驱动类型2.8 设置显示器类型2.9 开始安装 三、操作系统安装3…

Von Maur, Inc EDI 需求分析

Von Maur, Inc 是一家历史悠久的卖场&#xff0c;成立于19世纪&#xff0c;总部位于美国。作为一家知名的零售商&#xff0c;Von Maur 主要经营高端时装、家居用品和美妆产品。其使命是为顾客提供优质的产品和无与伦比的购物体验。多年来&#xff0c;Von Maur 凭借其卓越的服务…

计算机视觉应用方向

计算机视觉可以大致有以下几个方向&#xff08;更详细的可以参考papers with code&#xff09;&#xff1a; 图像分类目标检测图像分割图像生成风格迁移超分辨率 1. 图像分类 图像分类是是视觉识别中的一项基本任务&#xff0c;目的是分辨整个图像并将其分类。 1.1 常用数据…

php使用get和post传递数据出现414 Request-URI Too Large的解决方案

递数据出现414 Request-URI Too Large的解决方案 一、Request-URI Too Large的原因二、GET与POST三、项目分析1.读取源数据2.将读取的到数据&#xff0c;进行传递3.ajax获取传递的数据并传递到后台4.传递数据5.解决方案 一、Request-URI Too Large的原因 “Request-URI Too La…

如果你不只是个点工,那你应该知道 前后端分离与不分离的区别

Web 应用的开发主要有两种模式&#xff1a; 前后端不分离 前后端分离 理解它们的区别有助于我们进行对应产品的测试工作。 前后端不分离 在早期&#xff0c;Web 应用开发主要采用前后端不分离的方式&#xff0c;它是以后端直接渲染模板完成响应为主的一种开发模式。以前后端…

理想汽车:中国电动汽车领域最有投资价值的公司?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;尽管面临着价格和中国电动汽车市场需求放缓的压力&#xff0c;但理想汽车&#xff08;LI&#xff09;在6月份还是交付了32,575辆电动汽车&#xff0c;并且超过了竞争对手蔚来&a…

element-plus:el-date-picker日期只选择年月不要日

<el-date-picker v-model"value" type"month" format"YYYY-MM" value-format"YYYY-MM" />使用format属性将时间显示格式修改为YYYY–MM 年月格式 使用value-format将绑定值的格式修改为YYYY–MM年月格式

DNS解析过程实践分析【nslookup演示】

基本原理 首先一句话概括&#xff0c;DNS就是做域名到IP的映射&#xff0c;rdns表示IP到域名的映射。 怎么映射&#xff0c;其中传递的报文&#xff0c;以及如何进行进行扫描&#xff0c;记录类型都大有讲究。涉及到网络空间测绘当中的DNS扫描&#xff0c;dos也有DNS的相关应…

企升编辑器word编写插件

面向用户群体招投标人员&#xff0c;用统一的模板来编写标书&#xff0c;并最终合并标书。项目经理&#xff0c;编写项目开发计划书&#xff0c;项目验收文档等。开发人员&#xff0c;编写项目需求规格说明书、设计说明书、技术总结等文档。其他文档编写工作量较多的岗位人员。…

小红书 KOL 种草执行策略揭秘:打造爆款产品,提升品牌影响力

随着互联网的普及和社交媒体的发展&#xff0c;小红书成为了众多年轻人购物决策的重要参考平台。小红书 KOL 种草作为一种新兴的营销方式&#xff0c;以其强大的传播力和影响力&#xff0c;越来越受到各大品牌的重视。本文伯乐网络传媒将给大家深入探讨小红书 KOL 种草的执行策…

TS协议概念及传输流程

TS协议之PAT&#xff08;节目关联表&#xff09;TS协议之PMT&#xff08;节目映射表&#xff09;TS协议之PES&#xff08;ES数据包&#xff09; 概要 TS协议是一种媒体流封装协议&#xff0c;类似于MP4&#xff0c;FLV等&#xff0c;可以将编码好的视频流(H164,H265等)和音频…

大数据——推荐系统

1 推荐系统的发展 推荐系统是指面对没有需求的用户在进入产品时&#xff0c;要给用户推荐什么东西&#xff0c;现在的APP基本上都会采用推荐系统。 从一开始的1990s开始的门户网站&#xff0c;像Yahoo、搜狐和Hao123等等&#xff0c;都是基于分类目录的网页导航网站&#xff0…

【Elasticsearch】学好Elasticsearch系列-聚合查询

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 先看后赞&#xff0c;养成习惯。 点赞收藏&#xff0c;人生辉煌。 文章目录 概念doc values 和 fielddatamulti-fields&#xff08;多字段&#xff09;类型聚合分类分桶聚合Histogram 聚合 指标聚合Percentil…

用chatGPT从左右眼图片生成点云数据

左右眼图片 需求 需要将左右眼图像利用视差生成三维点云数据 先问问chatGPT相关知识 进一步问有没有现成的软件 chatGPT提到了OpenCV&#xff0c;我们让chatGPT用OpenCV写一个程序来做这个事情 当然&#xff0c;代码里面会有一些错误&#xff0c;chatGPT写的代码并不会做模…