当前位置: 首页 > news >正文

JavaScript:pc端网页特效--元素偏移量offset系列

1.offset概述

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

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

offset系列常用属性:

offset系列属性作用
element.offsetParent返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
element.offsetTop返回元素相对带有定位父元素上方的偏移
element.offsetLeft返回元素相对带有定位父元素左边框的偏移
element.offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight返回自身包括padding、边框、内容区的高度,返回数值不带单位

(1)element.offsetTop和element.offsetLeft

对于一个div盒子

<div class="father"><div class="son"></div>
</div>

先给它设置一个css样式:

.father {width: 200px;height: 200px;background-color: pink;margin: 100px;
}
.son {width: 100px;height: 100px;background-color: goldenrod;margin-left: 45px;
}

然后再定义div,最后可以试着输出一下element.offsetTop和element.offsetLeft:

var father = document.querySelector('.father');
var son = document.querySelector('.son');
console.log(father.offsetTop);
console.log(father.offsetLeft);
console.log(son.offsetLeft);

最后输出的结果输出的是距离body的偏移,因为我们的父级没有定位或者盒子没有父亲,直接输出与body的相对偏移 

 

(2)element.offsetWidth和element.offsetHeight

也可以用element.offsetWidth和element.offsetHeight得到元素的宽度和高度

console.log(son.offsetWidth);
console.log(son.offsetHeight);

注意:这个宽度和高度也包含padding和border 

 (3)element.offsetParent

console.log(son.offsetParent);

如果.farther没有定位,则返回body

如果.farther有定位,则返回.son的父元素.father

 2.offset与style区别

offsetstyle
offset可以得到任何样式表中的样式值style只能得到行内样式表中的样式值
offset系列获得的数值是没有单位的style.width获得的是带有单位的字符串
offsetWidth包含padding+border+widthstyle.width活动不包含padding和border的值
offsetWidth等属性自身只读属性,只能获取不能赋值style.width是可读写属性,可以获取也可以赋值
如果想获取元素大小位置,用offset更合适如果想给元素更改值,需要用style改变

案例:获取鼠标在盒子里的坐标

我们首先设置好盒子以及盒子的样式

<div class="box"></div>
.box {width: 200px;height: 200px;background-color: pink;margin: 100px;
}

 然后我们来写直接获取鼠标在盒子里的坐标的JS

按理说我们不能直接得到鼠标在盒子里的坐标,但是我们可以得到鼠标相对页面的坐标,也能得到盒子边缘距离页面的坐标,然后再把它俩相减就可以得到啦,代码实现如下:

var box = document.querySelector('.box');
box.addEventListener('mousemove', function (e) {var x = e.pageX - box.offsetLeft;var y = e.pageY - box.offsetTop;this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
})

我们来做案例来更深入地体验一下它们之间的差异性吧~ 

案例:模态框拖拽

我们想做一个这样的登录界面

点击“登录会员”后就出现遮罩层,我们可以任意拖动这个遮罩层移动

我们先来搭建基本框架

<div class="login-header"><a href="javascript:;" id="link">点击登录会员</a></div>
<div class="login" id="login"><div class="login-title" id="title"><p>登录会员</p><span><a href="javascript:;" id="closeBtn" class="close-login">关闭</a></span></div><div class="login-input-content"><div class="login-input"><label for="username">用户名:</label><input type="text" placeholder="请输入用户名" id="username" name="info[username]" class="login-username"></div><div class="login-input"><label for="password">密码:</label><input type="password" placeholder="请输入密码" id="password" name="info[password]" class="login-password"></div></div><div class="login-button" id="loginBtn"><a href="javascript:void(0);" id="login-button-submit">登录</a></div>
</div><!-- 遮盖层 -->
<div class="login-bg" id="bg"></div>

 然后再用css给它装饰一下

 * {padding: 0;margin: 0;
}a {color: #000;text-decoration: none;display: inline-block;
}.login-header {position: fixed;top: 20px;left: 50%;font-size: 18px;transform: translateX(-50%);
}.login {display: none;width: 520px;height: 270px;position: fixed;border: #ebebeb solid 1px;left: 50%;top: 50%;background: #fff;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: 109px;font-size: 18px;position: relative;border: none;
}.login-title span {position: absolute;right: -11px;top: -30px;font-size: 12px;background: #fff;border: #ebebeb solid 1px;width: 30px;height: 30px;border-radius: 50%;text-align: center;
}.login-title span a {position: absolute;left: 0px;line-height: 30px;height: 30px;width: 30px;
}.login-title p {position: relative;top: 13px;left: 0;
}.login-input-content {margin-top: -20px;margin-left: 40px;
}.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;font-size: 14px;
}.login-input input {height: 30px;width: 281px;border: 1px solid #ebebeb;padding: 0 5px;
}.login-input input.list-input {float: left;line-height: 35px;height: 35px;width: 35px;border: #ebebeb 1px solid;
}.login-button {width: 75px;margin: 22px auto 0px auto;line-height: 40px;font-size: 14px;border: 1px solid #ebebeb;border-radius: 21px;text-align: center;
}.login-button a {display: block;
}.login-bg {display: none;width: 100%;height: 100%;position: fixed;top: 0;left: 0;background: rgba(0, 0, 0, .3);
}

