JavaScript-12-PC端网页特效

本文详细解读了网页开发中元素偏移量(offset)、可视区(client)和滚动(scroll)系列的属性与用法,包括动态获取元素尺寸、位置、滚动状态,并介绍了flexible.js的源码和常见网页特效如轮播图、节流阀的实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

元素偏移量offset系列

概述

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

常用属性

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

注:

  1. offsetParent 返回带有定位的父级元素
  2. parentNode 返回最近一级的父级元素
  • element.offsetTop 返回元素相对带有定位父元素上方的偏移
  • element.offsetLeft 返回元素相对带有定位父元素左边框的偏移
  • element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
  • element.offsetHeight 返回自身包括padding、边框、内容区的宽度,返回数值不带单位

offset与style

offsetstyle
作用可以得到任意样式表中的样式值行内样式表中的样式值
返回值不带单位的数值带有单位的字符串
width 返回值padding+border+width的数值不包含padding和border的值
属性offsetWidth等属性是只读属性,只能获取不能赋值style.width是可读写属性,可获取也可赋值
适用获取元素大小位置更改元素值

元素可视区client系列

概述

使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态得到该元素的边框大小、元素大小等。

常用属性

  • element.clientTop 返回元素上边框的大小
  • element.clientLeft 返回元素左边框的大小
  • element.clientWidth 返回自身包括padding、内容区宽度,不含边框,返回数值不带单位
  • element.clientHeight 返回自身包括padding、内容区高度,不含边框,返回数值不带单位

元素滚动scroll系列

概述

使用scroll系列的相关属性可以动态地得到该元素的大小、滚动距离等

常用属性

  • element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
  • element.scrollLeft 返回被卷去的左侧距离,返回数值不带单位
  • element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
  • element.scrollHeight 返回自身实际的高度,不含边框,返回数值不带单位

页面卷去头部兼容性解决方案

function getScroll(){
    return(
        left:window.pageXOffset || document.documentElement.scrollLeft||document.body.scrollLeft||0,
        top:window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0
    );
}

三大系列

三大系列作用主要用法
element.offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位获取元素位置
element.clientWidth返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位获取元素大小
element.scrollWidth返回自身实际的宽度,不含边框,返回数值不带单位获取滚动距离

页面滚动距离通过 window.pageXOffset获得

在这里插入图片描述

flexible.js源码分析

立即执行函数

  • 含义:不需要调用,能够立马执行函数
  • 主要作用:创建一个独立的作用域,避免了命名冲突问题
  • 语法规范:
  1. (function(形参){})(实参);
  2. (function(形参){}(实参));

pageshow

触发load事件的情况

  1. a标签的超链接
  2. F5或刷新按钮(强制刷新)
  3. 前进后退按钮
    火狐浏览器有“往返缓存”,后退的时候不能刷新页面。针对这一问题,使用pageshow,在页面显示时触发,无论是否来自缓存,都会重新加载页面。

pageshow 只针对window元素
persisted属性,判断页面是否来自于缓存

mouseenter和mouseover

mouseenter

鼠标移动到元素上时就会触发,只会经过自身盒子触发。不会冒泡。搭配mouseleave,也不会冒泡

mouseover

鼠标移动到元素上时就会触发,经过子盒子还会触发。会冒泡,搭配mouseout

封装简单动画函数

 function simpleflash(obj, target, step, time) {
            var timer = setInterval(function() {
                if (obj.offsetLeft > target) {
                    clearInterval(timer);
                } else {
                    obj.style.left = obj.offsetLeft + step + 'px';
                }
            }, time);
        }
        simpleflash(flash, 400, 10, 50);

动画实现原理

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

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

动画函数给不同元素记录不同定时器

核心原理: 利用JS是一门动态语言,可以方便地给当前对象添加属性

 function simpleflash(obj, target, step, time) {
 //若定时器是由其他事件进行触发,触发一次,就会开启一个定时器,不断触发,定时器会越来越多,元素移动速度会越来越快
 //先清除以前的定时器,再保留当前定时器
           clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                if (obj.offsetLeft > target) {
                    clearInterval(obj.timer);
                } else {
                    obj.style.left = obj.offsetLeft + step + 'px';
                }
            }, time);
        }
        simpleflash(obj1, 400, 10, 50);
        simpleflash(obj2, 400, 10, 50);

缓动效果

缓动效果原理: 让元素运动速度有所变化,常见的就是减速运动
思路:

  1. 让盒子每次移动距离慢慢变小
  2. 核心算法:(目标值-当前位置)/步长

动画函数多个目标值之间移动

  1. 移动步长为正值,上取整
  2. 移动步长为负值,下取整
function simpleflash(obj, target, step, time) {
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                    var adv = (target - obj.offsetLeft) / step; //减速
                    adv = adv > 0 ? Math.ceil(adv) : Math.floor(adv); //前进上取整,后退下取整
                    if (obj.offsetLeft == target) {
                        clearInterval(obj.timer);
                    } else {
                        // obj.style.left = obj.offsetLeft + step + 'px';//匀速
                        obj.style.left = obj.offsetLeft + adv + 'px';
                    }
                },
                time);
        }
        var btnShort = document.querySelector('#btnShort');
        var btnLong = document.querySelector('#btnLong');
        btnShort.addEventListener('click', function() {
            simpleflash(flash, 500, 10, 50);
        })
        btnLong.addEventListener('click', function() {
            simpleflash(flash, 1000, 10, 50);
        })

