PC端网页特效:偏移量offset、可视client、滚动scroll、动画效果及其案例

目录

1. 元素偏移量

1.1 offset 概述

1.2 offset 和 style 的区别

1.3 获取鼠标在盒子里的坐标

 1.4 拖动模态框

 1.5 京东放大镜效果案例

2. 元素可视client 系列

 2.1 立即执行函数

2.2 淘宝flexibleJS源码分析之核心原理

3. 元素滚动scorll 系列

3.1 属性

 3.2 仿淘宝右侧侧边栏案例

3.3 大三总结

 3.4 mouseenter 和mouseover

4. 动画函数封装

4.1 动画实现原理

 4.2 动画封装函数

 4.3 给不同的元素记录不同的定时器


1. 元素偏移量

1.1 offset 概述

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

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

offset 常用属性 :

  • .offsetWidth=padding+border+width(.offsetHeiht同)
  • .offsetTop/.offsetLeft:如果父级没有定位,以body为准

.offsetParent 与.parentNode 的区别:

  • 前者需要父亲有定位
  • 后者是最近一级的父亲,无论父亲有无定位

1.2 offset 和 style 的区别

总结:获取元素大小用offset,修改大小用style 

1.3 获取鼠标在盒子里的坐标

案例分析:

  1. 点击盒子得到盒子得到鼠标盒子左右的距离
  2. 首先得到鼠标在页面中的坐标(e.pageX,e.pageY)
  3. 然后得到盒子在页面中的距离(box.offsetLeft,box.offsetRight)
  4. 1-2即可得到
  5. 如果想得到鼠标移动鼠标,得到鼠标坐标,可用mousemove鼠标移动事件
<!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: aquamarine;
            margin: 100px auto;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <script>
        var box = document.querySelector('.box');
        box.addEventListener('click', function (e) {
            // console.log(e.pageX);
            // console.log(e.pageY);
            // console.log(box.offsetLeft);
            // console.log(box.offsetTop);
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            this.innerHTML = 'x是' + x + 'y是' + y;
        })
    </script>
</body>

</html>

 效果:点击可显示坐标

 1.4 拖动模态框

点击弹出页面,点击按钮关闭页面分析:

  1. 点击弹出框,模态框和遮挡层就会显示出来 display:block;
  2. 点击关闭按钮,模态框和遮挡层会隐藏起来 display:none;

根据鼠标可以拖拽页面分析:

  • 原理:鼠标按下并移动鼠标,之后松开鼠标
  • 触发事件是鼠标按下mousedown,移动鼠标mousemove,鼠标松开mouseup
  • 拖拽过程:鼠标移动过程,获得最新的值赋值给模态框的left值和top值,模态框跟鼠标走
  • 鼠标按下的事件源是最上面的一行,id是title
  • 鼠标的坐标减去鼠标在盒子内的坐标,才是模态框的真正位置
  • 鼠标按下,得到在盒子的坐标
  • 鼠标移动,模态框的坐标=鼠标坐标-盒子坐标,注意移动事件
  • 鼠标弹起,停止拖拽
<!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>拖动模态框</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>
        var login = document.querySelector('.login');
        var mask = document.querySelector('.login-bg');
        var link = document.querySelector('#link');
        var closeBtn = document.querySelector('#closeBtn');
        var btn2 = document.querySelector('#title');
        // 点击和隐藏
        link.addEventListener('click', function () {
            mask.style.display = 'block';
            login.style.display = 'block';
        })
        closeBtn.addEventListener('click', function () {
            mask.style.display = 'none';
            login.style.display = 'none';
        })
        // 拖拽
        btn2.addEventListener('mousedown', function (e) {
            var x = e.pageX - login.offsetLeft;
            var y = e.pageY - login.offsetTop;
            document.addEventListener('mousemove', move)
            function move(e) {
                login.style.left = e.pageX - x + 'px';
                login.style.top = e.pageY - y + 'px';
            }
            // 弹起移除
            document.addEventListener('mouseup', function (e) {
                document.removeEventListener('mousemove', move)
            })
        })


    </script>
</body>

</html>

效果:

 1.5 京东放大镜效果案例

