1. 获取样式
1.1 JS获取style中的样式
DOM对象 是不可以直接获取内部样式的中属性的
只能获取行内样式的属性
1.2 client系列 (只读)
clientWidth
拿的是盒子 内容 + padding的宽clientHeight
拿的是盒子 内容 + padding的高clientLeft
拿的是盒子左边框大小clientTop
拿的是盒子上边框大小
1.3 offset系列 (只读)
offsetWidth
- 拿的是盒子 内容 + padding + border的宽
offsetHeight
- 拿的是盒子 内容 + padding + border的高
offsetLeft
- 拿的是元素的偏移量:可以认为就是拿的绝对定位left值
- 切记如果进行
offsetLeft
的值进行加法运算不允许添加px
offsetTop
- 拿的是元素的偏移量:可以认为就是拿的绝对定位top值
- 在没有边框的时候
那么clientWidth/offsetWidth
和clientHeight/offsetHeight
是一样的结果
1.4 Scroll系列
- scrollWidth 只读
- 当内容比盒子小的时候,拿的是盒子的clientWidth
- 当内容比盒子大的时候,拿的是内容的offsetWidth + 盒子的一侧内边距
document.documentElement.scrollWidth
- scrollHeight 只读
- 当内容比盒子小的时候,拿的是盒子的clientHeight
- 当内容比盒子大的时候,拿的是内容的offsetHeight + 盒子的一侧内边距
document.documentElement.scrollHeight
- scrollTop可读可写
- 拿的是盒子内容向上滚动的距离
document.documentElement.scrollTop
- scrollLeft可读可写
- 拿的是盒子内容向左滚动的距离
document.documentElement.scrollLeft
1.5 总结
- 元素的大小:宽和高的获取:以后我们拿元素的宽和高,先看元素有没有边框,如果没有边框,那么clientWidth和offsetWidth是一样的,如果有边框,看你需要不,需要的话就用offsetWidth,不需要就用clientWidth; scrollWidth几乎不用
- 元素的位置(偏移量)的获取:以后需要获取元素的位置直接通过
offsetLeft
和offsetTop
去获取,但是注意相对的参照元素是谁;(和绝对定位参照类似)- 视口宽高求法(固定的)
document.documentElement.clientWidth
document.documentElement.clientHeight
-
案例练习---滚动页面导航栏固定
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>案例练习-导航栏跟随</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100%;
height: 150px;
background-color: #e6e1e2;
text-align: center;
line-height: 150px;
}
div input {
width: 735px;
height: 40px;
border-radius: 20px;
border: 2px solid #f40;
outline: none;
}
</style>
</head>
<body style="height: 3000px;">
<div>
<input type="text">
</div>
<script>
// 滚动一个视口的高度 然后就将input固定在头部
// 如果不到一个视口的高度 就默认了
var inp = document.querySelector('input')
document.onscroll = function() {
// 获取的是html滚动的距离
var scrollHeight = document.documentElement.scrollTop;
// 获取的视口
var htmlDis = document.documentElement.clientHeight;
if (scrollHeight >= htmlDis) {
inp.style.position = 'fixed'
inp.style.top = 0
inp.style.left = 0
inp.style.right = 0
inp.style.margin = 'auto'
} else {
inp.style.position = 'static'
}
}
</script>
</body>
</html>
-
案例练习-盒子来回移动
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>案例练习-盒子来回移动</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
position: absolute;
width: 100px;
height: 100px;
background-color: aquamarine;
}
</style>
</head>
<body>
<div></div>
<script>
var div = document.querySelector('div');
var step = 3;
setInterval(function(){
var startX = div.offsetLeft;
var endX = startX + step;
// 边界右:
if(endX >= document.documentElement.clientWidth - div.offsetWidth){
endX = document.documentElement.clientWidth - div.clientWidth;
step = -3;
// 左边界:
}else if(endX <= 0){
endX = 0;
step = 3;
}
div.style.left = endX + 'px';
},16);
</script>
</body>
</html>
2. 初始包含块
-
即页面的第一屏
-
初始包含块:和浏览器第一屏大小一致的一个块状结构,称作初始包含块,元素子绝父不相的时候,其实相对的是初始包含块去做的定位,不是body也不是html也不是视口
-
打开浏览器最外层的结构,首先是document,接着是初始包含块 , HTML , body
- html单独设置某些特殊属性作用的位置(
background-color
)- body单独设置某些特殊属性作用的位置(
background-color
)- html, body 比较特殊,特殊原因它的部分属性作用的不是自己 而是document,doucument是网页最外层的元素,html文档当中没有任何标签标示它
- 如果同时设置, 即body生效 html还是作用于document
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
html{
width: 500px;
height: 500px;
margin-left: 100px;
border: 10px solid blue;
/* background-color: red; */ /* 整个网页变成红色而不是宽高500的这个盒子*/
/*html比较特殊,特殊原因它的部分属性作用的不是自己 而是document*/
/*doucument是网页最外层的元素,html文档当中没有任何标签标示它*/
}
body{
width: 300px;
height: 3000px;
border: 10px solid yellow;
background-color: red;/* 整个网页变成红色而不是宽高500的这个盒子*/
/*body比较特殊,单独的给Body设置某些属性,作用的不是自己 而是document*/
/*doucument是网页最外层的元素,html文档当中没有任何标签表示它*/
}
</style>
</head>
<body>
<div id="box"></div>
</body>
</html>
3. 系统滚动条的控制
html和body这两个元素overflow的scroll属性,控制着系统的滚动条,系统的滚动条有两个,一个是body身上的,一个是document身上的。我们平时看到的那个滚动条是document身上的。如果我们想要控制系统滚动条哪个显示哪个关闭分以下情况:
- 单独的给body或者html 设置overflow:scroll 滚动条打开的全部都是document的
- 如果两个元素同时设置overflow属性,body设置的是scroll,html设置是hidden,那么document的滚动条被关闭,body身上的滚动条会打开,相反,body身上被关闭,document身上的被打开
- 如果两个元素同时设置overflow:hidden;那么系统的两个滚动条全部被关闭
- 如果两个都设置overflow:scroll,那么html会打开document身上的,而body会打开自己身上的滚动条
- 通常情况下系统滚动条会被禁用因为浏览器样式不统一
企业级开发的书写方式 :
html,body {
height: 100%;
overflow: hidden;
}
4. 鼠标拖拽基础
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
#box{
position: absolute;
left: 0;
top: 0;
width: 150px;
height: 80px;
background-color: red;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function(){
var box = document.getElementById('box');
box.onmousedown = function(e){
e = e || window.event;
//按下的时候获取元素的初始位置和鼠标的初始位置
var eleX = box.offsetLeft;
var eleY = box.offsetTop;
var startX = e.clientX;
var startY = e.clientY;
box.onmousemove = function(e){
e = e || window.event;
//可以获取鼠标的结束位置
var endX = e.clientX;
var endY = e.clientY;
//求出鼠标的距离差 即 盒子的移动距离
var disX = endX - startX;
var disY = endY - startY;
//求出元素移动的最终位置 = 元素的初始位置 + 鼠标的距离差(盒子的移动距离)
var lastX = eleX + disX;
var lastY = eleY + disY;
//把求出来的最终位置设置给元素
box.style.left = lastX + 'px';
box.style.top = lastY + 'px';
};
box.onmouseup = function(){
box.onmousemove = box.onmouseup = null;
}
}
}
</script>
</body>
</html>
基础拖拽问题:
- 鼠标拖动过快,会跑出元素,元素就不动
因为计算机跟不上你的速度,跑出盒子,盒子不动,因为事件添加在盒子身上,跑出去后事件就不在盒子身上触发了。包括在外部鼠标抬起,也是解绑不了盒子上的事件的,因为鼠标抬起也是在盒子身上添加的;解决:移动事件和抬起事件,最好添加给document
浏览器默认行为:
在盒子当中写上文字,拖拽先选中文字,在拖拽,文字跟着走,盒子不动,放手盒子会瞬间到放手的位置
因为浏览器有默认行为,拖拽文字就是一个默认行为。
解决:取消浏览器的默认行为在低版本浏览器当中在盒子当中写上文字,拖拽先选中文字,在拖拽会出现禁止拖拽的现象
因为低版本浏览器专门有这样的行为,禁止拖拽是低版本浏览器专属,解决:使用全局捕获,把鼠标后续的事件,强制拉回作用在元素身上,以后鼠标就只能作用在元素身上了,全局捕获有捕获就有释放,否则后果自负
取消浏览器默认行为根据事件添加方式不同而不同
- dom0事件,那么在事件回调当中写上return false;
- dom2事件, 在事件回调当中添加e.preventDefault();
上下边界吸附效果
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
position: absolute;
left: 0;
top: 0;
width: 150px;
height: 80px;
background-color: red;
}
</style>
</head>
<body>
<div id="box">张三</div>
<script type="text/javascript">
window.onload = function () {
var box = document.getElementById('box');
box.onmousedown = function (e) {
e = e || window.event;
//按下的时候获取元素的初始位置和鼠标的初始位置
var eleX = box.offsetLeft;
var eleY = box.offsetTop;
var startX = e.clientX;
var startY = e.clientY;
//全局捕获
box.setCapture && box.setCapture(); //只有低版本浏览器才会用到全局捕获
document.onmousemove = function (e) {
e = e || window.event;
//可以获取鼠标的结束位置
var endX = e.clientX;
var endY = e.clientY;
//求出鼠标的距离差
var disX = endX - startX;
var disY = endY - startY;
//求出元素移动的最终位置 = 元素的初始位置 + 鼠标的距离差
var lastX = eleX + disX;
var lastY = eleY + disY;
// 左右边界
// if(lastX >= document.documentElement.clientWidth - div.offsetWidth){
// lastX = document.documentElement.clientWidth - div.clientWidth;
// }else if(lastX <= 0){
// lastX = 0;
// }
// 上下边界
// if(lastY >= document.documentElement.clientHeight - div.clientHeight){
// lastY = document.documentElement.clientHeight - div.offsetHeight;
// }else if(lastY <= 0){
// lastY = 0;
// }
// 左右吸附效果
if(lastX >= document.documentElement.clientWidth - div.offsetWidth - 50){
lastX = document.documentElement.clientWidth - div.clientWidth;
}else if(lastX <= 50){
lastX = 0;
}
// 上下吸附效果
if(lastY >= document.documentElement.clientHeight - div.clientHeight - 50){
lastY = document.documentElement.clientHeight - div.offsetHeight;
}else if(lastY <= 50){
lastY = 0;
}
//把求出来的最终位置设置给元素
box.style.left = lastX + 'px';
box.style.top = lastY + 'px';
};
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null;
box.releaseCapture && box.releaseCapture(); //低版本浏览器释放全局捕获
};
return false;
};
};
</script>
</body>
</html>
-
案例练习---碰撞变化效果
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>21_鼠标拖拽-碰撞效果</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
position: absolute;
width: 100px;
height: 100px;
background-color: aquamarine;
}
img {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div></div>
<img src="./img/1.jpg">
<script>
var div = document.querySelector('div');
var img = document.querySelector('img');
div.onmousedown = function(event){
var eleX = div.offsetLeft;
var eleY = div.offsetTop;
var startX = event.clientX;
var startY = event.clientY;
document.onmousemove = function(event){
var endX = event.clientX;
var endY = event.clientY;
var disX = endX - startX;
var disY = endY - startY;
var lastX = disX + eleX;
var lastY = disY + eleY;
// 左右边界
if(lastX >= document.documentElement.clientWidth - div.offsetWidth){
lastX = document.documentElement.clientWidth - div.clientWidth;
}else if(lastX <= 0){
lastX = 0;
}
// 上下边界
if(lastY >= document.documentElement.clientHeight - div.clientHeight){
lastY = document.documentElement.clientHeight - div.offsetHeight;
}else if(lastY <= 0){
lastY = 0;
}
div.style.left = lastX + 'px';
div.style.top = lastY + 'px';
// 碰撞效果
// 左
var divL = div.offsetLeft + div.offsetWidth;
var imgL = img.offsetLeft;
// 上
var divT = div.offsetTop + div.offsetHeight;
var imgT = img.offsetTop;
// 右
var divR = div.offsetLeft;
var imgR = img.offsetLeft + img.offsetWidth;
// 下
var divB = div.offsetTop;
var imgB = img.offsetTop + img.offsetHeight;
// 不换的
if(divL < imgL || divT < imgT || divR > imgR || divB > imgB){
img.src = './img/1.jpg';
}else {
img.src = './img/2.jpg';
}
}
document.onmouseup = function(){
document.onmouseup = document.onmousemove = null;
}
}
</script>
</body>
</html>