前端技术——6——JavaScript-BOM、DOM对象

15 篇文章 0 订阅

BOM——浏览器对象,使JavaScript有能力与浏览器对话,包括Window对象、History对象、Location对象。

window对象

Window对象是内置对象,已经实例化为window,alert()即是window对象的方法,完整的写法是window.alert()。还包括:
confirm():有两个按钮,确定、取消,alert只有确定。确定返回值true,取消返回值false。
propmt():有一个文本输入框,确定返回输入框的内容,取消返回值为null。
open():打开一个新的浏览器窗口或查找一个已命名的窗口。
close():关闭浏览器窗口。
setInterval():按照指定的周期(以毫秒计)来调用函数或计算表达式,设定定时器。
clearInterval():取消由setInterval()设置的定时器。
setTimeout():在指定的毫秒数后调用函数或计算表达式。
clearTimeout():取消由setTimeout()方法设置的timeout。
scrollTo():把内容滚动到指定的坐标。

定时器举例:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text" id="clock">
<input type="button" value="begin" onclick="begin_click();">
<input type="button" value="end" onclick="end_m();">
<script>
    function mytime() {
        var date_obj = new Date();
        return date_obj.toLocaleString();
    }
    function begin_m() {
        var stime = mytime();
        var ret = document.getElementById("clock");
        ret.value = stime;
    }
   var ID1;
    function begin_click() {
        begin_m();
        ID1 = setInterval(begin_m,1000); //设置一个定时器
    }
    function end_m() {
        clearInterval(ID1);  //清除定时器
    }

</script>
</body>
</html>

运行结果:

当点击begin按钮时,在文本框中每隔1秒执行一次begin_m,即显示一次时间,按end,停止。

有一个bug,就是点击多次begin后,end就不好用了,因为每次调用setInterval(),都会生成一个新的定时器,ID1变量保存的是最后一次点击begin按钮时生成的定时器,end结束的只是最后一次的定时器,前面几次的还在运行。修改:

   var ID1;
    function begin_click() {
        if (ID1 == undefined){
            //判断是否存在定时器了,如果没有存在,生成新的定时,否则只使用已生成的
            begin_m();
            ID1 = setInterval(begin_m, 1000); //设置一个定时器
        }
    }
    function end_m() {
        clearInterval(ID1);  //清除定时器
        ID1 = undefined;  
        //清除定时器的同时,将ID1置为undefined,下次按begin时可以重新开始
    }

setTimeout使用:

History对象

三种方法:forward()、back()、go()

举例,两个页面,第一个页面点击一个连接进入第二个页面,第二个页面点击后退回到前一个页面,第一个页面再点击前进,进入第二个:

第一个页面:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="前进" onclick="func1();">
<a href="history2.html">qqqqqqqqqqqq</a>
<script>
    function func1(){
        history.forward();
    }
</script>
</body>
</html>

第二个:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="后退" onclick="func2();">
<script>
    function func2() {
        history.back();
    }
</script>
</body>
</html>

属性length,保存了访问了多少历史页面

Location对象

方法:reload(),重新加载,刷新页面的作用。

<input type=“button” value=“重载” οnclick=“history.reload();”>

DOM对象(DHTML):——Document Object Model

DOM定义了访问HTML和XML文档的标准:

W3C文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。

W3C DOM标准被分为3个不同的部分:

  • 核心DOM–针对任何结构化文档的标准模型
  • XML DOM–针对XML文档的标准模型
  • HTML DOM–针对HTML文档的标准模型

XML DOM定义了所有XML元素的对象和属性,以及访问它们的方法。

HTML DOM定义了所有HTML元素的对象和属性,以及访问它们的方法。

DOM节点

HTML文档中的所有内容都是节点(NODE):

  • 整个文档是一个文档节点(document对象)
  • 每个HTML元素是元素节点(element对象)
  • HTML元素内的文本是文本节点(text对象)
  • 每个HTML属性是属性节点(attribute对象)
  • 注释是注释节点(comment对象)

节点(NODE)对象有自身属性和导航属性:

节点(自身)属性:

  • attributes – 节点(元素)的属性节点
  • node Type – 节点类型
  • node Value – 节点值
  • node Name – 节点名称
  • innerHTML – 节点(元素)的文本值

