jsDOM模型详解二之HTMLDOM

jsDOM模型详解二之HTMLDOM

简介:

HTML DOM是HTML Document Object Model(文档对象模型)的缩写,HTML DOM专门适用于 HTML最佳化XHTML的文档对象模型。
可以将HTML DOM理解为网页的API。HTML DOM将网页中的各个元素都看作对象,从而使网页中的元素也可以被计算机语言获取或者编辑。
HTML DOM 定义了访问和操作HTML文档的标准方法。

HTML DOM事实上是标准DOM的一种实现,在标准DOM中,认为一切HTML元素都是节点对象,即可以理解为:
HTML对象是Node对象的后代对象
每一个HTML元素都有一个DOM对象原型,比如:

,其DOM对象原型是HTMLDivElement

,其DOM对象原型是HTMLParagraphElement

所有HTML对象的公共原型是HTMLElement,而HTMLElement的原型是Element, Element的原型是Node。
HTML DOM中的主要内容包括HTMLElement、Style对象、Event对象、表单对象等

HTMLElement对象

在DOM标准中,每个HTML元素都是继承自HTMLElement。即每个HTML元素对象都继承了HTMLElement的属性和方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nv3xbzxl-1596378342624)(C:\Users\dell\Desktop\我的前端博客\images2\dom4.png)]

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>元素的尺寸_HTMLElement对象</title>
<style type="text/css">
	body {
		margin:0px;
		padding:100px;
	}
	#content {
		width:600px;
		height:200px;
		overflow:scroll;
		border:#069 10px solid;
		background:#D3E6FE;
		padding:50px;
		font-size:14px;
		line-height:200%;
		margin:100px;
	}
</style>
</head>

<body>
	<div id="content">
        <h1>再别康桥</h1>
        轻轻的我走了,<br/>
        正如我轻轻的来;<br/>
        我轻轻的招手,<br/>
        作别西天的云彩。<br/>
        那河畔的金柳,<br/>
        是夕阳中的新娘;<br/>
        波光里的艳影,<br/>
        在我的心头荡漾。<br/>
        软泥上的青荇,<br/>
        油油的在水底招摇;<br/>
        在康河的柔波里,<br/>
        我甘心做一条水草。<br/>
        那榆阴下的一潭,<br/>
        不是清泉,是天上虹;<br/>
        揉碎在浮藻间,<br/>
        沉淀着彩虹似的梦。<br/>
        寻梦?撑一支长篙,<br/>
        向青草更青处漫溯;<br/> 
	</div>
    <div id="info">
    </div>
<script language="javascript">		
	var str = '';
	str += 'Body的offsetWidth:'+document.body.offsetWidth+'<br/>';
	str += 'Body的offsetHeight:'+document.body.offsetHeight+'<br/>';
	str += 'Body的offsetTop:'+document.body.offsetTop+'<br/>';
	str += 'Body的offsetLeft:'+document.body.offsetLeft+'<br/>';
	str += 'Body的clientWidth:'+document.body.clientWidth+'<br/>';
	str += 'Body的clientHeight:'+document.body.clientHeight+'<br/>';
	str += 'Body的clientTop:'+document.body.clientTop+'<br/>';
	str += 'Body的clientLeft:'+document.body.clientLeft+'<br/>';
	str += 'Body的scrollWidth:'+document.body.scrollWidth+'<br/>';
	str += 'Body的scrollHeight:'+document.body.scrollHeight+'<br/>';
	str += 'Body的scrollTop:'+document.body.scrollTop+'<br/>';
	str += 'Body的scrollLeft:'+document.body.scrollLeft+'<br/>';
	
	str += '<p>*******************************************************</p>';
	var contentObj = document.getElementById('content');
	
	str += 'Content的offsetWidth:'+contentObj.offsetWidth+'<br/>';
	str += 'Content的offsetHeight:'+contentObj.offsetHeight+'<br/>';
	str += 'Content的offsetTop:'+contentObj.offsetTop+'<br/>';
	str += 'Content的offsetLeft:'+contentObj.offsetLeft+'<br/>';
	str += 'Content的clientWidth:'+contentObj.clientWidth+'<br/>';
	str += 'Content的clientHeight:'+contentObj.clientHeight+'<br/>';
	str += 'Content的clientTop:'+contentObj.clientTop+'<br/>';
	str += 'Content的clientLeft:'+contentObj.clientLeft+'<br/>';
	str += 'Content的scrollWidth:'+contentObj.scrollWidth+'<br/>';
	str += 'Content的scrollHeight:'+contentObj.scrollHeight+'<br/>';
	str += 'Content的scrollTop:'+contentObj.scrollTop+'<br/>';
	str += 'Content的scrollLeft:'+contentObj.scrollLeft+'<br/>';
	
	var infoObj = document.getElementById('info');
	infoObj.innerHTML = str;
