第9天-BOM和DOM

什么是DOM

文档对象模型(Document Object Model),DOM作用:可以去修改网页内容、样式、结构。 每个浏览器都会把html文档解析成dom树,就可以用相关方法和属性操作网页元素

 

DOM节点

什么是节点?节点之间的关系?

  • 根节点:html, 也叫祖先节点
  • 父节点
  • 子节点
  • 兄弟节点

节点类型

元素节点 1
文本节点 3
文档节点 9
注释节点 8

 

<div id='box'>heboan</div>
<div id='box2'><!--这是注释--></div>

<script>
    oBox = document.getElementById('box')
    console.log(oBox.nodeType) //1  元素节点
    console.log(oBox.firstChild.nodeType) //3   oBox的第一个子节点是heboan,这是个文本节点
    console.log(document.nodeType)  //9  文档节点
    
    oBox2 = document.getElementById('box2')
    console.log(oBox2.firstChild.nodeType) //8 注释节点
    
</script>
nodeType获取节点类型

节点类型使用场景

<ul id='ul1'>
    <li>1111</li>
    <li>2222</li>
    <li>3333</li>
</ul>

<script>
    //需求,点击document,修改li的背景色
    var oUl1 = document.getElementById('ul1');
    //通过节点的方式找li,childNodes返会所有子节点
    var aNodes = oUl1.childNodes
    document.onclick = function(){
        for(var i=0;i<aNodes.length;i++){
            aNodes[i].style.backgroundColor = "red"
        }
    }
    
</script>
View Code

这行上面代码是会报错的,这是为什么呢?

我们console.log(aNodes)看看,发现有7个对象,我们不是只有3个li吗???

这是因为,它识别到空格为text了

所以,这个时候,我们就可以利用节点类型进行过滤了

<script>
    //需求,点击document,修改li的背景色
    var oUl1 = document.getElementById('ul1');
    //通过节点的方式找li,childNodes返会所有子节点
    var aNodes = oUl1.childNodes
    console.log(aNodes)
    document.onclick = function(){
        for(var i=0;i<aNodes.length;i++){
            if(aNodes[i].nodeType == 1){  //判断节点类型
                aNodes[i].style.backgroundColor = "red"
            }
        }
    }
</script>
View Code

节点名的使用场景

<ul id='ul1'></ul>
<input id='ipt' />
<button id="btn">按钮</button>

<script>
    var oUl = document.getElementById('ul1');
    var oIpt = document.getElementById('ipt');
    var oBtn = document.getElementById('btn');
    
    oBtn.onclick = function(){
        //创建一个li对象
        var oLi = document.createElement('li');
        oLi.innerHTML = oIpt.value;
        oUl.appendChild(oLi);    
    }
    
    //点击新添加的li有背景变化
    oUl.onclick = function(ev){
        //当我们点击的事li才设置颜色,如果点击的是ul就不做操作
        if(ev.target.nodeName === 'LI'){
            ev.target.style.backgroundColor = "#009F95";
        }
    }
</script>
nodeName使用场景

上面的代码的如果不做nodeName判断,那么就会出现bug,点击到ul,会导致整个ul变色

 

查找元素方法

getElement系列

  getElementById :id来获取

  getElementsByClassName: 通过类名称来获取

  getElementsByTagName: 通过标签名来获取

  总结:凡是Element带s,就表示返回的事一个集合

  通过设置范围,查找相应的元素

    document.getElementById

    obj.getElementById

querySelector系列

查找 wrap下面的所有的div

<script>
    var oWrap = document.getElementById('wrap')
    var aDiv = oWrap.getElementsByTagName('div')
    console.log(aDiv)
</script>
getElement写法
<script>
    var oDiv = document.querySelectorAll('#wrap div')
    console.log(oDiv)
</script>
querySelector写法
<script>
    var oBox = document.querySelector('#box')
    console.log(oBox)
</script>
querySelector查找id为box的元素

querySelectorAll返回有的符合条件的,querySelector只返回某一个

总结:两者的区别,getElement执行效率更高,查找起来相对麻烦些

 