导航属性:

  • parentNode – 节点(元素)的父节点(推荐)
  • firstChild – 节点下第一个子元素
  • lastChild – 节点下最后一个子元素
  • childNodes – 节点(元素)的子节点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="div1">
        <div>hello div</div>
        <p>hello ppp</p>
    </div>

<script>
    var ele = document.getElementById("div1");
    alert(ele);
</script>
</body>
</html>

变量el是HTMLDivElement对象。

所以找孩子的方法、属性似乎与我们想要的结果不符,很少使用。

找父节点是唯一的:

推荐使用以下属性:进行文档树导航

  • parentElement //父节点标签元素

  • children // 所有子标签

  • firstElementChild// 第一个子标签元素

  • lastElementChild //最后一个子元素标签

  • nextElementSibling // 下一个兄弟标签元素

  • previousElementSibling //上一个兄弟标签元素

    var ele = document.getElementById(“div1”);
    var ele2 = ele.firstElementChild;
    alert(ele2.nodeName); // DIV
    var ele3 = ele.lastElementChild;
    alert(ele3.nodeName); // P
    var eles4 = ele.children;
    alert(eles4); //[object HTMLCollection]是一个集合了
    alert(eles4.length); // 2
    alert(eles4[0]); //[object HTMLDivElement]
    alert(eles4[0].nodeName); //DIV
    for(var i=0;i<eles4.length;i++){
    console.log(eles4[i]);
    }
    var ele5 = document.getElementById(“div1”).firstElementChild;
    var ele6 = ele5.nextElementSibling; //找到ele5的下一个兄弟标签元素
    alert(ele6.nodeName); //就是P

访问HTML元素(节点),等同于访问节点

以不同的方式来访问HTML元素:

页面查找:

  • 通过使用getElementById()方法

  • 通过使用getElementsByTagName()方法

  • 通过使用getElementsByClassName()方法

  • 通过使用getElementsByName()方法

    Title
    hello
    hello2
    hello3

    hello p

局部查找:

先选定一个元素,然后在这个元素里查找,即这个局部就是选定的这个元素内:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="div1">hello
    <div class="div2">hello2</div>
    <div class="div3" name="abc">hello3
        <p class="ddd" name="ccc">hello inner</p>
    </div>
    <p>hello p</p>
</div>
<script>
    var ele = document.getElementsByClassName("div3");
    var ele2 = ele[0].getElementsByTagName("p"); //只在div3下找p标签,通过tag
    alert(ele2[0].innerHTML);// hello inner
    // var ele3 = ele[0].getElementById("");//不支持ID
    var ele4 = ele[0].getElementsByClassName("ddd");//通过class查找
    alert(ele4[0].innerHTML); // hello inner
    var ele5 = ele[0].getElementsByName("ccc");//不支持通过name查找
    //以上是局部查找,不支持ID和name查找
</script>
</body>
</html>

HTML DOM Event(事件)

HTML4.0新特性之一是有能力使HTML事件触发浏览器中的动作(action),比如用户点击某个HTML元素时启动一段JavaScript代码。以下属性可插入到HTML标签来定义事件动作:

  • onclick 当用户点击某个对象时调用的事件句柄
  • ondblclick 当用户双击某个对象时调用的事件句柄
  • onfocus 元素获得焦点 //光标进入输入框
  • onblur 元素失去焦点 //应用场景:表单验证,用户离开某个输入框时,代表输入完成,进行验证
  • onchange 域的内容被改变 //应用场景:用于表单元素,当元素内容被改变时触发(三级联动)
  • onkeydown 某个键盘按键被按下 //应用场景:当用户在最后一个输入框按下回车键时,表单提交。
  • onkeypress 某个键盘按键被按下并松开
  • onkeyup 某个键盘按键被松开
  • onload 一张页面或一副图像完成加载。
  • onmousedown 鼠标按钮被按下
  • onmousemove 鼠标被移动
  • onmouseout 鼠标从某个元素移开
  • onmouseover 鼠标移到某个元素之上
  • onselect 文本被选中
  • onsubmit 确认按钮被点击

事件的监听者是操作系统。

