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>
<bodyPC 端网页特效-offset 系列及学习案例
PC 端网页特效-offset 系列及学习案例
学习地址还是在这里:JavaScript 基础语法-dom-bom-js-es6 新语法-jQuery-数据可视化 echarts 黑马 pink 老师前端入门基础视频教程(500 多集)持续
总归说学完一个是一个,不能继续下次一定了
offset 即 元素偏移量,PC 端的网页特效是一个系列:
- offset
- client
- scroll
- 动画函数封装
不过因为每周学习的进度关系,所以会将 PC 端网页特效做一个系列的笔记。
其学习案例有 3 个:
- 基础的 offset 应用案例,即获得鼠标在盒子中的坐标
- 拖曳窗口
- 仿京东放大镜
offset 概述
offset 即偏移量,使用 offset 系列相关属性可以 动态的 获取该元素的位置(偏移)、大小等,如:
- 元素距离带有定位父元素的位置
- 获取元素自身的大小(宽度高度)
注:返回的数值不带单位
offset 系列常用的属性包括:
-
element.offsetParent
返回作为该元素带有定位的父级元素,如果父级元素没有定位,则返回 body
注意,parentNode
和 offsetParent
还是有本质上的区别的:parentNode
返回的是直接父级元素,offsetParent
返回的是带有定位的父级元素。
-
element.offsetTop
返回元素带有定位父元素上方的偏移
-
element.offsetLeft
返回元素带有定位父元素左边框的偏移
-
element.offsetWidth
返回自身包括 padding
, 边框, 内容区的宽度,返回数值不带单位
-
element.offsetHeight
返回自身包括 padding
, 边框, 内容区的高度,返回数值不带单位
offset 和 style 的区别
offset style offset 可以得到任意样式表中的样式值 style 只能得到行内样式表中的样式值,无法获得内嵌样式 offset 系列获得的数值是没有单位的 style.width
获得的是带有单位的字符串offsetWidth 包含 padding+border+width style.width
获得不包含 padding 和 border 的值offsetWidth 等属性是只读属性,只能获取不能赋值 style 属性是可读写属性,style.width
可以获取也可以赋值 只想要获取元素大小位置的时候,用 offset 更合适 要对元素样式进行修改的话,使用 style 更合适
offset 学习案例
即获得鼠标在盒子中的坐标
效果图:
<!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 的东西,不过效果图上没有展示出来。
效果图:
实现是部分完整的——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 先做案例吧。代码都是一样的,不知道为什么在自己电脑上好抖……晚点继续研究一下。另外就是代码注释还是不够,这也是个毛病。
实现代码:
<!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 端网页特效的主要内容,如果未能解决你的问题,请参考以下文章