PC 端网页特效

Posted 步步生花@苏殿主

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PC 端网页特效相关的知识,希望对你有一定的参考价值。

文章目录


一、元素偏移量 offset 系列

1、offset概述

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

  • 获得元素距离带有定位父元素的位置
  • 获得元素自身的大小(宽度高度)
  • 注意: 返回的数值都不带单位

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * 
            margin: 0;
            padding: 0;
        
        
        .father 
            /* position: relative; */
            width: 200px;
            height: 200px;
            background-color: pink;
            margin: 150px;
        
        
        .son 
            width: 100px;
            height: 100px;
            background-color: purple;
            margin-left: 45px;
        
        
        .w 
            width:200px;
            height: 200px;
            background-color: skyblue;
            margin: 0 auto 200px;
            padding: 10px;
            border: 15px solid red;
            box-sizing: border-box;
        
    </style>
</head>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="w"></div>
    <script>
        // offset 系列
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        // 1.可以得到元素的偏移 位置 返回的不带单位的数值  
        console.log(father.offsetTop);
        console.log(father.offsetLeft);
        // 它以带有定位的父亲为准  如果么有父亲或者父亲没有定位 则以 body 为准
        console.log(son.offsetLeft);
        var w = document.querySelector('.w');
        // 2.可以得到元素的大小 宽度和高度 是包含padding + border + width 
        console.log(w.offsetWidth);
        console.log(w.offsetHeight);
        // 3. 返回带有定位的父亲 否则返回的是body
        console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body
        console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
    </script>
</body>

</html>

2、 offset 与 style 区别

(1)offset

  • offset 可以得到任意样式表中的样式值
  • offset 系列获得的数值是没有单位
  • offsetWidth 包含padding+border+width
  • offsetWidth 等属性是只读属性,只能获取不能赋值
  • 所以,我们想要获取元素大小位置,用offset更合适

(2)style

  • style 只能得到行内样式表中的样式值
  • style.width 获得的是带有单位的字符串
  • style.width 获得不包含padding和border 的值
  • style.width 是可读写属性,可以获取也可以赋值
  • 所以,我们想要给元素更改值,则需要用style改变

案例:拖拽模态框

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .login-header 
            width: 100%;
            text-align: center;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
        
        
        ul,
        li,
        ol,
        dl,
        dt,
        dd,
        div,
        p,
        span,
        h1,
        h2,
        h3,
        h4,
        h5,
        h6,
        a 
            padding: 0px;
            margin: 0px;
        
        
        .login 
            display: none;
            width: 512px;
            height: 280px;
            position: fixed;
            border: #ebebeb solid 1px;
            left: 50%;
            top: 50%;
            background: #ffffff;
            box-shadow: 0px 0px 20px #ddd;
            z-index: 9999;
            transform: translate(-50%, -50%);
        
        
        .login-title 
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            height: 40px;
            font-size: 18px;
            position: relative;
            cursor: move;
        
        
        .login-input-content 
            margin-top: 20px;
        
        
        .login-button 
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #ebebeb 1px solid;
            text-align: center;
        
        
        .login-bg 
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: rgba(0, 0, 0, .3);
        
        
        a 
            text-decoration: none;
            color: #000000;
        
        
        .login-button a 
            display: block;
        
        
        .login-input input.list-input 
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ebebeb 1px solid;
            text-indent: 5px;
        
        
        .login-input 
            overflow: hidden;
            margin: 0px 0px 20px 0px;
        
        
        .login-input label 
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 14px;
        
        
        .login-title span 
            position: absolute;
            font-size: 12px;
            right: -20px;
            top: -30px;
            background: #ffffff;
            border: #ebebeb solid 1px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
        
    </style>
</head>

