Part3:DOM、DOM盒子模型

JS中的DOM操作:盒子模型属性

DOM:document object model 文档对象模型,提供系列的属性和方法,让我们能在JS中操作页面中的元素

1.获取元素的属性和方法
document.getElementById([ID])
[context].getElementsByTagName([TAG-NAME])
[context].getElementsByClassName([CLASS-NAME]) 
//=>在IE6~8中不兼容
document.getElementsByName([NAME]) 
//=>在IE浏览器中只对表单元素的NAME有作用
[context].querySelector([SELECTOR])
[context].querySelectorAll([SELECTOR])
//=>在IE6~8中不兼容

//---------------------
document
document.documentElement  
document.head
document.body
childNodes 所有子节点
children 所有元素子节点
//=>IE6~8中会把注释节点当做元素节点获取到
parentNode
firstChild / firstElementChild
lastChild / lastElementChild
previousSibling / previousElementSibling
nextSibling / nextElementSibling
//=>所有带Element的,在IE6~8中不兼容
2.DOM的增删改操作
document.createElement([TAG-NAME])
document.createTextNode([TEXT CONTENT])
字符串拼接(模板字符串),基于innerHTML/innerText存放到容器中

[PARENT].appendChild([NEW-ELEMENT])
[PARENT].insertBefore([NEW-ELEMENT],[ELEMENT])

[ELEMENT].cloneNode([TRUE/FALSE])
[PARENT].removeChild([ELEMENT])

//=>设置自定义属性
[ELEMENT].xxx=xxx;
console.log([ELEMENT].xxx);
delete [ELEMENT].xxx;

[ELEMENT].setAttribute('xxx',xxx);
console.log([ELEMENT].getAttribute('xxx'));
[ELEMENT].removeAttribute('xxx');
3.获取元素样式和操作样式
//=>修改元素样式
[ELEMENT].style.xxx=xxx;  //=>修改和设置它的行内样式
[ELEMENT].className=xxx;  //=>设置样式类

//=>获取元素的样式
console.log([ELEMENT].style.xxx); //=>获取的是当前元素写在行内上的样式,如果有这个样式,但是没有写在行内上,则获取不到
4.JS盒子模型属性

基于一些属性和方法,让我们能够获取到当前元素的样式信息,例如:clientWidth 、offsetWidth等

  • client
    • width / height
    • top / left
  • offset
    • width / height
    • top / left
    • parent
  • scroll
    • width / height
    • top / left

方法:window.getComputedStyle([ELEMENT],[伪类]) / [ELEMENT].currentStyle

【案例1】:盒子居中
<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title>JS盒子模型属性</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}

		html,
		body {
			height: 100%;
		}

		.box {
			box-sizing: border-box;
			padding: 15px;
			width: 300px;
			height: 300px;
			border: 10px solid lightblue;
			background: lightcyan;
			font-size: 18px;
			line-height: 30px;
		}

		/* 居中:定位(五种)  */
		/* .box {
			position: absolute;
			top: 50%;
			left: 50%;
			margin-left: -150px;
			margin-top: -150px;
		} */

		/* .box {
			position: absolute;
			top: 50%;
			left: 50%;
			/!* 基于CSS3变形属性中的位移,在不知道宽高的情况下也能实现效果 *!/
			transform: translate(-50%, -50%);
		} */

		/* .box {
			position: absolute;
			top: 0;
			left: 0;
			bottom: 0;
			right: 0;
			margin: auto;
		} */

		/* FLEX :http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html*/
		/* body {
			display: flex;
			/!* 设置元素在FLEX容器主轴和交叉轴方向上的对齐方式:CENTER居中对齐 *!/
			justify-content: center;
			align-items: center;
		} */
	</style>
</head>

<body>
	<div id="box" class="box">
		夫君子之行,静以修身,俭以养德,非淡泊无以明志,非宁静无以致远。夫学须静也,才须学也,非学无以广才,非志无以成学。淫漫则不能励精,险躁则不能冶性,年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及~~
	</div>
	<script>
		// JS实现居中:(一屏幕的宽度-盒子的宽度)/2 === LEFT
		let winW = document.documentElement.clientWidth,
			winH = document.documentElement.clientHeight,
			box = document.getElementById('box');
		box.style.position = 'absolute';
		box.style.left = (winW - 300) / 2 + 'px';
		box.style.top = (winH - 300) / 2 + 'px';
	</script>
</body>

</html>

box-sizing的作用:
在这里插入图片描述

let box = document.getElementById('box');

//=>获取盒子可视区域的宽高(内容宽度+左右PADDING)
//1.内容溢出与否对他无影响
//2.获取的结果是没有单位的(其余的盒模型属性也是)
//3.获取的结果是整数,它会自己进行四舍五入(其余的盒模型属性也是)
box.clientWidth
box.clientHeight

//获取当前页面一屏幕(可视化)区域的宽高
let winW = document.documentElement.clientWidth || document.body.clientWidth;
let winH = document.documentElement.clientHeight || document.body.clientHeight;