案例分析:

  1. 鼠标经过小图片盒子,黄色遮挡层和大图片盒子显示,离开隐藏2个盒子功能(style.display=none/block)
  2. 黄色的遮挡层跟随鼠标功能(鼠标在盒子内的坐标给遮挡层(定位,top、left),用
  3. 移动黄色遮挡层,大图片跟随移动(遮挡层移动距离/遮挡层最大移动距离=大图片移动距离/大图片最大移动距离,图片加定位,top、left值等于图片移动距离)

 window.addEventListener('load', function()} 一定要加这个,让html页面加载完再执行js文件

2. 元素可视client 系列

client就是客户端,,可以返回元素边框大小,元素大小

  •  与offsetWidth最大的区别是不包含边框
  • 重点用clientWidth 和clientHeight

 2.1 立即执行函数

不需要调用,马上执行函数

 写法:1.(function(){}();  即()()

 立即函数的最大作用:就是独立创立了一个作用域,里面的变量都是局部变量,避免命名冲突

2.2 淘宝flexibleJS源码分析之核心原理

  • load页面加载事件触发(3个情况):
  • a链接
  • f5或者刷新按钮
  • 前进后退按钮

 pageshow 页面加载事件 与load 事件区别:在页面显示时触发,无论页面是否来自缓存,在load事件触发后触发,这个事件是给window添加的,根据时间对象persisted判断缓存中的pageshow事件,返回true,false

(function flexible(window, document) {
    //  获取html的根元素
    var docEI = document.documentElement
    // dpr物理像素比
    var dpr = window.devicePixelRatio || 1
    // 1.设置body的字体大小
    function setBodyFontSize() {
        if (document.body) {
            document.body.style.fontSize = (12 * dpr) + 'px'
        } else { //script引入在head里面,js没有body
            // dom元素加载完再去设置body,DOMContentLoaded 是dom里面的标签元素
            document.addEventListener('DOMContentLoaded', setBodyFontSize)
        }
    }
    setBodyFontSize();

    // 2. 设置html文字大小
    function setRemUnit() {
        var rem = docEI.clientWidth / 10; //页面分成十等分
        docEI.style.fontSize = rem + 'px'
    }
    setRemUnit()

    // 3.页面尺寸变化,重新设置rem的大小
    window.addEventListener('resize', setRemUnit)
    window.addEventListener('pageshow', function (e) { //pageshow 是加载事件 
        if (e.persisted) {
            setRemUnit();
        }
    })
})(window, document)

3. 元素滚动scorll 系列

3.1 属性

scorll翻译是滚动,该属性可以得到元素的大小,滚动距离

  • 使用最多的是scrollTop,scrollLeft 
  • 得到的是元素的实际内容大小(被卷去的距离)

 3.2 仿淘宝右侧侧边栏案例

案例分析

  • 原先的侧边栏是绝对定位
  • 当页面滚动到一定位置ban,侧边栏改固定定位
  • window.pageYOffset:获得页面被卷去的头部元素被卷去的是头部:element.scrollTop
  • 页面继续滚动,会显示返回顶部案例
  • 页面滚动,事件源是document

页面被卷去头部有兼容性问题,ie9以上兼容

 

<body>
    <div class="side">
        <span class="goBack">返回顶部</span>
    </div>
    <header class="head w">头部</header>
    <div class="ban w">banner</div>
    <div class="main w">主体</div>
    <script>
        var side = document.querySelector('.side');
        var goBack = document.querySelector('.goBack');
        var ban = document.querySelector('.ban');
        var main = document.querySelector('.main');
        //被卷去头部的大小,一定要写到滚动的外面,offsetTop带有定位父元素(无是body)的偏移量
        var banTop = ban.offsetTop;
        var sideTop = side.offsetTop - banTop;
        var mainTop = main.offsetTop;
        // 滚动事件
        document.addEventListener('scroll', function () {
            // pageYOffset页面卷去的头部,,侧边栏变固定定位
            if (window.pageYOffset >= banTop) {
                side.style.position = 'fixed';
                side.style.top = sideTop + 'px';
            } else {
                side.style.position = 'absolute';
                side.style.top = '300px';
            }
            // 当我们页面滚动到main盒子,就显示 goback模块
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block';
            } else {
                goBack.style.display = 'none';
            }

        })
    </script>
</body>

3.3 大三总结

 

  • offsetTop系列经常用于获取元素的位置
  • clientWight/Height 用于获取元素的大小
  • scorllTop获取元素滚动的距离
  • 页面滚动距离可以通过window.pageXoffset获得

 3.4 mouseenter 和mouseover

mouseenter 鼠标事件:移动自身盒子、子盒子都会触发;不会冒泡

mouseover 鼠标事件:只经过自身盒子会触发

mouseenter与mouseleave 搭配,同样不会冒泡

4. 动画函数封装

4.1 动画实现原理

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

实现步骤:

  1. 获得盒子的位置,让盒子在当前的位置上1一个移动距离
  2. 利用定时器不断重复这个操作
  3. 加个定时器结束的条件
  4. 这个元素加定位,才能使用element.style.left

 4.2 动画封装函数

注意函数需要传递2个参数,动画对象和移动到的距离

<!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>
        div {
            position: absolute;
            left: 0;
            width: 50px;
            height: 50px;
            background-color: aqua;
        }
    </style>
</head>

<body>
    <div></div>
    <script>
        // 简单封装动画函数
        function animate(obj, target) {
            var time = setInterval(function () {
                if (obj.offsetLeft >= target) {
                    clearInterval(time);
                }
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }, 0.1);
        }
        var div = document.querySelector('div');
        animate(div, 300);
    </script>
</body>

</html>

 4.3 给不同的元素记录不同的定时器

<body>
    <button>点击运动</button>
    <div></div>
    <span></span>
    <script>
        // 给不同元素给定不同定时器
        function animate(obj, target) {
            obj.time = setInterval(function () {
                if (obj.offsetLeft >= target) {
                    clearInterval(obj.time);
                }
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }, 0.1);
        }
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        var btn = document.querySelector('button');
        // 不断点击按钮,元素速度加快,因为开启太多的定时器
        // 解决方案,让元素只有一个定时器在执行
        clearInterval(obj.target);
        btn.addEventListener('click', function () {
            animate(span, 500)
        })
        animate(div, 300);

    </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值