<body>
    <div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
    <div id="login" class="login">
        <div id="title" class="login-title">登录会员
            <span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label>用户名:</label>
                <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
            </div>
            <div class="login-input">
                <label>登录密码:</label>
                <input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
            </div>
        </div>
        <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
    </div>
    <!-- 遮盖层 -->
    <div id="bg" class="login-bg"></div>
    <script>
        // 1. 获取元素
        var login = document.querySelector('.login');
        var mask = document.querySelector('.login-bg');
        var link = document.querySelector('#link');
        var closeBtn = document.querySelector('#closeBtn');
        var title = document.querySelector('#title');
        // 2. 点击弹出层这个链接 link  让mask 和login 显示出来
        link.addEventListener('click', function() 
                mask.style.display = 'block';
                login.style.display = 'block';
            )
            // 3. 点击 closeBtn 就隐藏 mask 和 login 
        closeBtn.addEventListener('click', function() 
                mask.style.display = 'none';
                login.style.display = 'none';
            )
            // 4. 开始拖拽
            // (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
        title.addEventListener('mousedown', function(e) 
            var x = e.pageX - login.offsetLeft;
            var y = e.pageY - login.offsetTop;
            // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
            document.addEventListener('mousemove', move)

            function move(e) 
                login.style.left = e.pageX - x + 'px';
                login.style.top = e.pageY - y + 'px';
            
            // (3) 鼠标弹起,就让鼠标移动事件移除
            document.addEventListener('mouseup', function() 
                document.removeEventListener('mousemove', move);
            )
        )
    </script>
</body>

</html>

二、元素可视区 client 系列

1、client概述

client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

2、立即执行函数

  • 立即执行函数 (function() )() 或者 (function()())
  • 主要作用: 创建一个独立的作用域。 避免了命名冲突问题
<body>
    <script>
        // 1.立即执行函数: 不需要调用,立马能够自己执行的函数
        function fn() 
            console.log(1);

        
        fn();
        // 2. 写法 也可以传递参数进来
        // 1.(function() )()    或者  2. (function()());
        (function(a, b) 
            console.log(a + b);
            var num = 10;
        )(1, 2); // 第二个小括号可以看做是调用函数
        (function sum(a, b) 
            console.log(a + b);
            var num = 10; // 局部变量
        (2, 3));
        // 3. 立即执行函数最大的作用就是 独立创建了一个作用域, 里面所有的变量都是局部变量 不会有命名冲突的情况
    </script>
</body>

3、pageshow事件

  • pageshow事件在页面显示时触发,无论页面是否来自缓存。
  • 在重新加载页面中,pageshow会在load事件触发后触发
  • 根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加。
window.addEventListener('pageshow', function() 
    alert(11);
)

三. 元素滚动 scroll 系列

1、 元素 scroll 系列属性

scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

2、页面被卷去的头部

如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll 事件。

注意,元素被卷去的头部是 element.scrollTop , 如果是页面被卷去的头部 则是 window.pageYOffset,如果是被卷去的左侧 window.pageXOffset

案例:仿淘宝固定右侧侧边栏

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .slider-bar 
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        
        
        .w 
            width: 1200px;
            margin: 10px auto;
        
        
        .header 
            height: 150px;
            background-color: purple;
        
        
        .banner 
            height: 250px;
            background-color: skyblue;
        
        
        .main 
            height: 1000px;
            background-color: yellowgreen;
        
        
        span 
            display: none;
            position: absolute;
            bottom: 0;
        
    </style>
</head>

<body

PC 端网页特效-offset 系列及学习案例

PC 端网页特效-offset 系列及学习案例

学习地址还是在这里:JavaScript 基础语法-dom-bom-js-es6 新语法-jQuery-数据可视化 echarts 黑马 pink 老师前端入门基础视频教程(500 多集)持续

总归说学完一个是一个,不能继续下次一定了

offset 即 元素偏移量,PC 端的网页特效是一个系列:

  • offset
  • client
  • scroll
  • 动画函数封装

不过因为每周学习的进度关系,所以会将 PC 端网页特效做一个系列的笔记。

其学习案例有 3 个:

  1. 基础的 offset 应用案例,即获得鼠标在盒子中的坐标
  2. 拖曳窗口
  3. 仿京东放大镜

offset 概述

offset 即偏移量,使用 offset 系列相关属性可以 动态的 获取该元素的位置(偏移)、大小等,如:

  • 元素距离带有定位父元素的位置
  • 获取元素自身的大小(宽度高度)

注:返回的数值不带单位

offset 系列常用的属性包括:

  • element.offsetParent

    返回作为该元素带有定位的父级元素,如果父级元素没有定位,则返回 body

    注意,parentNodeoffsetParent 还是有本质上的区别的:parentNode 返回的是直接父级元素,offsetParent 返回的是带有定位的父级元素。

  • element.offsetTop

    返回元素带有定位父元素上方的偏移

  • element.offsetLeft

    返回元素带有定位父元素左边框的偏移

  • element.offsetWidth

    返回自身包括 padding, 边框, 内容区的宽度,返回数值不带单位

  • element.offsetHeight

    返回自身包括 padding, 边框, 内容区的高度,返回数值不带单位