对于按键事件,keyCode属性声明了被敲击的键生成的Unicode字符码。对于keydown和keyup事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘布局相关。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="press" onkeydown="fun1(event);">
<script>
    function fun1(e) {
        alert(e.keyCode);
    }
</script>
</body>
</html>

onsubmit事件只能绑定到表单上。

绑定事件的另一种方法:

var obj = document.getElementsByClassName(“kkk”)[0];
obj.οnclick=function(){
语句;
}

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form id="id1" onsubmit="return check();">  // 这里要注意,一定要加return才行
    <input type="text" name="username">
    <input type="submit" value="submit">
</form>
<script>
    function check() {
        alert("验证失败!");
        return false;

    }
    //对于onsubmit事件的函数,需要有返回值,值为布尔型,true则提交,false则不提交

    function check(e) {
        e.preventDefault();//阻止默认动作,也可实现上面的阻止提交动作
    }
    //第二种绑定事件的方式
    var form_1 = document.getElementById("id1");
    form_1.onsubmit = function () {
        alert("shibai");
        return false;
    }
    //这种另外一种实现绑定的方式,比较常用
</script>
</body>

关于在form标签中直接使用onsubmit必须使用return的解释:

onsubmit属性就像是这个html对象的一个方法名,其值(一字符串)就是其方法体,默认返回true;
和Java一样,在该方法体中你可以写任意多个语句,包括内置函数和自定义函数,如
οnsubmit="
alert(‘haha’); // 内置函数
submitTest(); // 自定义函数
alert(this.tagName); // 用到了this关键词
…(任意多条语句)
return false;
"
就相当于
Form.prototype.onsubmit = function() {
alert(‘haha’); // 内置函数
submitTest(); // 自定义函数
alert(this.tagName); // 用到了this关键词
…(任意多条语句)
return false;
};

这样的话你就覆写了(override)其默认方法(默认返回true)
大家注意到方法体中可以用this这个关键词,这里即代表了的对象实例。
经过这样的分析后,以上情况就不难理解了:

事件传播

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #div1{
            height: 200px;
            width: 200px;
            background-color: #84a42b;
        }
        #div2{
            height: 100px;
            width: 100px;
            background-color: #336699;
        }
    </style>
</head>
<body>
<div id="div1" onclick="alert('div1');">
    <div id="div2" onclick="alert('div2');"></div>
</div>
</body>
</html>

点击div2时,会先弹出alert窗口div2,后又弹出div1,这就是事件传播。

在div2中增加:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #div1{
            height: 200px;
            width: 200px;
            background-color: #84a42b;
        }
        #div2{
            height: 100px;
            width: 100px;
            background-color: #336699;
        }
    </style>
</head>
<body>
<div id="div1" onclick="alert('div1');">
    <div id="div2" onclick="f1(event);"></div>
</div>
<script>
    function f1(e) {
        alert("div2");
        e.stopPropagation();  //阻止事件传播
    }
</script>
</body>
</html>

增删改查,node的CURD

增:
createElement(name) 创建元素
appendChild() 将元素添加

删:
获得要删除的元素,获得它的父元素,使用removeChild()方法删除

改:
第一种方式:使用上面增和删结合完成修改
第二种方式:使用setAttribute()方法修改属性,使用innerHTML属性修改元素的内容

查:
使用之前的方法,如document的getElementsBy。。。方法

修改HTML DOM包括以下的方面:

  • 改变HTML内容:最简单方法是使用innerHTML,innerText

  • 改变CSS样式:document.getElementsBy。。。("").style.color=“red”;

  • 改变HTML属性:elementNode.setAttribute(name,value)、elementNode.getAttribute(name)<---------------->elementNode.value(DHTML)

  • 创建新的HTML元素:createElement(name)

  • 删除已有的HTML元素:elementNode.removeChild(node)

  • 关于class的操作:elementNode.className、elementNode.classList.add、elementNode.classList.remove

    Title
    hello div2

    hello ppp

上面的字体变大变小有点问题,修改如下:

 function big() {
        var ele = document.getElementById("div2");
        // ele.className="big1";
        ele.classList.remove("small1");
        ele.classList.add("big1");
    }
    function small() {
        var ele = document.getElementById("div2");
        // ele.className="small1";
        ele.classList.remove("big1");
        ele.classList.add("small1");
    }