接下来就是我们重点看怎么用JS来实现功能啦

我们先来将我们一会要用的名称定义好

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');

先加上点击“点击登录会员”显示遮罩层和点击“关闭”来隐藏遮罩层

link.addEventListener('click', function () {mask.style.display = 'block';login.style.display = 'block';
})
closeBtn.addEventListener('click', function () {mask.style.display = 'none';login.style.display = 'none';
})

接下来就是实现拖动遮罩层啦

先定义isDraggin,用来判断是否在移动遮罩层,定义offsetX,和offsetY来记录鼠标点击位置与登录框左上角的偏移量

var isDragging = false;
var offsetX, offsetY;

给title绑定一个监听器,鼠标按下后就来显示鼠标点击位置与登录框左上角的偏移量,在这里面要记得把isDraggin设置成true,表明正处于移动中

title.addEventListener('mousedown', function (e) {isDragging = true;offsetX = e.pageX - login.offsetLeft;offsetY = e.pageY - login.offsetTop;
});

然后要让登录框跟着鼠标移动,并且是在整个页面里移动,所以给document设置mousemove类型的监听器,实时更新登录框在页面的位置,从而达到拖动登录框的目的

document.addEventListener('mousemove', function (e) {if (isDragging) {login.style.left = (e.pageX - offsetX) + 'px';login.style.top = (e.pageY - offsetY) + 'px';}
});

最后不要忘记解除移动状态,不然登录框就bia在鼠标上,一直跟着鼠标走啦,设置mouseup类型的监听器,将isDraggin设置成false,这样登录框就不会再跟着鼠标走啦

document.addEventListener('mouseup', function () {isDragging = false;
});

 

 

http://www.xdnf.cn/news/261685.html

相关文章:

  • flask 获取各种请求数据:GET form-data x-www-form-urlencoded JSON headers 上传文件
  • 每天学一个 Linux 命令(35):dos2unix
  • SMT贴片检验标准核心要点与实施规范
  • MySQL进阶(三)
  • 欺骗单页应用(SPA)渲染隐藏路由 -- trouble at the spa b01lersCTF
  • Ubuntu 24.04 完整Docker安装指南:从零配置到实战命令大全
  • NuttX 与 PX4 系统开发全流程详解
  • 《AI大模型应知应会100篇》第46篇:大模型推理优化技术:量化、剪枝与蒸馏
  • 基于 SAFM 超分辨率上采样模块的 YOLOv12 改进方法—模糊场景目标检测精度提升研究
  • 一、大模型原理:第一步分词Tokenization
  • MySQL数据操作全攻略:DML增删改与DQL高级查询实战指南
  • hadoop存储数据文件原理
  • 微服务设计约束
  • 介绍 PHP-FPM 和 Python WSGI
  • 【Bootstrap V4系列】学习入门教程之 组件-按钮(Buttons)
  • 宝塔docker拉取仓库失败
  • Nginx发布Vue(ElementPlus),与.NETCore对接(腾讯云)
  • list的迭代器详讲
  • Linux之基础开发工具(yum,vim,gcc,g++)
  • 基于 Dify + vLLM插件 + Qwen3 构建问答机器人Docker版
  • 【计算机视觉】三维重建: OpenMVS:工业级多视图立体视觉重建框架
  • ActiveMQ 集群搭建与高可用方案设计(二)
  • 生成对抗网络(GAN, Generative Adversarial Network)​
  • More Effective C++学习笔记
  • ShaderToy学习笔记 08.阴影
  • 力扣:24两两交换链表的节点
  • 搭建一个 gRPC 服务端和客户端
  • 【Java学习】关于springBoot的自动配置和起步依赖
  • CSS 预处理器 Sass
  • 【2025软考高级架构师】——案例分析总结(13)