</script>
</body>
</html>
//直接复制上述代码运行即可查看效果

offsetWidth 水平方向 width + 左右padding + 左右border-width

offsetHeight 垂直方向 height + 上下padding + 上下border-width

clientWidth 水平方向 width + 左右padding

clientHeight 垂直方向 height + 上下padding

offsetTop 获取当前元素到 定位父节点 的top方向的距离

offsetLeft 获取当前元素到 定位父节点 的left方向的距离

scrollWidth 元素内容真实的宽度,内容不超出盒子高度时为盒子的clientWidth

scrollHeight 元素内容真实的高度,内容不超出盒子高度时为盒子的clientHeight

css样式

每个HTML元素都有一个style属性,通过style可以给HTML元素设置CSS样式,这种设置方式叫做“内联样式表”或“行内样式表”
在Javascript中,我们可以通过HTML DOM中的Style对象操作HTML对象的“内联样式表”:
Style对象只能获取或设置HTML对象的style属性中的CSS属性。
对于没有中划线的css属性一般直接使用style.属性名即可。如:obj.style.margin
对于含有中划线的css属性,将每个中划线去掉并将每个中划线后的第一个字符换成大写即可。如:obj.style.marginTop
浮动比较特殊,要使用obj.style. cssFloat
对于多值符合属性,不能直接访问属性值,要通过最终属性名

1.通过window.getComputedStyle(obj,null)获取Style对象:
如果已知对象的Id,这种方式可以获取该对象所有的CSS属性。
这种方式IE不支持,IE中需要用obj.currentStyle。
对于多值复合属性,这种方式获取不到属性值,要通过最终属性名。
在Firefox中,颜色获取到的值形式如rgb(255,0,0),而IE中则如#ff0000。

2.JS操作CSS除了Style对象外,我们还可以通过以下两种方式:
对象的className。
给link一个Id,通过Id来操作外部样式表。网页换皮肤的原理也是来源于此。

//网页换肤
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>改变整个页面的样式_CSS样式操作</title>
<link rel="stylesheet" id="mySkin" type="text/css" href="CSS/a.css">
</head>

<body>
	<div class="box">
    	竭尽全力而不是尽力而为
    </div>
    
    <input type="button" value="皮肤A" onClick="skin('a');"/>
    <input type="button" value="皮肤B" onClick="skin('b');"/>
    <input type="button" value="皮肤C" onClick="skin('c');"/>
	<script language="javascript">
		function skin(s){
			var mySkin = document.getElementById('mySkin');
			mySkin.href = 'CSS/'+s+'.css';
		}
	</script>
</body>
</html>

EVENT事件对象

Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,因为函数不会在事件发生前被执行。

事件处理的4种方式

1.手工触发:
用法:在HTML代码中用事件属性执行代码或函数
优点:使用直接、简单,哪个HTML标签要触发什么事件,则就在该HTML标签上加事件属性。
缺点:不能做到JS与HTML完全分离。

2.匿名函数:
用法:在JS中获取要触发事件的HTML对象,给HTML对象的事件属性绑定一个匿名函数,作为事件的响应。
优点:可以做到JS与HTML完全分离
缺点:一个匿名函数只能绑定给一HTML对象的事件属性,事件响应函数不能重用

3.显示声明:
用法:在JS中,通过function关键字显示声明函数,然后获取要触发事件的HTML对象,给HTML对象的事件属性绑定一个显示函数的函数名,作为事件的响应。
优点:可以做到JS与HTML完全分离,并且显示声明的函数可以重复使用
缺点:显示声明的函数与HTML对象的事件属性从代码上看,没有直观的联系。

4.事件监听函数:
用法:通过HTML DOM 对象的addEventListener()方法,为该对象注册事件响应函数。
语法:target.addEventListener(type, listener, useCapture);
target:文档节点、document、window 或 XMLHttpRequest。
type:字符串,事件名称,不含"on",比如"click"、“mouseover”、"keydown"等。
listener:实现了 EventListener 接口或者是 JavaScript 中的函数。
useCapture:是否使用捕捉,看了后面的“事件流”就明白了,一般用 false。

<body>    
    <input type="button" value="手工触发事件" onClick="clickMe();"/>
    <input type="button" value="匿名函数事件" id="myId"/>
    <input type="button" value="显式声明事件" id="myId"/>
    <script language="javascript">
		function clickMe(){
			alert('每个HTML元素都有事件属性,其形式“on”+“事件名称”,不区分大小写。\n这是通过手工触发的方式点击我了');
		}
		var myIdObj = document.getElementById("myId");
		myIdObj.onclick = function(){
			alert('每个HTML元素的DOM对象都有事件属性,其形式“on”+“事件名称”,不区分大小写。\n这是通过匿名函数的方式点击我了');
		}
		var myIdObj = document.getElementById("myId");
		myIdObj.onclick = clickMe; //clickMe为什么不加括号
		function clickMe(){
			alert('每个HTML元素的DOM对象都有事件属性,其形式“on”+“事件名称”,不区分大小写。\n这是通过显式声明的方式点击我了');
		}
	</script>