常用的属性

 childnodes  获取所有子节点

<div id="wrap">
    <div>111111</div>
    <div>222222</div>
    <div>333333</div>
    <div>444444</div>
</div>

<script>
    //根据方法获取节点
    var oWrap = document.getElementById('wrap')
    
    //根据属性获取节点
    console.log(oWrap.childNodes)  //获取oWrap所有的子节点
</script>
获取oWrap所有的子节点

可以看到所有子节点包含了空格(文本节点),如果只想获取所有的子元素节点,可以使用children

children  获取所有的子元素节点

<div id="wrap">
    <div>111111</div>
    <div>222222</div>
    <div>333333</div>
    <div>444444</div>
</div>

<script>
    //根据方法获取节点
    var oWrap = document.getElementById('wrap')
    
    //根据属性获取节点
    console.log(oWrap.children)  //获取oWrap所有的子节点
</script>
获取oWrap所有的子元素节点

parentNode获取父节点

<div id="wrap">
    <div>111111</div>
    <div id=box>222222</div>
    <div>333333</div>
    <div>444444</div>
</div>

<script>
    var oWrap = document.getElementById('wrap')
    
    console.log(oWrap.parentNode) //获取 oWrap的父节点
</script>
获取 oWrap的父节点

previousSibling获取上一个兄弟节点

<div id="wrap">
    <div>111111</div><div id=box>222222</div><div>333333</div><div>444444</div>
</div>

<script>
    var oBox = document.getElementById('box')
    
    console.log(oBox.previousSibling) //获取 oBox的上一个兄弟节点
</script>
获取 oBox的上一个兄弟节点

nextSibling获取下一个兄弟节点

<div id="wrap">
    <div>111111</div><div id=box>222222</div><div>333333</div><div>444444</div>
</div>

<script>
    var oBox = document.getElementById('box')
    
    console.log(oBox.nextSibling) //获取 oBox的上一个兄弟节点
</script>
获取 oBox的上一个兄弟节点

 

DOM操作

createElement 创建一个元素

appendChild   添加一个子元素在最后

<ul id='uL1'></ul>
<button id="btn">click</button>

<script>
    var oUL1 = document.getElementById('uL1')
    var oBtn = document.getElementById('btn')
    
    oBtn.onclick = function(){
        //创建一个li元素
        var oLi = document.createElement('li')
        oLi.innerHTML = 'heboan'
        
        //把创建的li元素添加到ul中
        oUL1.appendChild(oLi)        
    }        
</script>
示例

inertBefore 在一个元素钱插入元素

<ul id='uL1'>
    <li>11111</li>
    <li id=l2>22222</li>
    <li>11111</li>
</ul>
<button id="btn">click</button>

<script>
    var oUL1 = document.getElementById('uL1')
    var oBtn = document.getElementById('btn')
    var oL2 = document.getElementById('l2')
    
    oBtn.onclick = function(){
        //创建一个li元素
        var oLi = document.createElement('li')
        oLi.innerHTML = 'heboan'
        
        //在oL2元素前面插入oLi
        oUL1.insertBefore(oLi, oL2)        
    }        
</script>
insertBefore

removeChild 删除一个子元素

<ul id='uL1'>
    <li>11111</li>
    <li id=l2>22222</li>
    <li>11111</li>
</ul>
<button id="btn">click</button>

<script>
    var oUL1 = document.getElementById('uL1')
    var oBtn = document.getElementById('btn')
    var oL2 = document.getElementById('l2')
    
    oBtn.onclick = function(){
        //删除一个子元素
        oUL1.removeChild(oL2)

    }        
</script>
removeChild

 

宽、高和位置总结

鼠标位置:

  • clientX/clientY   鼠标在浏览器可视区的坐标
  • pageX/pageY: 鼠标在整个网页中的坐标

<body style="height: 3000px;">

    <script>
        document.onclick = function(ev){
            console.log(ev.clientX, ev.clientY)
            console.log('------------')
            console.log(ev.pageX, ev.pageY)
        }
    </script>
    
</body>
鼠标位置

 

