[js]dom树-js原型链
这是之前总结的, 发现有很多的毛病,就是重点不突出,重新翻看的时候还是得耗费很长时间去理解这玩意.
js中的继承
js中什么是类
1,类是函数数据类型
2.每个类有一个自带prototype属性
prototype = constractor+__proto__
3,每个类的实例指向类的原型
给人感觉子类继承父类的东西,和父类本身没啥关系, 和父类的财产(原型)有关系.
console.log(document instanceof Document); // true
console.log(window instanceof Window); // true
object <-- EventTarget <--
Element(1)
HTMLElement <-- HTMLDivElement <-- div
odiv = document.getElementById('app');
Document(9)
document是Document的一个实例.
- 常用属性
document.head
document.body
document.title
document.location.href
document.location.host
document.location.protocol
document.location.host
document.location.origin
document.URL //获取url
document.location.pathname
document.location.search
document.cookie
document.documentElement //整个html的引用
- 常用方法
document.getElementById
document.getElementsByClassName
document.getElementsByTagName
document.append
window.location.pathname
window.location.search
window.close() //关闭标签
window.open()
参考: http://www.w3school.com.cn/js/js_window.asp
onchange等事件,在哪里?
dir(HTMLDivElement)
DOM 是为了操作文档出现的 API,document 是其的一个对象;
BOM 是为了操作浏览器出现的 API,window 是其的一个对象。
- 继承: 本类的原型指向要继承类的实例
- 模拟系统类
function myObject() {
};
function myEventTarget() {
};
myEventTarget.prototype = new myObject;
myEventTarget.prototype.addListener = function () {
};
function myNode() {
}
myNode.prototype = new myEventTarget;
myNode.prototype.createElement = function () {
};
var n = new myNode;
console.dir(n);
js
DOM节点层次图
Dom并非一种编程语言,Dom只是提供了一系列的接口,利用Dom的这些接口可以很方便的读取,修改,删除Html和XML文件中的标签元素和文本内容.在这里我们侧重于讲解Dom对Html文件的操作.
那么Dom是如何读取和管理Html文件的呢?首先你必须要了解html的源码结构
div > HTMLDivElement > HTMLElement > Element > Node > EventTarget
document -> HTMLDocument > Document > Node > EventTarget
参考: DOM, DOCUMENT, BOM, WINDOW 有什么区别?
https://www.zhihu.com/question/33453164
document.title = 'how to make love';
document.body;
document.getElementById('xxx');
DOM 是为了操作文档出现的 API,document 是其的一个对象;
BOM 是为了操作浏览器出现的 API,window 是其的一个对象。
div > HTMLDivElement > HTMLElement > Element > Node > EventTarget
document -> HTMLDocument > Document > Node > EventTarget
参考: http://huang-jerryc.com/2016/06/28/JavaScript原型中的哲学思想/
参考: 从原型链看DOM--Node类型
http://www.cnblogs.com/venoral/p/5293575.html
参考:http://www.th7.cn/web/js/201609/188644.shtml
参考:http://www.cnblogs.com/mominger/p/3822775.html
dom操作
回顾dom
参考:
http://www.bijishequ.com/detail/413949?p=11-54-70
http://www.bijishequ.com/detail/421975?p=
这篇很经典
http://www.cnblogs.com/jscode/archive/2012/09/04/2670819.html
这篇图解还没怎么理解
http://developer.51cto.com/art/201009/228137_all.htm
div#div1
HTMLDivElement
HTMLElement
Element
Node
EventTarget
Object
div > HTMLDivElement > HTMLElement > Element > Node > EventTarget
document -> HTMLDocument > Document > Node > EventTarget
oDiv instanceof Node //true
oDiv instanceof Element //true
##################################
# 获取元素
##################################
document.
getElementById 得到类数组 获取选项/长度 遍历
getElementsByTagName
getElementsByName(button获取性别,先遍历checkbox,oSex[i].value)
getElementsByClassName
##################################
# 元素之间的关系
##################################
// 节点: 文字 标签 文字 注释都是节点 回车和空格算一个 text
// nodetype nodename nodevalue
// 元素节点: 标签 1 大写标签名 null
// 文本节点: text 3 #text 文档内容
// 注释节点: 8 #commnet 注释内容
// document 9 #document null
console.log(oDiv.nodeType); //获取所有子节点的元素节点,判断nodetype
console.log(oDiv.nodeName);
console.log(oDiv.nodeValue);
console.log(oDiv.children); //获取元素子节点
console.log(oDiv.parentNode); //获取父亲节点
console.log(oDiv.previousElementSibling);//获取上一个哥哥节点
console.log(oDiv.nextSibling); //获取下一个弟弟节点
console.log(oDiv.firstChild); //获取所有子节点中的第一个
console.log(oDiv.lastChild); //获取所有子节点中最后一个
##################################
# 增删改查元素
##################################
var layer = document.createElement("div");
layer.id = "div1";
layer.style.width = "300px";
layer.style.height = "200px";
layer.style.border = "5px solid red";
var btn = document.getElementById('btn');
btn.onclick = function () {
document.body.appendChild(layer);
};
layer.onclick = function () {
document.body.removeChild(layer);
};
oDiv.parentNode.removeChild(oDiv);
document.body.insertBefore(oP2, oP);
oDiv.parentNode.removeChild(oDiv);
var clop = oP.cloneNode(); //克隆当前
var clop2 = oP.cloneNode(true); //克隆子子孙孙
js操作的是行内样式.
oDiv.style.width //引用数据类型
oDiv.style.backgroundColor //这种ok
var bgS = oDiv.style; bgS.backgroundColor //这种ok
var bg = oDiv.style.backgroundColor; bg = "green" //这种不ok
constructor的事
默认类的prototype = constructor+proto
function Fn() {
};
console.log(Fn.prototype);
重新赋值后prototype = proto,没constructor了
function Fn() {
};
Fn.prototype= {
getX: function () {
}
};
console.log(Fn.prototype);
var f = new Fn();
console.log(f.__proto__);
原型链多级继承模拟
<script>
// HTMLDivElement > HTMLElement > Element > Node > EventTarget > object
function myObject() {
};
myObject.prototype = {
hasOwnProperty: function () {
console.log("myObject");
}
};
function myEventTarget() {
};
myEventTarget.prototype = new myObject();
myEventTarget.prototype.sum = function () {
console.log('myEventTarget...')
};
var f = new myEventTarget;
console.dir(f);
</script>
/*
* 操作DOM的属性和方法
* [获取元素或者元素集合]
* getElementById
* ->上下文只能是document(只有document这个实例的原型链上才能找到这个方法,其它实例都找不到)
* ->ID重复了获取第一个
* ->IE6~7中会把表单元素的name当做id使用
* getElementsByTagName
* ->获取当前上下文中,所有子子孙孙中标签名叫做XXX的元素
* getElementsByClassName
* ->IE6~8中不兼容
* getElementsByName
* ->在IE浏览器中只对表单元素的name起作用
* ->上下文也只能是document
* querySelector
* querySelectorAll
* ->不兼容IE6~8
* ->没有DOM映射
* document.documentElement
* document.body
* document.head
* ...
*
* [描述节点和节点之间关系的属性]
* nodeType nodeName nodeValue
* 元素节点 1 大写标签名 null
* 文本节点 3 #text 文本内容
* 注释节点 8 #comment 注释内容
* 文档节点 9 #document null
*
* childNodes:所有子节点
* children:所有元素子节点(IE6~8中会把注释当做元素节点)
* parentNode
* previousSibling / previousElementSibling
* nextSibling
* firstChild
* lastChild
*
* [动态操作DOM]
* createElement
* createDocumentFragment
* appendChild
* insertBefore
* cloneNode(true/false)
* removeChild
* set/get/removeAttribute
*
* [散]
* xxx.style.xxx=xxx 设置行内样式
* =>xxx.style.xxx 获取行内样式
*
* xxx.className='xxx'
*
* xxx.onclick=function...
*
* ...
*/
/*
* JS盒子模型属性
* =>在JS中通过相关的属性可以获取(设置)元素的样式信息,这些属性就是盒子模型属性(基本上都是有关于样式的)
*
* client
* top
* left
* width
* height
*
* offset
* top
* left
* width
* height
* parent
*
* scroll
* top
* left
* width
* height
*/
//=>clientTop/Left/Width/Height
//1.clientWidth & clientHeight:获取当前元素可视区域的宽高(内容的宽高+左右/上下PADDING)
//=>和内容是否有溢出无关(和是否设置了OVERFLOW:HIDDEN也无关),就是我们自己设定的内容的宽高+PADDING
//=>获取当前页面一屏幕(可视区域)的宽度和高度
// document.documentElement.clientWidth || document.body.clientWidth
// document.documentElement.clientHeight || document.body.clientHeight
//2.clientTop & clientLeft:获取(上/左)边框的宽度
//3.offsetWidth & offsetHeight:在client的基础上加上border(和内容是否溢出也没有关系)
//4、scrollWidth & scrollHeight:真实内容的宽高(不一定是自己设定的值,因为可能会存在内容溢出,有内容溢出的情况下,需要把溢出的内容也算上)+ 左/上PADDING,而且是一个约等于的值 (没有内容溢出和CLIENT一样)
//=>在不同浏览器中,或者是否设置了OVERFLOW:HIDDEN都会对最后的结果产生影响,所以这个值仅仅做参考,属于约等于的值
//=>获取当前页面的真实宽高(包含溢出的部分)
// document.documentElement.scrollWidth || document.body.scrollWidth
// document.documentElement.scrollHeight || document.body.scrollHeight
//=============================
//=>通过JS盒模型属性获取值的特点
//1.获取的都是数字不带单位
//2.获取的都是整数,不会出现小数(一般都会四舍五入,尤其是获取的 偏移量)
//3.获取的结果都是复合样式值(好几个元素的样式组合在一起的值),如果只想获取单一样式值(例如:只想获取PADDING),我们的盒子模型属性就操作不了了(这不能说没有用,真实项目中,有时候我们就是需要获取组合的值来完成一些操作)
//===========[获取元素具体的某个样式值]
//1.[元素].style.xxx 操作获取
//> 只能获取所有写在元素行内上的样式(不写在行内上,不管你写没写都获取不到,真实项目中我们很少会把样式写在行内上)
//=>outer.style.width =>'' (width是写在样式表中的)
//2.获取当前元素所有经过浏览器计算的样式
//> 经过计算的样式:只要当前元素可以在页面中呈现(或者浏览器渲染它了),那么它的样式都是被计算过的
//=>不管当前样式写在哪
//=>不管你是否写了(浏览器会给元素设置一些默认样式)
/*
* 标准浏览器(IE9+)
* window.getComputedStyle([元素],[伪类,一般都写null]) 获取到当前元素所有被浏览器计算过的样式(对象)
*
* IE6~8
* [元素].currentStyle 获取经过计算的样式
*/
/*
* getCss:获取当前元素某一个样式属性值
*
* @param
* curEle[object]:当前要操作的元素
* attr[string]:当前要获取的样式属性名
*
* @return
* 获取的样式属性值
*/
let getCss = function getCss(curEle, attr) {
if ('getComputedStyle' in window) {
let val = window.getComputedStyle(curEle, null)[attr];
//=>把获取的结果去除单位(不是所有的值都能去单位的,例如:display\一些复合值都去不掉单位),只有符合 数字+单位 这种模式的结果才能基于PARSE-FLOAT去单位
let reg = /^-?\d+(\.\d+)?(px|rem|em|pt)?$/i;
reg.test(val) ? val = parseFloat(val) : null;
return val;
}
//=>throw new SyntaxError:抛出一个错误(语法错误),让浏览器崩溃,不在继续执行JS
throw new SyntaxError('您的浏览器版本过低,请升级到最新版本,谢谢配合!!');
};
console.log(getCss(outer, 'width'));