使用classList,只是添加,并且是添加到class列表中,所以添加后会一直存在,改变时需要删除。

关于Event对象:

Event对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。事件通常与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经创建好了,并且会在事件函数被调用时传递给事件函数,我们获得仅仅需要接收一下即可。

改变HTML属性:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="div1"> hello div1</div>
<input id="add" type="button" value="add">

<script>
    var ele = document.getElementById("add");
    ele.onclick = function () {
        var ele1 = document.getElementsByClassName("div1")[0];
        var img = document.createElement("img");
        img.setAttribute("src","1.jpg");
        // img.src="1.jpg";   //第二种设置元素属性方式,是DHTML语法
        ele1.appendChild(img);
    }
</script>
</body>
</html>

关于a标签的补充:

<a href=“javascript:viod(0)” οnclick=“del(this)”>hello
协议名:协议内容,将a标签自身功能阉割,取消跳转功能。

this参数:代表调用函数的元素本身。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>hello1
    <div onclick="show(this);">hello2</div>
<!--    //this代表<div onclick="show(this);">hello2</div>这个元素-->
    <div>hello3</div>
</div>
<script>
    function show(s) {
        console.log(s.innerHTML); //hello2
    }
</script>
</body>
</html>

模态对话框

点击一个按钮,弹出一个对话框,背景变暗,除弹出的对话框,其他无法操作:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: auto 0;
        }
        #div1{
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 2000px;
            background-color: #b4b4b4;
            z-index: 1000;
        }
        #div2{
            position: fixed;
            width: 100%;
            height: 2000px;
            background-color: red;
            opacity: 0.3;
            z-index: 1001;
        }
        #div3{
            height: 300px;
            width: 300px;
            background-color: #2459a2;
            position: absolute;
            top:50%;
            left: 50%;
            z-index: 1002;
            margin-left: -150px;
            margin-top: -150px;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
<div id="div1">
    <input type="button" value="click" onclick="show();">
</div>
<div id="div2" class="div hide"></div>
<div id="div3" class="div hide">
    <input type="button" value="cancel" onclick="cancel();">
</div>
<script>
    function show() {
        var div_t = document.getElementsByClassName("div");
        for(var i=0;i<div_t.length;i++){
            div_t[i].classList.remove("hide");
        }
    }
    function cancel() {
        var div_t = document.getElementsByClassName("div");
        for(var i=0;i<div_t.length;i++){
            div_t[i].classList.add("hide");
        }
    }
</script>
</body>
</html>

结果画面:

二级联动:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<select id="province" onchange="func1(this);">

</select>

<select id="city">

</select>

<script>
    var data_p={"北京":["朝阳","海淀"],"山东":["济南","烟台"],"河北":["石家庄","张家口"]}
    //数据可以从数据库提取,以后动态形成
    var pro = document.getElementById("province");
    var city_t = document.getElementById("city");
    for(var i in data_p){
        var option_pro = document.createElement("option");
        option_pro.innerHTML=i;
        pro.appendChild(option_pro);
    }
    function func1(s) {
        var pro_n = (s.options[s.selectedIndex]).innerHTML;
        // for(var j=0;j<city_t.children.length;j++){
        //     city_t.removeChild(city_t.children[j--]);
        // }//循环删除city下的option选项,要注意这个算法,options是动态的
        //删除一个孩子,下一次判断时,即j<city_t.children.length;,Length减1
        //实际还可以写成city_t.removeChild(city_t.children[0]);j=j-1

        city_t.options.length = 0;
        //在选择其他选项前,要把当前的选项清空,此方法简洁
        for(var k in data_p[pro_n]){
            var option_city = document.createElement("option");
            option_city.innerHTML=data_p[pro_n][k];
            city_t.appendChild(option_city);
        }

    }
    //参数s是this对象,代表当前操作的元素,这里即id为province的select元素
    //this.options即s.options是select下的所有option元素,相当于选select的所有child元素
    //selectedIndex保存了本次选择的option项的索引,最后innerHTML取出省份名称

    // function func1() {
    //     var pro = document.getElementById("province");
    //     console.log(pro.value);//显示选择项的value值
    // }

