盒子模型和盒子偏移量
js中的盒子模型
clientHeight
高度+上下填充
clientWidth
宽度+左右填充
clientLeft
左边框宽度
clientTop
上边框宽度
offsetWidth
宽度+左右填充+左右边框 ==>clientWidth
+左右边框
offsetHeight
高度+上下填充+上下边框 ==>clientHeight
+上下边框
offsetLeft
当前元素距离父元素左偏移量
offsetTop
当前元素的外边框距离父级元素的内边框的上偏移量
offsetParent
scrollWidth
区别于clientWidth
内容+左填充,如果没有发生溢出就是和clientWidth
相等的
scrollHeight
区别于clientHeight
内容+上填充
scrollTop
scrollLeft
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{ margin: 0; padding: 0;}
#div1{
width: 200px;
height: 200px;
margin: 40px auto;
border: 10px solid green;
padding: 20px;
overflow: auto;
opacity: .4;
filter: alpha(opacity=40);
/*
*/
/* box-sizing: border-box; 加上的padding要在宽度上减去 */
}
</style>
<!--<link rel="stylesheet" href=""/>-->
</head>
<body>
<div id="div2" style="position: relative">
<div style="position: absolute; width: 200px; " id="div1" class="div div1">习近平在网信工作座谈会上讲话 专题 漫评 这三年张德江主持会议 俞正声会见代表 刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效习近平在网信工作座谈会上讲话 专题 漫评 这三年张德江主持会议 俞正声会见代表 刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效习近平在网信工作座谈会上讲话 专题 漫评 这三年张德江主持会议 俞正声会见代表 刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效习近平在网信工作座谈会上讲话 专题 漫评 这三年张德江主持会议 俞正声会见代表 刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效习近平在网信工作座谈会上讲话 专题 漫评 这三年张德江主持会议 俞正声会见代表 刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效习近平在网信工作座谈会上讲话 专题 漫评 这三年张德江主持会议 俞正声会见代表 刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效刘云山陕西调研2016年一季度全国网信系统行政执法工作取得新成效</div>
</div>
<!--<video src=""></video>-->
<!--<audio src=""></audio>-->
<select name="" id="df">
<option value=""></option>
<option value=""></option>
<option value=""></option>
</select>
</body>
</html>
<script>
var oDiv = document.getElementById('div1');
//console.dir(oDiv);
//console.log(oDiv.clientHeight);
//console.log(oDiv.scrollHeight);
//console.log(oDiv.scrollTop);
//console.log(oDiv.scrollLeft);
/*
* 获取可视窗口:document.documentElement.clientHeight || document.body.clientHeight
* 是不是可以加到我们的untils
*
* */
/*
* 通过元素的style属性只能获取行内样式,但是我们一般不把样式写在行内
* 获取元素的浏览器计算后的样式
* */
function getCss(curEle){ //返回了那个样式对象
if(window.getComputedStyle){ //如果在window下存在一个getComputedStyle的属性,那么我就认为支持这个方法
return window.getComputedStyle(curEle,null); //null参数是伪类
}else{ //ie低版本
return curEle.currentStyle;
}
}
//我想获取到具体的某一个属性
function getCss(curEle,attr){
if(/MSIE (?:6|7|8)/.test(window.navigator.userAgent)){
return curEle.currentStyle[attr];
}
return window.getComputedStyle(curEle,null)[attr];
}
//需要规避复合值的问题 margin padding
//把带获取到带单位的把单位去掉 px em pt rem deg
function getCss(curEle,attr){
//处理带单位的问题
var reg = /^(-?\d+\.?\d+)(?:px|em|pt|deg|rem)$/;
var val = null;
if(/MSIE (?:6|7|8)/.test(window.navigator.userAgent)){
debugger
//这里处理filter的滤镜问题 alpha(opacity=40);
if(attr === 'opacity'){
//alpha(opacity=40)
val = curEle.currentStyle['filter'];
var reg1 = /^alpha\(opacity=(\d+(\.\d+)?)\)/;
return reg1.test(val) ? RegExp.$1/100 : 1;
}else{
val = curEle.currentStyle[attr];
}
}else{
val = window.getComputedStyle(curEle,null)[attr];
}
return reg.test(val)? parseFloat(val) :val ; //如果正则验证通过,寿命返回值是带单位的,那么我们就要人为去掉这个单位。否则不变
}
getCss(oDiv,'opacity');
</script>
获取伪类
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>伪类</title>
<style>
*{
margin: 0; padding: 0; font-size: 14px; font-family: 'Microsoft Yahei';
}
.box{
width: 300px;
margin: 40px auto;
padding: 10px;
border: 2px solid #ccc;
background: lightyellow;
}
.box p{
line-height: 30px;
text-align: center;
}
.box p:before{ /*相当于在p的前面放一个你看不到的元素*/
display: block;
line-height: 30px;
content: '我是放在p前面的';
color: #999999;
}
.box p:after{
display: block;
line-height: 30px;
content: '我是放在p后面的';
color: #999999;
}
.box ul{
list-style: none;
}
.box ul li{
width: 100px;
height: 100px;
background: yellow;
/*display: inline-block;*/
float: left;
font-size: 30px;
line-height: 100px;
text-align: center;
}
.box ul li:nth-child(3n+1){
background: palevioletred;
}
.box ul li:nth-child(odd){ /*奇数*/
}
.box ul li:nth-child(even){ /*偶数*/
}
.clearFix{
zoom: 1;
}
.clearFix:after{
content: "";
display: block;
width: 0;
height: 0;
overflow: hidden;
clear: both;
}
</style>
</head>
<body>
<div id="div1" class="box">
<p>下雨了多穿衣服吧</p>
</div>
<div class="box">
<ul class="clearFix">
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li>
</ul>
</div>
</body>
</html>
<script>
var oDiv = document.getElementById('div1');
var p = oDiv.getElementsByTagName('p')[0];
//把null这个参数换成before 或者after
console.log(window.getComputedStyle(p,'before').content);
</script>
获取元素的偏移量
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{ margin: 0; padding: 0; }
#outer{position: relative; width: 200px; height: 200px; margin: 30px auto; padding: 50px;
background: deeppink; border: 10px solid #999; }
#middle{position: relative; width: 80px; height: 80px; background: green; border: 10px solid #999; padding: 50px; }
#inner{ width: 60px; height: 60px; border: 10px solid #999; background: darkblue; }
</style>
</head>
<body>
<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
</body>
</html>
<script>
/*
* offsetLeft 和 offsetTop 的问题 offsetParent
* */
var inner = document.getElementById('inner');
console.log(inner.offsetParent,inner.parentNode,inner.offsetLeft); //
var middle = document.getElementById('middle');
console.log(middle.offsetParent,middle.parentNode,middle.offsetLeft);
var outer = document.getElementById('outer');
console.log(outer.offsetParent,outer.parentNode,outer.offsetLeft);
//offsetParent 和 parentNode 完全不是一回事,我们的offsetParent取决你元素的相对位置
function offset(ele){ //只要存在offsetParent我们就尝试把offsetParent的边框和它的offsetLeft加上,一直到body不存在offsetParent(body的offsetParent是null)为止。我们知道截至的条件,所以使用while循环
var eleLeft = ele.offsetLeft; //当前元素的offsetLeft
var eleTop = ele.offsetTop; //当前元素的offsetTop
var eleParent = ele.offsetParent;
var left = null;
var top = null;
left +=eleLeft;
top += eleTop;
while(eleParent){ //存在父级相对位置参照物
//console.log(eleParent);
/*
* ps: ie8中会有一个问题如果在ie8中就不加父级的边框了。因为已经加过了。
* 判断我的当前浏览器是不是ie8 1 可以用正则 test MSIE 8.0 2 字符串
* 中的indexOf MSIE 8.0 判断 -1. window.navigator.userAgent
* */
left += eleParent.clientLeft/*父级参照物的边框*/+eleParent.offsetLeft;
top += eleParent.clientTop/*父级参照物的上边框*/+eleParent.offsetTop;
eleParent = eleParent.offsetParent;//??
}
return {left:left,top:top};
}
console.log(offset(inner));
</script>
返回顶部案例实战
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
*{ margin: 0; padding: 0; }
html,body{ width: 100%; height: 300%; background: linear-gradient(to right bottom, #0001ff 0, #9bff83 10%, #ff44b5 20%, #1600ff 30%, #000000 40%, #ff0500 50%, #ffffff 60%, #ff0500 70%, #ffffff 80%, #000000 100%);
font-family: 'Microsoft Yahei'; font-weight: bold; }
.link{ display: none; text-decoration: none; width: 50px; height: 50px; border: 2px solid #999; border-radius: 100%; line-height: 50px; text-align: center; background: orangered; position: fixed; right: 30px; bottom: 30px; opacity: .5; }
.link:hover{ opacity: .9; }
</style>
</head>
<body>
<!--锚点-->
<!--<div id="id" style="height: 30px; position: relative; left: 0; top: 500px; background: black;"></div>-->
<!--href="javascript:void 0" 可以阻止a链接的默认行为-->
<!--<a href="#id" class="link">Top</a>--> <!--默认行为-->
<a href="javascript: void 0" class="link" id="link">Top</a> <!--默认行为-->
</body>
</html>
<script src="utils.js"></script>
<script>
/*
* js盒子模型只有scrollTop和scrollLeft是可读写。
* */
// 获取这个a链接按钮
var aLink = document.getElementById('link');
aLink.onclick = function (){
/*document.body.scrollTop = 0;*/
var duration = 500; //要在500ms内完成运动效果
var distance = utils.getWin('scrollTop'); //滚出去的部分就是要运动的距离
var interval = 10;
var step = (distance/duration)/*1ms跑多远*/*interval;//我们每驱动一定时器就跑step这么远
var timer = window.setInterval(function (){
if(utils.getWin('scrollTop') <= 0){ //定时器就清除掉了
window.clearInterval(timer);
//已经回到了顶部,为了下次的onscroll事件仍然需要被出发,显示按钮需要把已经移除的事件再添加上
window.onscroll = showBtn; //把丢失的事件重新注册
return;
}
var srcollTop = utils.getWin('scrollTop');
srcollTop -= step; //每次在原有的基础上减去步长
utils.getWin('scrollTop',srcollTop);
console.log(utils.getWin('scrollTop')); //虽然达到了回到顶部的效果,但是我们的定时器却仍然在运行。所以别忘记清掉定时器
},interval);
window.onscroll = null; //当我点击发生的时候,为了避免由于scroll事件引起的按钮显示问题,可以先人为的移除事件
this.style.display = 'none'; //这里的消失效果,如果不加断点根本就看不到,在回到顶部的过程中又触发了window.onscroll事件,而这个事件是处理按钮显示的
}
//默认让按钮隐藏,当滚轮超过一屏的时候让按钮显示
window.onscroll = showBtn;
function showBtn(){ //浏览器会在单位时间内不断的捕捉 频率 frequency
//console.log('你已经触发了滚轮事件');
//判断你滚轮滚出去了多少
var winScrollTop = utils.getWin('scrollTop'); //获取了浏览器已经滚出去高度
var screenHeight = utils.getWin('clientHeight');
//console.log(winScrollTop-screenHeight);
if(winScrollTop-screenHeight > 0){ //滚出的部分已经超过了一屏
aLink.style.display = 'block';
}
}
</script>
dom库的封装
var utils = {
listToArray: function (similarArray) {
/*
* try catch js
* */
var a = [];
try {
a = Array.prototype.slice.call(similarArray);
} catch (e) {
alert(); //ie7 和 8 弹出
var a = [];
for (var i = 0; i < similarArray.length; i++) {
a[a.length] = similarArray[i];
}
}
return a;
},
jsonParse: function (jsonStr) {
return 'JSON' in window ? JSON.parse(jsonStr) : eval("(" + jsonStr + ")");
},
offset: function (ele) {
var eleLeft = ele.offsetLeft;
var eleTop = ele.offsetTop;
var eleParent = ele.offsetParent;
var left = null;
var top = null;
left += eleLeft;
top += eleTop;
while (eleParent) {
//console.log(eleParent);
/*
* ps: ie8中会有一个问题如果在ie8中就不加父级的边框了。因为已经加过了。
* 判断我的当前浏览器是不是ie8 1 可以用正则 test MSIE 8.0 2 字符串
* 中的indexOf MSIE 8.0 判断 -1. window.navigator.userAgent
* */
if (window.navigator.userAgent.indexOf('MSIE 8.0') !== -1) { //ie8
left += eleParent.offsetLeft;
top += eleParent.offsetTop;
} else {
left += eleParent.clientLeft + eleParent.offsetLeft;
top += eleParent.clientTop + eleParent.offsetTop;
}
eleParent = eleParent.offsetParent;
}
return {left: left, top: top};
},
getWin: function (attr, val) { //一个参数的时候是读取,两个参数可以赋值
if (val !== undefined) {
document.documentElement[attr] = val;
document.body[attr] = val;
}
return document.documentElement[attr] || document.body[attr];
},
getCss: function (curEle, attr) {
//
var reg = /^(-?\d+(\.\d+)?)(?:px|em|pt|deg|rem)$/;
var val = null;
if (/MSIE (?:6|7|8)/.test(window.navigator.userAgent)) {
//这里处理filter的滤镜问题 alpha(opacity=40);
if (attr === 'opacity') {
//alpha(opacity=40)
val = curEle.currentStyle['filter'];
var reg1 = /^alpha\(opacity=(\d+(\.\d+)?)\)/;
return reg1.test(val) ? RegExp.$1 / 100 : 1;
}
val = curEle.currentStyle[attr];
} else {
val = attr === 'opacity' ? window.getComputedStyle(curEle,null)[attr]/1 : window.getComputedStyle(curEle,null)[attr];
}
return reg.test(val) ? parseFloat(val) : val; //如果正则验证通过,寿命返回值是带单位的,那么我们就要人为去掉这个单位。否则不变
}
}
网友评论