//=>获取盒子左边框和上边框的大小
box.clientLeft
box.clientTop
let box = document.getElementById('box');

//=>在CLIENT的基础上加上BORDER == 盒子本身的宽高
box.offsetWidth
box.offsetHeight

//=>在没有内容溢出的情况下,获取的结果和CLIENT是一样的
//=>在有内容溢出的情况下,获取的结果约等于真实内容的宽高(上/左PADDING + 真实内容的高度/宽度)
//1.不同浏览器获取的结果不尽相同
//2.设置overflow属性值对最后的结果也会产生一定的影响
box.scrollWidth
box.scrollHeight

//获取整个页面真实的高度
document.documentElement.scrollHeight || document.body.scrollHeight
let box = document.getElementById('box');
//=>竖向滚动条卷去的高度
//=>横向滚动条卷去的宽度
//1.边界值
//min=0
//max=整个的高度scrollHeight - 一屏幕高度clientHeight
box.scrollTop
box.scrollLeft

//=>13个盒子模型属性,只有这两个是“可读写”的属性(既可以获取也可以设置对应的值),其余的都是“只读”属性(不能设置值,只能获取)
box.scrollTop=0;
【案例2】:回到顶部
<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title>回到顶部</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}

		html,
		body {
			height: 1000%;
			/* CSS3中的背景颜色线性渐变 */
			background: -webkit-linear-gradient(top left, lightblue, lightpink, lightyellow);
		}

		.link {
			display: none;
			position: fixed;
			right: 30px;
			bottom: 230px;
			box-sizing: border-box;
			width: 100px;
			height: 100px;
			background: lightcoral;
			font-size: 16px;
			color: #000;
			text-decoration: none;
			text-align: center;
			line-height: 100px;
		}
	</style>
</head>

<body>
	<a href="javascript:;" id="link" class="link">回到顶部</a>

	<script>
		let HTML = document.documentElement,
			LINK = document.getElementById('link');

		// 1.当浏览器滚动条滚动的时候,我们进行验证:卷去的高度超过两屏,我们让#LINK显示
		function check() {
			//winH:一屏幕高度  scrollT:卷去的高度
			let winH = HTML.clientHeight,
				scrollT = HTML.scrollTop;
			LINK.style.display = scrollT >= winH * 2 ? 'block' : 'none';
		}
		window.onscroll = check;

		// 2.点击回到顶部
		LINK.onclick = function () {
			/* 让按钮隐藏 */
			LINK.style.display = 'none';
			//先禁止滚动事件触发(因为在回到顶部的运动过程中,如果事件一直在,会计算按钮显示隐藏的样式,无法让按钮隐藏)
			window.onscroll = null;

			/* 实现动画 */
			let step = 1000;
			let timer = setInterval(() => {
				//每一次获取最新的SCROLL-TOP值,在现有的基础上减去步长,让其走一步
				let curT = HTML.scrollTop;
				if (curT === 0) {
					//边界判断:已经回到顶部后,我们清除定时器
					clearInterval(timer);
					//恢复滚动条滚动的监听事件
					window.onscroll = check;
					return;
				}
				curT -= step;
				HTML.scrollTop = curT;
			}, 17);
		};


		//SET-INTERVAL:设置一个定时器(TIMER代表这个定时器),每间隔INTERVAL这么久,就会把FUNCTUION执行一次...一直到手动清除定时器为止
		// let timer = setInterval([FUNCTUION], [INTERVAL]);
		// clearInterval(timer);
	</script>
</body>

</html>
【案例3】:盒子模型
<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title>JS盒子模型属性</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}

		.outer {
			box-sizing: border-box;
			margin: 20px auto;
			width: 500px;
			height: 500px;
			background: lightcoral;
			border: 10px solid orangered;

			position: relative;
		}

		.box {
			box-sizing: border-box;
			margin: 20px auto;
			padding: 15px;
			width: 300px;
			height: 300px;
			border: 10px solid lightblue;
			background: lightcyan;
			font-size: 18px;
			line-height: 30px;
			overflow: auto;
		}
	</style>
</head>

<body>
	<div class="outer" id="outer">
		<div id="box" class="box">
			夫君子之行,静以修身,俭以养德,非淡泊无以明志,非宁静无以致远。夫学须静也,才须学也,非学无以广才,非志无以成学。淫漫则不能励精,险躁则不能冶性,年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及~~
		</div>
	</div>

	<script>
		/*
		 * offset:获取当前元素距离BODY的左/上偏移(不论其父参照物是谁)
		 *   @params
		 *      curEle:current element当前要操作的元素
		 *   @return
		 *      [object]包含上/左偏移的信息  => {top:xxx,left:xxx} 
		 * by zhufengpeixun on 2019/08/14
		 */
		function offset(curEle) {
			let par = curEle.offsetParent,
				l = curEle.offsetLeft,
				t = curEle.offsetTop;
			//存在父参照物,而且还没有找到BODY
			while (par && par.tagName !== "BODY") {
				//在原有偏移的基础上累加:父参照物的边框、父参照物的偏移
				if (!/MSIE 8\.0/.test(navigator.userAgent)) {
					//IE8中偏移值自已就算了边框了,不需要我们在加边框的值 navigator.userAgent获取当前浏览器的版本信息
					l += par.clientLeft;
					t += par.clientTop;
				}
				l += par.offsetLeft;
				t += par.offsetTop;
				//继续获取上级参照物
				par = par.offsetParent;
			}
			return {
				top: t,
				left: l
			};
		}
	</script>

