js盒子模型
提供一些属性和方法用来描述当前盒子的样式的
client
clientWidth/clientHight
当前盒子可视区域的宽度和高度
可视区域:内容的宽高+padding
clientWidth=width+padding(left/right)
clientHight=height+padding(top/bottom)
和内容是否已出以及我们是否设置了overflow:hidden;没有关系
clientTop
和clientLeft
clientTop:盒子上边框的高度。
clientLeft:盒子左边框的宽度。
获取的结果就是border-width的值
通过js盒子模型属性获取的结果是不带单位的,而且只能是整数(他会自动四舍五入)
[图片上传失败...(image-44f587-1570785313950)]
获取当前页面一屏幕的宽度
document.documentElement.clientWidth||document.body.clientWidth
获取当前页面一屏幕的高度
document.documentElement.clientHeight||document.body.clientHeight
面试题:让一个盒子水平垂直居中?不知道盒子宽度和高度如何处理?
css
:
知道盒子宽高时
[图片上传失败...(image-63d655-1570785313950)]
不知道盒子宽高时(不兼容ie低版本浏览器)
[图片上传失败...(image-57feda-1570785313950)]
使用css3的flex伸缩盒模型(不兼容)
[图片上传失败...(image-545a5c-1570785313950)]
js
:获取当前盒子具体的left/top值
[图片上传失败...(image-e4c527-1570785313950)]
offset
offsetWidth
和offsetHeight
在clientWidth和clientHeight的基础上加上
盒子的边框
即可
offsetWidth=width+padding(左右)+border(左右)=clientHeight+border(左右)
在真实项目中想获取一个盒子的宽度和高度,我们一般用offsetWidth而不是clientwidth,border也是盒子的一部分
offsetParent
:参照物
offsetLeft
:左偏移()
offsetTop
:上偏移
offset系列(与溢出的内容无关)
偏移:
1.当前元素(边框以外)到参照物(边框以内)的距离
2.获取偏移量,当前元素不一定要设成定位元素。
3.当前元素找参照物的方式跟css里找参照物一样
4.默认的参照物是body,但实际上到窗口左边和上边的距离,body是文档的代理人,对body不要设置margin,float等属性
5.其他元素margin,float也会造成影响
scroll
scrollWidth
和scrollHeight
没有内容溢出的情况:获取的结果和clientWidth和clientHeight是一样的
有内容溢出的情况:真实内容的宽度或者高度(包含溢出的内容),加上左padding或者上padding。获取的结果是一个约等于值,每个浏览器由于对行高或者文字的渲染不一样,结果也是不一样的,是否设置了overflow对最后获取的结果也有影响
[图片上传失败...(image-cbc9b0-1570785313950)]
scrollLeft
:横向滚动条卷出去的宽度
scrollTop
:纵向滚动条卷出去的高度。
最大宽、高 等于= 整个文档(scrollwidth/height)宽、高,减去一屏的(clientwidth/height)宽、高
scrollTop=scrollheight-clientheight
scrollLeft
、scrollTop
是13个js盒子模型相关属性里唯一两个可以赋值的属性
,其他的11个属性只能获取不能赋值,
通过js盒模型属性获取值的特点
- 1.若赋值是浮点数取得是整数部分,不会四舍五入
- 2.13个js盒子模型获取的值都不带单位
- 3.获取的结果都是复合样式值(好几个元素的样式组合在一起的值),如果只想获取单一样式值(例如只想获取padding)我们的盒子模型属性就操作不了了(这不能说没有用,真实项目中有时候我们就是需要获取组合的值来完成一些操作)
在js中获取元素具体的样式值
通过js盒子模型属性获取的结果都是盒子的组合样式值,不能直接获取某一个具体样式值,例如就想获得左padding
curEle.style.xxx
获取当前元素所有写在行内
样式上的样式值
特殊:只有把样式写在行内样式上,才可以通过这种办法获取到(写在其他地方的样式获取不到)所以这种办法在真实项目中使用非常少。
window.getComputedStyle
/currentStyle
只要当前元素在页面中显示出来我们就可以获取样式值,也就是获取所有经过浏览器计算过的样式
window.getComputedStyle:适用于标准浏览器,低版本IE浏览器不兼容,所以用curEle.currentStyle来获取需要的样式值。
[图片上传失败...(image-2ef0a6-1570785313950)]
[图片上传失败...(image-7fc29d-1570785313950)]
[图片上传失败...(image-a88a73-1570785313950)]
[图片上传失败...(image-daf800-1570785313950)]
[图片上传失败...(image-795616-1570785313950)]
[图片上传失败...(image-7a3dad-1570785313950)]
[图片上传失败...(image-5bba7a-1570785313950)]
设置元素样式属性
加单位(符合加单位)
[图片上传失败...(image-f40e17-1570785313950)]
[图片上传失败...(image-7f8b17-1570785313950)]
[图片上传失败...(image-4f8bef-1570785313950)]
加单位(排除不需要加单位的)
[图片上传失败...(image-2ab4d4-1570785313950)]
批量给当前元素设置css样式
[图片上传失败...(image-9180c7-1570785313950)]
必须和setCss一起使用。
封装css属性
var css = function () {
var len = arguments.length;
fn = getCss;
len > 3 ? fn = setCss : (len === 2 && Object.prototype.toString.call(arguments[1]) === '[object Object]' ? fn = setGroupCss : null);
return fn.apply(this.arguments);}
考虑兼容性方法
考虑兼容性方法:
try{}catch(e){};
判断属性的方式"getComeputedStyle"in window,window.getComeputedStyle
检测数据类型,instanceOf,
Object.prototype.tostring.call
检测浏览器的方式
/MSIE[6-8]\.0/.test(navigator.userAgent)
拖拽
原理
[图片上传失败...(image-d94834-1570785313950)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="../../reset.min.css">
<style type="text/css">
html, body {
height: 500%;
-webkit-user-select :none;
}
.dialogMark {
position: fixed;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .3);
}
.diaLogBox {
/*控制盒子在中间我们最好在js中实现,经过精密的计算,计算出具体的top和left而不是模糊的百分比这样我们在js中通过*/
width: 200px;
position: fixed;
height: 300px;
background: #FFF;
z-index: 101;
overflow: hidden;
}
.diaLogBox h3 {
position: relative;
padding: 0 10px;
height: 50px;
line-height: 50px;
background: #DDD;
border-bottom: 1px solid #aaaaaa;
cursor: move;
}
.diaLogBox h3 i {
position: absolute;
right: 10px;
top: 50%;
margin-top: -10px;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
font-size: 16px;
color: #E01D20;
font-style: normal;
font-family: "Microsoft JhengHei";
background: lightgoldenrodyellow;
}
</style>
</head>
<body>
<!--dialog:模态框-->
<div class="dialogMark"></div>
<div class="diaLogBox" id="diaLogBox">
<h3 class="title">大力出奇迹
<i class="closeBtn">X</i>
</h3>
<div class="con">
</div>
</div>
<script>
let dialogRender = (function () {
let diaLogBox = document.getElementById('diaLogBox');
let title = diaLogBox.getElementsByTagName('h3')[0];
let closeBtn=diaLogBox.getElementsByTagName('i')[0];
let winW = document.documentElement.clientWidth || document.body.clientWidth;
let winH = document.documentElement.clientHeight || document.body.clientHeight;
let maxL = winW - diaLogBox.offsetWidth;
let maxT = winH - diaLogBox.offsetHeight;
let Down = function (ev) {
console.log(1);
ev = ev || window.event;
//记录鼠标起始位置&&盒子的起始位置
this.strX = ev.clientX;
this.strY = ev.clientY;
this.strL = diaLogBox.offsetLeft;
this.strT = diaLogBox.offsetTop;
//谷歌下不兼容,用setCapture,releaseCapture解决鼠标焦点丢失问题
if(this.setCapture){
this.onmousemove=Move;
this.onmouseup=Up;
this.setCapture();
return;
}
//按下代表拖拽开始,会有鼠标丢失的问题,
// this.onmousemove=Move;
// this.onmouseup=Up;
//解决方法:
//用document解决鼠标焦点丢失问题
//let _this = this;
document.onmousemove = (ev) => {
Move.call(this,ev);
};
document.onmouseup = (ev) => {
Up.call(this,ev);
}
};
let Move = function (ev) {
// console.log(this);
ev = ev || window.event;
let curL = ev.clientX - this.strX + this.strL;
let curT = ev.clientY - this.strY + this.strT;
console.log(curT, ev.clientY, this.strY, this.strT);
//边界处理
curL = curL < 0 ? 0 : (curL > maxL ? maxL : curL);
curT = curT < 0 ? 0 : (curT > maxT ? maxT : curT);
console.log(curT);
diaLogBox.style.left = curL + 'px';
diaLogBox.style.top = curT + 'px';
console.log(diaLogBox.style.top);
};
let Up = function (ev) {
//谷歌下不兼容,用setCapture,releaseCapture解决鼠标焦点丢失问题
if(this.setCapture){
this.onmousemove=null;
this.onmouseup=null;
this.releaseCapture();
return;
}
//用document解决鼠标焦点丢失问题
document.onmousemove = null;
document.onmouseup = null;
};
closeBtn.onclick=function () {
diaLogBox.style.display='none';
};
return {
init: function () {
//让盒子处于页面中间
diaLogBox.style.left = maxL / 2 + 'px';
diaLogBox.style.top = maxT / 2 + 'px';
title.onmousedown = Down;
}
}
})();
dialogRender.init();
</script>
</body>
</html>
弹性盒子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="../../reset.min.css">
<style type="text/css">
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
#box {
position: absolute;
width: 200px;
height: 200px;
top: 100px;
left: 100px;
background: red;
cursor: move;
}
</style>
</head>
<body>
<div id="box">
</div>
<script src="发布订阅subscribe.js"></script>
<script>
let box = document.querySelector('#box');
let subscribeDown = new Subscribe();
let subscribeMove = new Subscribe();
let subscribeUp = new Subscribe();
let down = function (ev) {
this.strX = ev.clientX;
this.strY = ev.clientY;
this.strT = this.offsetTop;
this.strL = this.offsetLeft;
//解决鼠标焦点丢失
this.MOVE = move.bind(this);
this.UP = up.bind(this);
document.addEventListener('mousemove', this.MOVE);
document.addEventListener('mouseup', this.UP);
subscribeDown.fire(this, ev);
};
let move = function (ev) {
this.curL = ev.clientX - this.strX + this.strL;
this.curT = ev.clientY - this.strY + this.strT;
this.style.left = this.curL + 'px';
this.style.top = this.curT + 'px';
subscribeMove.fire(this, ev)
};
let up = function (ev) {
//抬起清除事件
document.removeEventListener('mousemove', this.MOVE);
document.removeEventListener('mouseup', this.UP);
subscribeUp.fire(this, ev);
};
box.onmousedown = down;
subscribeMove.add((curEle, ev) => {
if (!curEle.lastFly) {
curEle.lastFly = curEle.offsetLeft;
curEle.speedFly = 0;
return;
}
curEle.speedFly = curEle.offsetLeft - curEle.lastFly;
curEle.lastFly = curEle.offsetLeft;
});
subscribeUp.add((curEle, ev) => {
let minL = 0;
let maxL = document.documentElement.clientWidth - curEle.offsetWidth;
let speed = curEle.speedFly;
let dir = 'right';
speed < 0 ? dir = 'left' : null;
speed = Math.abs(speed);
curEle.flyTimer = setInterval(() => {
if (speed < 0.5) {
clearInterval(curEle.flyTimer);
return;
}
speed *= 0.98;
let curL = curEle.offsetLeft;
if (dir === 'right') {
if (curL >= maxL) {
curEle.style.left = maxL + 'px';
dir = 'left';
return;
}
curL += speed;
} else {
if (curL <= minL) {
curEle.style.left = minL + 'px';
dir = 'right';
return;
}
curL -= speed;
}
curEle.style.left = curL + 'px';
}, 17);
});
subscribeDown.add((curEle, ev) => {
clearInterval(curEle.flyTimer);
curEle.speedFly = 0;
clearInterval(curEle.dropTimer);
});
subscribeUp.add((curEle, ev) => {
let speed = 9.8;
let minT = 0;
let maxT = document.documentElement.clientHeight - curEle.offsetHeight;
flag = 0;
curEle.dropTimer = setInterval(() => {
if (flag > 1) {
clearInterval(curEle.dropTimer);
return;
}
speed += 9.8;
speed *= 0.98;
let curT = curEle.offsetTop;
curT += speed;
if (curT >= maxT) {
curEle.style.top = maxT + 'px';
speed *= -1;
flag++;return;
}
if (curT <= minT) {
curEle.style.top = minT + 'px';
speed *= -1;
return;
}
curEle.style.top = curT + 'px';
flag = 0;
}, 17);
});
</script>
</body>
</html>
网友评论