</script>
</body>
</html>

左右选择:

html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box_l,#choice,#box_r{
            display: inline-block;
        }
        #choice{
            margin-bottom: 80px;
        }
    </style>
</head>
<body>
<div id="box_l">
    <select id="sele_left" multiple size="10">
        <option>选项1</option>
        <option>选项2</option>
        <option>选项3</option>
        <option>选项4</option>
        <option>选项5</option>
        <option>选项6</option>
    </select>
</div>
<div id="choice">
    <input type="button" value="------->" onclick="addsele();"><br>
    <input type="button" value="====>" onclick="addall();"><br>
    <input type="button" value="<-------" onclick="removesele();"><br>
    <input type="button" value="<====" onclick="removeall();">
</div>
<div id="box_r">
    <select multiple size="10" id="sele_right">
        <option>选项7</option>
    </select>
</div>
<script>
    var right_se = document.getElementById("sele_right");
    var left_se = document.getElementById("sele_left");
    function addsele() {
        var op = left_se.children;
        for(var i = 0;i<op.length;i++){
            if(op[i].selected==true){
                op[i].selected=false;
                right_se.appendChild(op[i]);
                i--;  //这一步的逻辑很重要,类似上例的
                //右边添加的同时,左边的同时删除。
                //appendChild是从一个元素向另一个元素中移动元素,注意是移动
            }
        }
    }
    function addall() {
        var op = left_se.children;
        for (var i=0;i<op.length;i++){
            op[i].selected = false;
            right_se.appendChild(op[i]);
            i--;
        }
    }
    function removesele() {
        var op = right_se.children;
        for(var i=0;i<op.length;i++){
            if(op[i].selected == true){
                op[i].selected=false;
                left_se.appendChild(op[i]);
                i--;
            }
        }
    }
    function removeall() {
        var op = right_se.children;
        for (var i=0;i<op.length;i++){
            op[i].selected = false;
            left_se.appendChild(op[i]);
            i--;
        }
    }
</script>
</body>
</html>

正反选:实现如下功能,可以一个一个单选,可以反选,可以全选

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="全选" onclick="seleall();">
<input type="button" value="取消" onclick="cancelall();">
<input type="button" value="反选" onclick="reverseall();">
<hr>
<table border="1px" class="box">
    <tr>
        <td><input type="checkbox"></td>
        <td>1111111</td>
        <td>2222222</td>
        <td>3333333</td>
    </tr>
        <tr>
        <td><input type="checkbox"></td>
        <td>1111111</td>
        <td>2222222</td>
        <td>3333333</td>
    </tr>
        <tr>
        <td><input type="checkbox"></td>
        <td>1111111</td>
        <td>2222222</td>
        <td>3333333</td>
    </tr>
</table>
<script>
    function seleall() {
        var t1 = document.getElementsByClassName("box")[0];
        var inputs = t1.children[0].getElementsByTagName("input"); //属于局部查找
        //对于table标签,它的孩子是tbody,虽然我们没写,但浏览器会增加
        for(var i in inputs){
            inputs[i].checked=true;
        }
    }
    function cancelall() {
        var t1 = document.getElementsByClassName("box")[0];
        var inputs = t1.children[0].getElementsByTagName("input");
        for(var i in inputs){
            inputs[i].checked=false;
        }
    }
    function reverseall() {
        var t1 = document.getElementsByClassName("box")[0];
        var inputs = t1.children[0].getElementsByTagName("input");
        for(var i in inputs){
            if(inputs[i].checked){
                inputs[i].checked = false;
            }else{
                inputs[i].checked = true;
            }
        }
    }
</script>
</body>
</html>

js作用域

js作用域类似python,if、while等控制语句并没有自己的作用域,而函数是有自己的作用域;

嵌套函数的作用域,先内后外。

闭包:

    var city = "bj";
    function func() {
        var city = "sh";
        function  inner() {
            // var city = "LF";
            console.log(city);
        }
        return inner;
    }
    var ret = func();
    ret();  //inner中的city=“LF”注释掉,这里结果就是sh,闭包,不注释,就是LF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值