offset 和 style 的区别

offsetstyle
offset 可以得到任意样式表中的样式值style 只能得到行内样式表中的样式值,无法获得内嵌样式
offset 系列获得的数值是没有单位的style.width 获得的是带有单位的字符串
offsetWidth 包含 padding+border+widthstyle.width 获得不包含 padding 和 border 的值
offsetWidth 等属性是只读属性,只能获取不能赋值style 属性是可读写属性,style.width 可以获取也可以赋值
只想要获取元素大小位置的时候,用 offset 更合适要对元素样式进行修改的话,使用 style 更合适

offset 学习案例

即获得鼠标在盒子中的坐标

效果图:

getting-coordinators

<!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" />
    <title>Document</title>
    <style>
      .box {
        width: 500px;
        height: 500px;
        background-color: #eee;
        margin-left: 50px;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <script>
      // 目标:
      // 在盒子中点击,想要获得鼠标距离盒子左右的距离
      // 实现:
      // 1. 获得鼠标在页面中的坐标,e.pageX, e.pageY
      // 2. 获得盒子到页面中的距离, box.offsetLeft, box.offsetTop
      // 3. 两者相减就能够获得鼠标在盒子中的坐标
      const box = document.querySelector(".box");
      box.addEventListener("mousemove", function (e) {
        // console.log(e.pageX, e.pageY);
        // console.log(box.offsetLeft, box.offsetTop);
        const x = e.pageX - this.offsetLeft;
        const y = e.pageY - this.offsetTop;
        box.textContent = `x: ${x}, y: ${y}`;
      });
    </script>
  </body>
</html>

拖曳窗口

这中还有一些 modal 的东西,不过效果图上没有展示出来。

效果图:

moving-element

实现是部分完整的——input 里面的东西我没有加进去,主要效果还是页面上的东西。

<!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" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      .login,
      .modal {
        display: none;
      }
      .login {
        width: 512px;
        height: 280px;
        position: fixed;
        border: #ebebeb solid 1px;
        left: 50%;
        top: 50%;
        background-color: #fff;
        box-shadow: 0 0 20px #ddd;
        z-index: 999;
        transform: translate(-50%, -50%);
        text-align: center;
      }
      .modal {
        position: absolute;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        background-color: rgba(0, 0, 0, 0.3);
        z-index: 998;
      }
      .login-content {
        margin: 100px auto;
        text-align: center;
      }
      .login-content h3:hover,
      .closeBtn:hover {
        cursor: pointer;
      }
      .closeBtn {
        position: absolute;
        right: 10px;
        top: 10px;
      }
      .login h4 {
        margin-top: 10px;
      }
      .login h4:hover {
        cursor: move;
      }
    </style>
  </head>
  <body>
    <div class="login-content">
      <h3 id="openLogin">点击弹出登录框</h3>
    </div>
    <div class="login">
      <div class="closeBtn" id="closeBtn">关闭</div>
      <h4 class="loginHeader">登录会员</h4>
    </div>
    <div class="modal"></div>
    <script>
      // 获取元素
      const login = document.querySelector(".login");
      const modal = document.querySelector(".modal");
      const closeBtn = document.querySelector("#closeBtn");
      const openLogin = document.querySelector("#openLogin");
      // 点击显示元素
      openLogin.addEventListener("click", () => {
        modal.style.display = "block";
        login.style.display = "block";
      });
      closeBtn.addEventListener("click", () => {
        modal.style.display = "none";
        login.style.display = "none";
      });
      // 实现拖拽移动功能
      // 1. 鼠标按下获得鼠标在盒子内的坐标
      const loginHeader = document.querySelector(".loginHeader");
      loginHeader.addEventListener("mousedown", function (e) {
        const x = e.pageX - login.offsetLeft;
        const y = e.pageY - login.offsetTop;
        const move = function (e) {
          login.style.left = `${e.pageX - x}px`;
          login.style.top = `${e.pageY - y}px`;
        };
        // 2. 移动鼠标
        document.addEventListener("mousemove", move);
        document.addEventListener("mouseup", function () {
          document.removeEventListener("mousemove", move);
        });
      });
    </script>
  </body>
</html>

仿京东放大镜

其他的部分是在品优购项目里面实现的,这个我还没做,所以没法复用页面。

无奈只好就直接用一个拉一个 div 先做案例吧。代码都是一样的,不知道为什么在自己电脑上好抖……晚点继续研究一下。另外就是代码注释还是不够,这也是个毛病。

magnifying-glass

实现代码:

<!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" />
    <title>Document</title>
    <style>
      .magnifying-glass {
        position: absolute;
        left: 100px;
        margin: 50px auto;
        min-height: 300px;
        border: 1px solid #ccc;
      }
      .modal {
        display: block;
        position: absolute;
        top: 0;
        left: 0;
        width: 300px;
        height: 300px;
        background-color: #fede4f;
        opacity: 0.5;
      }
      .modal:hover {
        cursor: move;
      }
      .enlarge-preview-wrapper {
        display: block;
        position: absolute;
        left: 460px;
        top: 0;
        width: 500px;
        height: 500px;
        overflow: hidden;
        border: 1px solid #ccc;
      }
      .enlarge-preview {
        position: absolute;
        top: 0;
        left: 0;
        width: 150%;
        height: auto;
      }
    </style>
  </head>
  <body>
    <div class="magnifying-glass">
      <img
        src="http://img10.360buyimg.com/n1/s450x450_jfs/t1/174266/32/5661/92244/607eb66fEcb90c325/8778d62b01b2c21b.jpg"
        class="preview-img"
      />
      <div class="modal"></div>
      <div class="enlarge-preview-wrapper">
        <img
          class="enlarge-preview"
          src="http://img10.360buyimg.com/n1/s450x450_jfs/t1/174266/32/5661/92244/607eb66fEcb90c325/8778d62b01b2c21b.jpg"
          alt=""
          srcset=""
        />
      </div>
    </div>

    <script>
      const previewImg = document.querySelector(".preview-img");
      const modal = document.querySelector(".modal");
      const enlargeImgWrapper = document.querySelector(
        ".enlarge-preview-wrapper"
      );
      // 案例分析
      // 1. 模块分割
      //      a. 鼠标经过小盒子图片,黄色的遮罩层和大图片盒子要被显示
      previewImg.addEventListener("mouseover", function (e) {
        modal.style.display = "block";
        enlargeImgWrapper.style.display = "block";
      });
      previewImg.addEventListener("mouseout", function (e) {
        modal.style.display = "none";
        enlargeImgWrapper.style.display = "none";
      });
      //      b. 黄色的遮罩层更随鼠标移动
      //          - 把鼠标坐标给遮挡层不合适,因为遮挡层坐标以父元素为准
      //          - 首先获得鼠标在盒子内的坐标
      //          - 获得的值作为遮挡层的 left 和 top
      previewImg.addEventListener("mousemove", function (e) {
        // 1. 先计算鼠标在盒子内的坐标
        const x = e.pageX - this.parentNode.offsetLeft;
        const y = e.pageY - this.parentNode.offsetTop;
        const maxX = this.offsetWidth - modal.offsetWidth;
        const maxY = this.offsetHeight - modal.offsetHeight;
        // 2. 计算最大最小空间
        let modalX = x - modal.offsetWidth / 2;
        modalX = modalX < 0 ? 0 : modalX > maxX ? maxX : modalX;
        let modalY = y - modal.offsetHeight / 2;
        modalY = modalY < 0 ? 0 : modalY > maxY ? maxY : modalY;

        modal.style.left = modalX + "px";
        modal.style.top = modalY + "px";
        //      c. 大图片跟随黄色遮罩层移动
        // 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 /遮挡层最大移动距离
        const enlargedImg = document.querySelector(".enlarge-preview");
        const modalMax =
          enlargedImg.offsetWidth - enlargeImgWrapper.offsetWidth;
        const enlargedX = (modalX * modalMax) / maxX;
        const enlargedY = (modalY * modalMax) / maxX;
        enlargedImg.style.left = -enlargedX + "px";
        enlargedImg.style.top = -enlargedY + "px";
      });
    </script>
  </body>
</html>

以上是关于PC 端网页特效的主要内容,如果未能解决你的问题,请参考以下文章

前端技术栈都有哪些

移动端和pc端,响应式设计布局

javascript课程大纲

pc端项目问题总结

Web前端期末大作业--零食商城网页设计(HTML+CSS+JavaScript+)实现

Web前端期末大作业--零食商城网页设计(HTML+CSS+JavaScript+)实现