</body>

事件监听:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>事件监听函数_事件处理的4种方式</title>
</head>
<body>
    <div id="myId" style="padding:10px; background-color:#0C0; color:#FFF;">
    	事件监听函数事件
    </div>
    <input type="button" value="解除点击事件" onClick="rMyClick();"/>
    <input type="button" value="解除鼠标经过事件" onClick="rMyMouseover();"/>
    <div id="info">
    </div>
    <script language="javascript">
		var myIdObj = document.getElementById("myId");
		myAddEvent(myIdObj,'click',myClick,false);
		myAddEvent(myIdObj,'mouseover',myMouseover,false);
		
		//兼容各种浏览器的事件监听函数
		function myAddEvent(target,type,listener,useCapture){
			if(window.navigator.userAgent.indexOf("MSIE")>0){ //判断是否是IE
				target.attachEvent('on'+type,listener);
			}else{
				target.addEventListener(type,listener,useCapture);
			}
		}
		//兼容各种浏览器的解除事件监听函数
		function myRemoveEvent(target,type,listener,useCapture){
			if(window.navigator.userAgent.indexOf("MSIE")>0){ //判断是否是IE
				target.detachEvent('on'+type,listener);
			}else{
				target.removeEventListener(type,listener,useCapture);
			}
		}
		
		function myClick(){
			document.getElementById('info').innerHTML += '通过事件监听函数的方式点击了我***<font color="#f00">鼠标点击</font>***!<br/>';
		}
		
		function myMouseover(){
			document.getElementById('info').innerHTML += '通过事件监听函数的方式触发了我***<font color="#00f">鼠标经过</font>***!<br/>';
		}
		
		function rMyClick(){
			myRemoveEvent(myIdObj,'click',myClick,false);
		}
		function rMyMouseover(){
			myRemoveEvent(myIdObj,'mouseover',myMouseover,false);
		}
	</script>
</body>
</html>

优点:
可以对同一物件的同一事件绑定多个事件处理程序。
可以通过事件流三个阶段更好地控制何时触发事件处理程序。
工作于 DOM 元素,而不仅是 HTML 元素。
缺点:
addEventListener()方法存在兼容性问题,在IE中要使用attachEvent()方法,其语法为:
target. attachEvent(type, listener);

事件流

当一个事件发生时,分为三个阶段:
捕获阶段:从根节点开始顺序而下,检测每个节点是否注册了事件处理程序。如果注册了事件处理程序,并且 useCapture 为 true,则调用该事件处理程序。(IE 中无此阶段。)
目标阶段:触发在目标对象本身注册的事件处理程序,也称正常事件派发阶段。
冒泡阶段:从目标节点到根节点,检测每个节点是否注册了事件处理程序,如果注册了事件处理程序,并且 useCapture 为 false,则调用该事件处理程序。

事件流的发送顺序有以下规律:
true 的触发顺序总是在 false 之前;
如果多个均为 true,则外层的触发先于内层;
如果多个均为 false,则内层的触发先于外层。
停止事件流传播:
当一个操作发生后,我们往往只需要一个响应就足够了,这个时候,我们需要停止事件流的传播。
event.stopPropagation()用于停止事件流传播。(IE中使用event.cancelBubble = true )其中event指事件对象,什么是事件对象?请听下回分解。

//代码复制运行即可
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>什么是事件流</title>
<style type="text/css">
	#divA , #divB , #divC {
		padding:20px;
	}
	#divA {
		background-color:#C00;
	}
	#divB {
		background-color:#F90;
	}
	#divC {
		background-color:#FFC;
	}
</style>
</head>

<body id="body">
    <div id="divA">
    	<div id="divB">
        	<div id="divC"></div>
        </div>
    </div>
    <script language="javascript">
		//兼容各种浏览器的事件监听函数
		function myAddEvent(target,type,listener,useCapture){
			if(window.navigator.userAgent.indexOf("MSIE")>0){ //判断是否是IE
				target.attachEvent('on'+type,listener);
			}else{
				target.addEventListener(type,listener,useCapture);
			}
		}
		myAddEvent(document.getElementById("body"),'click',function(){alert('body被点击啦');},false);
		myAddEvent(document.getElementById("divA"),'click',function(){alert('divA被点击啦');},false);
		myAddEvent(document.getElementById("divB"),'click',function(){alert('divB被点击啦');},false);
		myAddEvent(document.getElementById("divC"),'click',function(){alert('divC被点击啦');},false);
	</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_44691513/article/details/107752850