offset系列

  • offsetLeft offsetTop 是相对于定位父级的坐标位置
  • offsetWidth offsetHeight 是元素实体所占的总宽高,例如:总宽度=内容 + padding +border
  • offsetParent 表示定位的父级元素
<style>
    #box{
        width: 600px;
        height: 400px;
        border: 1px solid black;
        position: relative;
        margin: 100px auto;
    }
    
    #box-inner{
        width: 50px;
        height: 60px;
        background-color: green;
        border: 5px solid deeppink;
        padding: 10px;
        position: absolute;
        left: 100px;
        top: 100px
    }
</style>

...
<body>
    
    <div id="box">
        <div id=box-inner></div>
    </div>
    
    <script>
        var oBoxInner = document.getElementById('box-inner')
        
        document.onclick = function(){
            //盒子的定位偏移量,是相对于定位父级的坐标位置
            console.log("offsetLeft:" + oBoxInner.offsetLeft) //100
            console.log("offsetTop:" + oBoxInner.offsetTop)  //100
            
            //offsetWidth表示盒子占的总宽度=border = width + padding
            console.log("offsetWidth:" + oBoxInner.offsetWidth) //80
            
            //offsetHeight表示盒子占的总宽度=border = height + padding
            console.log("offsetHeight:" + oBoxInner.offsetHeight) //90
            
            //offsetParent 表示定位的父级元素
            console.log("offsetParent:" + oBoxInner.offsetParent.id)  //打印出父级元素的id为 box
        }
    </script>
    
</body>
offset系列

 

scroll系列

  • scrollLeft和scrollTop 表示元素滚出去的距离
  • scrollWidth和scrollHeight 对象的实际内容的宽高,会随对象中内容超过可视区后而变大
<style>
    #box{
        width: 300px;
        height: 150px;
        border: 1px solid black;
        margin: 100px auto;
        padding: 10px;
        margin: 20px;
        /*表示溢出隐藏, 里面的盒子比这个盒子高,高的部分会被隐藏,从而出现滚动条*/
        overflow: auto;
    }
    
    #box-inner{
        width: 290px;
        height: 400px;
        background-color: orangered;
        margin: 0 auto;
    }
</style>
...
<body>
    
    <div id="box">
        <div id=box-inner></div>
    </div>
    
    <script>
        var oBox = document.getElementById('box')
        
        document.onclick = function(){
            //滚出去的距离
            console.log("scrollTop: " + oBox.scrollTop)
            console.log("scrollLeft: " + oBox.scrollLeft)
            
            //内部实际占的宽度和高度
            console.log("scrollWidth: " + oBox.scrollWidth)  //303
            console.log("scrollHeight: " + oBox.scrollHeight)  //420
        }
    </script>
    
</body>
sroll系列

 

可视区宽高

  • clientWidth
  • clientHeight
<style>
    #box{
        width: 300px;
        height: 200px;
        border: 1px solid black;
        padding: 10px;
    }
    
</style>
...

<body>
    
    <div id="box"></div>
    
    <script>
        var oBox = document.getElementById('box')
        
        oBox.onclick = function(){
            //可视区的宽高:包含width和padding
            console.log(this.clientWidth)   //320
            console.log(this.clientHeight)  //220
            
            //offsetWidth/offsetHeight(包含width_padding_border)
            console.log(this.offsetWidth)
            console.log(this.offsetHeight)
        }
    </script>
    
</body>
可视区宽高

client和offset区别: client不加border,offset加border

 

文档可视区宽高以及滚动距离计算(重要)

<body style="height: 2000px;">
    <script>
        //获取文档相关
        //document是一个对象,对象没有宽高,必须要获取到html元素才有宽高
        //document.documentElement 获取到的是整个html页面
        
        //1 获取文档可视区的宽高
        console.log(document.documentElement.clientWidth)
        console.log(document.documentElement.clientHeight)
        
        //2 获取页面宽高
        console.log(document.documentElement.scrollWidth)
        console.log(document.documentElement.scrollHeight)
        
        // 3如何获取滚动距离
        console.log(document.documentElement.scrollTop)
        console.log(document.documentElement.scrollLeft)
        //注意以上上问题时非常常用的,必须记住
    </script>
