【日常记录】【JS】js 实现元素平滑上升

news2024/11/23 17:19:43

文章目录

    • 1、效果图
    • 2、基本骨架
    • 3、实现
    • 4、完整代码

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>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .container {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      width: 100%;
      padding-top: 300px;

    }

    .item {
      width: 70vw;
      height: 500px;
      margin-bottom: 20px;
      border-radius: 15px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="item" style="background-color: #cee288;" data-index="1"></div>
    <div class="item" style="background-color: #775414;" data-index="2"></div>
    <div class="item" style="background-color: #681dd1;" data-index="3"></div>
    <div class="item" style="background-color: #38d1a6;" data-index="4"></div>
    <div class="item" style="background-color: #50e211;" data-index="5"></div>
    <div class="item" style="background-color: #53357b;" data-index="6"></div>
    <div class="item" style="background-color: #f196ee;" data-index="7"></div>
  </div>
</body>

</html>

3、实现

为了不污染原有的样式,就不用css属性了,直接用JS创建动画
创建完动画,不能先让它执行动画,执行与不执行是我们决定

    let itemsEl = document.querySelectorAll('.item');
    itemsEl.forEach(f => {
      // 为了不污染原有的 transition 等其他属性,可以自己创建一个动画
      console.log(isInViewport(f), f);
      if (!isInViewport(f)) return
      let translateYAnimate = f.animate([
        { transform: 'translateY(80px)' },
        { transform: 'translateY(0)' }
      ], {
        duration: 1000, // 动画时常
      })
      translateYAnimate.pause() // 先暂停所有动画,需要通过其他的方法来判断 这个DOM 是否进入可视区

    })

在这里插入图片描述

这样达到的效果是,界面一加载,都做动画了,并不是预想的结果,需要判断这个Item 是否进入可视区,如果进入可视区,才能做动画

      let observe = new IntersectionObserver((entries) => {
        entries.forEach(f => {
          console.log(f);
          if (f.isIntersecting) {
            translateYAnimate.play()
            observe.unobserve(f.target) // 观察一次就行,只需要做一次动画
          } else {
          }
        })
      })
      observe.observe(f)

这样确实可以实现了,但是 浏览器会记住滚动条的位置,就会导致有问题,

  • 刚进来的时候,看到的DOM 并不需要做动画
  • 如果滚动到某一个位置后,刷新界面,再往上滚动,上面的DOM 也不需要做动画了

核心就是判断当前的DOM 距离视口顶部的距离 是否超过了 视口的高度, 如果是,才需要做动画,否则不需要

4、完整代码

<!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>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .container {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      width: 100%;
      padding-top: 300px;

    }

    .item {
      width: 70vw;
      height: 500px;
      margin-bottom: 20px;
      border-radius: 15px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="item" style="background-color: #cee288;" data-index="1"></div>
    <div class="item" style="background-color: #775414;" data-index="2"></div>
    <div class="item" style="background-color: #681dd1;" data-index="3"></div>
    <div class="item" style="background-color: #38d1a6;" data-index="4"></div>
    <div class="item" style="background-color: #50e211;" data-index="5"></div>
    <div class="item" style="background-color: #53357b;" data-index="6"></div>
    <div class="item" style="background-color: #f196ee;" data-index="7"></div>
  </div>

  <script>
  // 判断这个元素,是否在可视区里面
    const isInViewport = (el) => {
      const rect = el.getBoundingClientRect();
      console.log(rect.top);
      return (
        rect.top >= 0 &&
        rect.top >= (window.innerHeight || document.documentElement.clientHeight)
      );
    };
    let itemsEl = document.querySelectorAll('.item');
    // let elAnimateMap = new Map();
    itemsEl.forEach(f => {
      // 为了不污染原有的 transition 等其他属性,可以自己创建一个动画
      if (!isInViewport(f)) return
      let translateYAnimate = f.animate([
        { transform: 'translateY(80px)' },
        { transform: 'translateY(0)' }
      ], {
        duration: 1000, // 动画时常

      })
      translateYAnimate.pause() // 先暂停所有动画,需要通过其他的方法来判断 这个DOM 是否进入可视区
      // elAnimateMap.set(f, translateYAnimate)




      let observe = new IntersectionObserver((entries) => {
        entries.forEach(f => {
          console.log(f);
          if (f.isIntersecting) {
            translateYAnimate.play()
            // elAnimateMap.get(f.target).play()
            observe.unobserve(f.target) // 观察一次就行
          } else {
            // translateYAnimate.pause()
          }
        })
      })
      observe.observe(f)
    })

  </script>
</body>

</html>

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

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

相关文章

测试人员必备:常用自动化测试工具!

Appium 官网&#xff1a;http://appium.io AppUI自动化测试 Appium 是一个移动端自动化测试开源工具&#xff0c;支持iOS 和Android 平台&#xff0c;支持Python、Java 等语言&#xff0c;即同一套Java 或Python 脚本可以同时运行在iOS 和Android平台&#xff0c;Appium 是一…

2.1 LeetCode总结(基本算法)_DFS

1.4 练习 104. 二叉树的最大深度 int maxDepth(struct TreeNode *root, int len) {if (root NULL) {return len;}return fmax(maxDepth(root->left, len1), maxDepth(root->right, len1)); }二叉树最大深度就是基本的递归思路的求解&#xff0c; 手法主要是递归下去之…

React Hooks 全解: 常用 Hooks 及使用场景详解

React Hooks 是 React 16.8 版本引入的一项重要特性,它极大地简化和优化了函数组件的开发过程。 React 中常用的 10 个 Hooks,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useLayoutEffect、useImperativeHandle 和 useDebugValue。这些…

「JS 基础」迭代器和生成器 Iterator Generator 入门

前言 JavaScript的生成器(Generators)和迭代器(Iterators)是ES6引入的功能,使得开发者可以更方便地实现自定义的迭代逻辑。 迭代器 迭代器是一种接口,它为各种不同的数据结构(如数组或者映射)定义了一个标准的遍历方法。具体来说,一个迭代器对象必须实现一个 next…

背包问题详解

前言 本文主要讲解01背包问题&#xff0c;读者如果能完全搞懂01背包&#xff0c;那么稍作思考也能解决完全背包、多重背包问题。至于分组背包、有依赖的背包等问题博主也没有继续深入&#xff0c;但是应该都是在01背包的基础上拓展&#xff0c;读者若有兴趣可查阅其他文章。 …

电源监视继电器HRTH-J-2H2D AC220V 导轨安装 JOSEF约瑟

系列型号&#xff1a; HRTH-Y-2H2D-X-T跳位监视、合位监视、电源监控继电器&#xff1b; HRTH-Y-2Z-X-T跳位监视、合位监视、电源监控继电器&#xff1b; HRTH-Y-2H-X-T跳位监视、合位监视、电源监控继电器&#xff1b; HRTH-J-2H2D-X-T跳位监视、合位监视、电源监控继电器…

Django之rest_framework(一)

一、请求和响应对象介绍 REST framework引入了2个新的对象:Request和Response 1.1、Request rest_framework.request.Request 该对象扩展了常规的HttpRequest ,增加了对REST框架灵活的请求解析和请求认证的支持 官网:Requests - Django REST framework 主要属性: data 这…

react使用npm i @reduxjs/toolkit react-redux

npm i reduxjs/toolkit react-redux 创建一个 store文件夹&#xff0c;里面创建index.js文件和子模块文件夹 index,js文件写入以下代码 import {configureStore} from reduxjs/toolkit // 导入子模块 import counterReducer from ./modules/one import two from ./modules/tw…

计算机网络——CSMA/CD协议以及相关习题

目录 前言 引言 CSMA/CD协议 CSMA与CSMA/CD的区别 CSMA/CD流程 前言 本博客是博主用于复习计算机网络的博客&#xff0c;如果疏忽出现错误&#xff0c;还望各位指正。 引言 最早的以太网&#xff0c;许多计算机都连接在一根总线上工作——广播通信方式。 总线的特点想…

APP开发教学:开发同城O2O外卖跑腿系统源码详解

同城O2O外卖跑腿系统&#xff0c;满足了人们对于外卖送餐和生活服务的需求。今天&#xff0c;小编将为您讲解如何开发同城O2O外卖跑腿系统源码。 1.前期准备 首先&#xff0c;我们需要明确系统的功能需求和用户需求&#xff0c;包括外卖订购、配送员接单、支付功能等。其次&am…

排序1——C语言

排序 1. 复杂度2. 插入排序2.1 直接插入排序2.2 希尔排序 3. 选择排序3.1 直接选择排序3.2 堆排序 排序在生活中很常见&#xff0c;比如在网购时&#xff0c;按价格排序&#xff0c;按好评数排序&#xff0c;点餐时&#xff0c;按评分排序等等。而排序有快和慢&#xff0c;快的…

vue2响应式原理----发布订阅模式

很多人感觉vue2的响应式其实用到了观察者发布订阅。我们先来看一下简单的发布订阅的代码&#xff1a; // 调度中心 class Dep {static subscribes {}// 订阅所有需求static subscribe (key, demand) {// 对需求分类收集if (!Dep.subscribes[key]) Dep.subscribes[key] []Dep…

使用腾讯云服务器如何搭建网站?新手建站教程

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com整理使用腾讯云服务器建站教程&#xff0c;…

前端下载url文件(解决PDF, 图片自动在浏览器打开)

常规下载方法&#xff1a; /* 方法1 */ window.open(下载url地址, _blank)/* 方法2 */ const link document.createElement("a"); link.download true; link.href 下载url地址; link.click(); document.body.removeChild(link);pdf文件默认在浏览器中展示解决方案…

Linux:Zabbix + Grafana10.4.2(3)

1.部署zabbix 下面这篇文章写了详细的部署zabbix过程 &#xff0c;使用的centos9系统 Linux&#xff1a;部署搭建zabbix6&#xff08;1&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/137426966?spm1001.2014.3001.5501下面这篇文章使用的是centos7…

RTSP/Onvif安防视频EasyNVR平台 vs.多协议接入视频汇聚EasyCVR平台:设备分组的区别

EasyNVR安防视频云平台是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif协议接入的安防监控流媒体视频云平台。平台具备视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视频能力&#xff0c;能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、W…

二叉树练习day.8

235.二叉搜索树的最近公共祖先 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共…

30万的源码和300的源码有什么区别?

源码的质量很大程度上取决于其来源、开发者的技术水平和项目的具体需求。有些源码可能确实存在一些问题&#xff0c;比如代码结构混乱、注释不清晰、性能不佳等。 而价高优秀的源码都采用了高效的数据结构和算法&#xff0c;代码结构清晰&#xff0c;逻辑严谨&#xff0c;具有良…

ubuntu22下使用vscode调试redis7源码环境搭建

ubuntu22下使用vscode调试redis7源码环境搭建 ##vscode launch.json配置文件 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息&#xff0c;请访问: https://go.microsoft.com/fwlink/?linkid830387"version": "0.2.0&…

【神经网络与深度学习】循环神经网络基础

tokenization tokenization&#xff1a;分词 每一个词语都是token 分词方法&#xff1a;转为单个词、转为多个词语 N-gram表示法 准备词语特征的方法 &#xff08;把连续的N个词作为特征&#xff09; 如 ”我爱你“——>[我&#xff0c;爱&#xff0c;你] 2-gram——[[我…