</body>

</html>
5.getComputedStyle

获取当前元素所有经过浏览器计算过的样式

  • 只要元素在页面中呈现出来,那么所有的样式都是经过浏览器计算的
  • 哪怕你没有设置和见过的样式也都计算了
  • 不管你写或者不写,也不轮写在哪,样式都在这,可以直接获取

在IE6~8浏览器中不兼容,需要基于currentStyle来获取

//=>第一个参数是操作的元素  第二个参数是元素的伪类:after/:before
//=>获取的结果是CSSStyleDeclaration这个类的实例(对象),包含了当前元素所有的样式信息
let styleObj = window.getComputedStyle([element],null);
//获取方式:
styleObj["backgroundColor"]
styleObj.display

//=>IE6~8
styleObj = [element].currentStyle;
6.图片延迟加载【较难】
<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title>图片延迟加载</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}

		img {
			border: none;
		}

		img[src=""] {
			display: none;
		}

		.imgBox {
			box-sizing: border-box;
			margin: 800px auto;
			width: 300px;
			height: 245px;
			background: #CCC;
		}

		.imgBox img {
			display: none;
			width: 100%;
			height: 100%;
		}
	</style>
</head>

<body>
	<!-- 
		图片延迟加载 “图片懒加载”
		1.结构中,我们用一个盒子包裹着图片(在图片不展示的时候,可以占据着这个位置,并且设置默认的背景图或者背景颜色)
		2.最开始,IMG的SRC中不设置任何的图片地址,把图片的真实地址设置给自定义属性DATA-SRC/TRUE-IMG(最开始不展示图片:可以让图片隐藏)
		3.当浏览器窗口完全展示到图片位置的时候,我们再去加载真实图片,并且让其显示出来(第一屏幕中的图片一般都会延迟加载,来等待其它资源先加载完)
	 -->
	<div class="imgBox">
		<img src="" alt="" trueImg="images/IE3.jpg">
	</div>

	<!-- IMPORT JS -->
	<script src="4.延迟加载.js"></script>
</body>

</html>
/*
 * offset:获取当前元素距离BODY的左/上偏移(不论其父参照物是谁)
 *   @params
 *      curEle:current element当前要操作的元素
 *   @return
 *      [object]包含上/左偏移的信息  => {top:xxx,left:xxx} 
 * by zhufengpeixun on 2019/08/14
 */
function offset(curEle) {
	let par = curEle.offsetParent,
		l = curEle.offsetLeft,
		t = curEle.offsetTop;
	while (par && par.tagName !== "BODY") {
		if (!/MSIE 8\.0/.test(navigator.userAgent)) {
			l += par.clientLeft;
			t += par.clientTop;
		}
		l += par.offsetLeft;
		t += par.offsetTop;
		par = par.offsetParent;
	}
	return {
		top: t,
		left: l
	};
}


/*
 * 图片完全显示出来的条件 
 *   A:盒子底边距离BODY(页面最顶端)的距离:盒子的高度+盒子距BODY的上偏移
 *   B:浏览器底边距离BODY的距离:一屏幕的高度 + 卷去的高度
 *   A<=B:盒子就完全出现在用户的视野中
 * 让图片显示
 *   获取图片TRUE-IMG属性的值,赋值给SRC属性,当图片能正常加载出来后,让图片显示即可
 */
let imgBox = document.querySelector('.imgBox'),
	_img = imgBox.querySelector('img');

//=>显示图片 
//curImg:要显示的图片
function lazyImg(curImg) {
	//给SRC赋值真实的图片地址
	let trueImg = curImg.getAttribute("trueImg");
	curImg.src = trueImg;
	//校验图片是否能够正常加载出来:IMG.ONLOAD事件用来监听图片是否能加载
	curImg.onload = function () {
		curImg.style.display = 'block';
	};
	//=>设置自定义属性:isLoad存储当前图片已经加载过了
	curImg.isLoad = true;
}

//=>监听页面滚动事件(不论基于什么方式,只要页面滚动了,则触发事件)
window.onscroll = function () {
	//=>已经加载过就不要在重复加载了
	if (_img.isLoad) return;

	let HTML = document.documentElement,
		B = HTML.clientHeight + HTML.scrollTop,
		A = imgBox.offsetHeight + offset(imgBox).top; //=>当前案例中,获取距离BODY的上偏移完全可以imgBox.offsetTop,因为父参照物就是BODY
	if (A <= B) {
		//=>符合图片显示的条件了
		lazyImg(_img);
	}
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值