</body>
文档可视区宽高以及滚动距离计算
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        
        <style>
            #wrap{
                width: 100%;
                height: 500px;
                background-color: rgb(0,0,0,0.5);
                position: fixed;
                left: 0;
                top: 0;
                display: none;
            }
        
            #box{
                width: 300px;
                height: 300px;
                background-color: white;
                position: absolute;
                left: 0;
                top: 0;
                
            }
            
            h1 {
                background-color: #009F95;
                font-size: 16px;
                color: white;
            }
        </style>
    
    </head>
    
    <body style="height: 2000px;">
        <!--需求:点击按钮 弹窗遮罩-->
        <button id="btn">click</button>
        <div id="wrap">
            <div id="box">
                <h1>登录</h1>
            </div>
        </div>
        <p style="margin-top: 1500px;">11111</p>
        
        <script>
            var oBtn = document.getElementById('btn')
            var oWrap = document.getElementById('wrap')
            var oBox = document.getElementById('box')
            oBtn.onclick = function(){
                //让wrap显示
                oWrap.style.display = 'block'
                
                var pageH = document.documentElement.scrollHeight
                oWrap.style.height = pageH + 'px'
                
                //让登录box居中显示,设置left和top
                var dleft = document.documentElement.clientWidth/2 - oBox.offsetWidth/2
                var dtop =    document.documentElement.clientHeight/2 - oBox.offsetHeight/2
                //如果 dtop是负值,要重置为0
                if(dtop <0 ){
                    dtop = 0
                }
                
                oBox.style.left = dleft + 'px'
                oBox.style.top = dtop + 'px'
                
                window.onresize = function(){
                    //让登录box居中显示,设置left和top
                    var dleft = document.documentElement.clientWidth/2 - oBox.offsetWidth/2
                    var dtop =    document.documentElement.clientHeight/2 - oBox.offsetHeight/2
                    //如果 dtop是负值,要重置为0
                    if(dtop <0 ){
                        dtop = 0
                    }
                    
                    oBox.style.left = dleft + 'px'
                    oBox.style.top = dtop + 'px'
                }
                
                
            }
            oWrap.onclick = function(){
                this.style.display = 'none'
            }
        </script>
    </body>
    
</html>
应用案例

 

什么是BOM

BOM(Browse Object Model),浏览器对象模型,没有相关标准,是约定成俗的东西,定义了一些浏览器的方法和属性,大部分方法都是通过window对象来调用的,window对象是浏览器最顶层的对象。

  DOM: 操作文档

  BOM: 操作浏览器

<body>
    <button id="btn1">打开</button>
    <button id="btn2">关闭</button>

    <script>
        var oBtn1 = document.getElementById('btn1')
        var oBtn2 = document.getElementById('btn2')
        var w = null
        
        oBtn1.onclick = function(){
            //打开一个窗口,如果没有指定网址,则打开一个空白窗口
            //第2个参数,是打开窗口的方式,不写默认是新开一个窗口,self是在本页面跳转
            //返回的是新开窗口的对象
            w = open('https://www.baidu.com')
            //open('https://www.baidu.com', '_self')
        }
        
        oBtn2.onclick = function(){
            //关闭之前打开的窗口
            w.close()
        }

    </script>
</body>
open和close方法

 

BOM相关属性

<script>
    console.log(window.navigator.userAgent)
    //Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

    if(window.navigator.userAgent.indexOf("MSIE") != -1){
        alert('当前浏览器是IE')
    }else{
        alert('当前浏览器器不是IE')
    }
</script>
查看浏览器信息
//得到访问的地址
console.log(window.location.href)

//得到地址栏问号后面的东西 ?wd='xx'&age=12
console.log(window.location.search)

//得到地址栏#号后面的内容
console.log(window.location.hash)
地址栏相关

 

posted @ 2018-11-18 16:25  sellsa  阅读(167)  评论(0编辑  收藏  举报