动画函数添加回调函数

回调函数原理: 函数作为一个参数传到另一个函数里,当该函数执行完后,再执行传进去的函数,整个过程叫做回调。

function simpleflash(obj, target, step, time, callback) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
            var adv = (target - obj.offsetLeft) / step; //减速
            adv = adv > 0 ? Math.ceil(adv) : Math.floor(adv); //前进上取整,后退下取整
            if (obj.offsetLeft == target) {
                clearInterval(obj.timer);
                if (callback) {
                    callback();
                }
            } else {
                // obj.style.left = obj.offsetLeft + step + 'px';//匀速
                obj.style.left = obj.offsetLeft + adv + 'px';
            }
        },
        time);
}

常见的网页特效

网页轮播图

轮播图,也称为焦点图
功能需求:

  1. 鼠标经过轮播图模块,显示左右按钮,离开隐藏左右按钮
  2. 点击右侧按钮,图片往左播放一张,点击左侧按钮,图片往右播放一张
  3. 图片滚动同时,下侧索引模块跟随变化
  4. 点击下侧索引模块,播放相应图片
  5. 鼠标不经过轮播图,轮播图自动播放

节流阀

目的: 当上一个函数动画内容执行完毕,再执行下一个函数动画,让事件无法连续触发。防止轮播图按钮连续点击造成播放过快。(I see:有时候连续点击,就是想加快速度啊)
核心实现思路: 利用回调函数,添加变量控制,对动画函数进行封锁和解锁。

 //轮播图
    var focus = document.querySelector('.focus');
    var left = document.querySelector('.arrow-l');
    var right = document.querySelector('.arrow-r');
    var target = focus.offsetWidth;
    focus.addEventListener('mouseenter', function() {
        left.style.display = 'block';
        right.style.display = 'block';
        clearInterval(timer);
        timer = null;
    });
    focus.addEventListener('mouseleave', function() {
        left.style.display = 'none';
        right.style.display = 'none';
        timer = setInterval(function() {
            right.click();
        }, 3000);
    });

    //动态生成小圆圈
    var ul = focus.querySelector('ul');
    var ol = focus.querySelector('.circle');
    for (var i = 0; i < ul.children.length; i++) {
        var li = document.createElement('li');
        //记录小圆圈的索引号
        li.setAttribute('index', i);
        ol.appendChild(li);
        li.addEventListener('click', function() {
            for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            this.className = 'current';
            //点击小圆圈,移动图片
            var index = this.getAttribute('index');
            num = index;
            circle = index;
            simpleflash(ul, -index * target, 10, 5)
        })
    }
    ol.children[0].className = 'current';
    //克隆第一张图片
    var first = ul.children[0].cloneNode(true);
    ul.appendChild(first);
    //点击按钮,滚动
    var num = 0;
    var circle = 0;
    //定义变量,控制动画函数
    var flag = true;
    right.addEventListener('click', function() {
        if (flag) {
            flag = false;
            if (num == ol.children.length) {
                ul.style.left = 0 + 'px';
                num = 0;
            }
            num++;
            simpleflash(ul, -num * target, 10, 5, function() {
                flag = true; //动画函数执行完毕,再恢复控制变量
            });
            circle++;
            if (circle == ol.children.length) {
                circle = 0;
            }
            circleChange();
        }
    });
    left.addEventListener('click', function() {
        if (flag) {
            flag = false;
            if (num == 0) {
                num = ul.children.length - 1;
                ul.style.left = -num * target + 'px';

            }
            num--;
            simpleflash(ul, -num * target, 10, 5, function() {
                flag = true;
            });
            circle--;
            if (circle < 0) {
                circle = ol.children.length - 1;
            }
            circleChange();
        }

    });

    function circleChange() {
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        ol.children[circle].className = 'current';
    }
    //自动播放
    var timer = setInterval(function() {
        right.click();
    }, 5000);

返回顶部

document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;

window.scroll(0,0);

3.添加动画函数

 //返回顶部
    goBack.addEventListener('click', function() {
        //1. 
        // document.body.scrollTop = 0;
        // document.documentElement.scrollTop = 0;
        //2.
        // window.scroll(0, 0);
        //3.
        goTop(window, 0, 10, 15);
    });

    function goTop(obj, target, step, time, callback) {
        clearInterval(obj.timer);
        obj.timer = setInterval(function() {
                var adv = (target - window.pageYOffset) / step; //减速
                adv = adv > 0 ? Math.ceil(adv) : Math.floor(adv); //前进上取整,后退下取整
                if (window.pageYOffset == target) {
                    clearInterval(obj.timer);
                    callback && callback();
                }
                window.scroll(0, window.pageYOffset + adv);
            },
            time);
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值