跳转至

JavaScript04

11.DOM02

11.3HTML-DOM文档说明

11.3.1基本介绍

在HTML DOM(文档对象模型)中,每个部分都是节点

1)文档本身是文档节点

2)所有HTML元素是元素节点

3)所有HTML属性是属性节点

4)HTML元素内的文本是文本节点

5)注释是注释节点

11.3.2节点属性方法一览

HTML DOM Element 对象 (w3school.com.cn)

HTML DOM Document 对象 (w3school.com.cn)

11.3.3节点常用方法和属性

  • 节点常用方法

  • 通过具体的元素节点调用getElementByTagName()方法,获取当前节点的指定标签名孩子节点

  • appendChild(oChildNode)方法,可以添加一个节点,oChildNode是要添加的孩子节点

  • 节点常用属性

  • childNodes属性,获取当前节点的所有子节点

  • firstChild属性,获取当前节点的第一个子节点
  • lastChild属性,获取当前节点的最后一个子节点
  • parentNode属性,获取当前节点的父节点
  • nextSibling属性,获取当前节点的下一个节点 (Sibling:兄弟)
  • previousSibling属性,获取当前节点的上一个节点 (Sibling:兄弟)
  • className属性,用于获取或设置标签的class属性值
  • innerHTML属性,用于获取/设置起始标签和结束标签中的内容
  • innerText属性,用于获取/设置起始标签和结束标签中的文本

idea快捷键:ctrl+home 直接到页面最上面 ctrl+end 直接到页面最下面

11.3.4节点方法应用实例

  • 获取option节点
  • 按照name获取节点
  • 获取指定dom对象下的子节点
  • 获取第一个节点
  • 获取父节点
  • 获取兄弟节点
  • 设置文本域内容

例子

需求:完成功能(如图),点击右侧的按钮,可以得到对应的节点

image-20221102163826843

@CHARSET "UTF-8";

body {
    width: 800px;
    margin-left: auto;
    margin-right: auto;
}

button {
    width: 200px;
    margin-bottom: 10px;
    text-align: left;
}

#btnList {
    float: left;
}

#total {
    width: 450px;
    float: left;
}

ul {
    list-style-type: none;
    margin: 0px;
    padding: 0px;
}

.inner li {
    border-style: solid;
    border-width: 1px;
    padding: 5px;
    margin: 5px;
    float: left;
}

.inner {
    width: 400px;

    border-width: 1px;
    margin-bottom: 10px;
    padding: 10px;
    float: left;
}

dom编程的步骤就是:先拿到dom对象,然后通过dom对象的属性和方法进行操作。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>演示 HTML DOM 相关方法</title>
    <link rel="stylesheet" type="text/css" href="style/css.css"/>
    <script type="text/javascript">
        //使用动态绑定
        window.onload = function () {

            //1.查找id=java的节点
            //先获取btn01的dom对象
            var btn01 = document.getElementById("btn01");
            btn01.onclick = function () {
                //查找id=java的节点
                var java = document.getElementById("java");
                alert("java节点文本=" + java.innerText);
            }

            //2.查找所有option节点
            var btn02 = document.getElementById("btn02");
            btn02.onclick = function () {
                var options = document.getElementsByTagName("option");
                //alert(options);//[object HTMLCollection]
                for (var i = 0; i < options.length; i++) {
                    alert(options[i].innerText)
                }
            }

            //3.查找name=sport的节点
            //通过id名获取--->getElementById方法
            // 通过name获取--->getElementsByName方法
            // 通过元素标签名获取--->getElementsByTagName方法
            var btn03 = document.getElementById("btn03");
            btn03.onclick = function () {
                var sports = document.getElementsByName("sport");
                //alert(sports)//[object NodeList]
                for (var i = 0; i < sports.length; i++) {
                    alert("运动=" + sports[i].value);
                }
            }

            //4.查找 id=language下所有li节点
            //指定某一个元素下面的子元素
            var btn04 = document.getElementById("btn04");
            btn04.onclick = function () {
                //第一个document指的是整个html文档的document对象,
                // 在该对象中获取id为language的标签dom对象

                //第二个document指的是获取到的language的dom对象,
                // 在language的标签dom对象中再获取标签名为li的dom对象
                var lis = document.getElementById("language").getElementsByTagName("li");
                for (var i = 0; i < lis.length; i++) {
                    alert(lis[i].innerText);
                    //如果要取标签的value属性就用value,如果要取标签之间的文本值就用innerText
                }
            }

            //5.返回 id=sel01 的所有子节点(3种方法)
            var btn05 = document.getElementById("btn05");
            btn05.onclick = function () {
                //第一种方法
                //var option = document.getElementById("sel01").getElementsByTagName("option");

                //第二种:用childNodes拿到sel01标签下的所有子节点
                //如果使用这种方法,除了标签的内容之外,文本也会全部获取,需要条件过滤
                //alert(document.getElementById("sel01").childNodes.length)//11=>object Text+HTMLOptionElement
                //1.如果使用的是 document.getElementById("sel01").childNodes
                // 获取的是object text和object HTMLOptionElement
                //2.如果如果不希望得到text对象,需要将所有的内容放在一行(这样就没有换行)
                var childNodes = document.getElementById("sel01").childNodes;
                for (var i = 0; i < childNodes.length; i++) {
                    if (childNodes[i].selected) { //undefined,null,NaN,0,""都代表假
                        alert(i + " " + childNodes[i].innerText);
                    }
                }
                alert("=======================================");
                //第三种方式:
                //还有一个以前的方法
                //1.sel01是object HTMLSelectElement=>本身就具有集合的特点,直接进行遍历也是支持的
                var sel01 = document.getElementById("sel01");
                alert(sel01)//[object HTMLSelectElement]
                for (var i = 0; i < sel01.length; i++) {
                    alert(sel01[i].innerText)//直接得到option节点了
                }
            }

            //6.返回 id=sel01 的第一个子节点
            var btn06 = document.getElementById("btn06");
            btn06.onclick = function () {
                //这里使用上面的三种方法都可以,之外还有一种方法:直接使用属性firstChild
                var sel01 = document.getElementById("sel01");
                alert(sel01.firstChild);//拿到的节点是按照 .childNodes得到的第一个子节点
                alert(sel01[0]);//直接是得到第一个option节点,HTMLOptionElement
            }

            //7.返回 id=java 的父节点
            var btn07 = document.getElementById("btn07");
            btn07.onclick = function () {
                var java = document.getElementById("java");
                alert("java的父节点=" + java.parentNode);//[object HTMLUListElement]
                alert("语言=" + java.parentNode.innerText);
            }

            //8.返回 id=ct 的前后兄弟节点
            var btn08 = document.getElementById("btn08");
            btn08.onclick = function () {
                var ct = document.getElementById("ct");
                //注意:和前面的理解一样,节点不仅仅包括标签节点,还有节点之间的分割符之类的节点
                alert(ct.previousSibling.innerText)//[object Text],输出undefined
                alert(ct.previousSibling.previousSibling.innerText)//艳红
                alert(ct.nextSibling)//[object Text],输出undefined
                alert(ct.nextSibling.nextSibling.innerText)//春花
            }

            //9.读取 id=ct 的 value 属性值
            var btn09 = document.getElementById("btn09");
            btn09.onclick = function () {
                var ct = document.getElementById("ct");
                alert(ct.value);
            }

            //10.设置#person 的文本域
            var btn010 = document.getElementById("btn010");
            btn10.onclick = function () {
                var person = document.getElementById("person");
                person.innerText = "这是修改后的介绍";
            }

        }
    </script>
</head>
<body>
<div id="total">
    <div class="inner">
        <P>
            你会的运动项目:
        </P>
        <input type="checkbox" name="sport" value="zq" checked="checked">足球
        <input type="checkbox" name="sport" value="tq">台球
        <input type="checkbox" name="sport" value="ppq">乒乓球 <br/>
        <hr/>
        <P>
            你当前女友是谁:
        </P>
        <select id="sel01">
            <option>---女友---</option>
            <option>艳红</option>
            <option id="ct" value="春桃菇凉">春桃</option>
            <option>春花</option>
            <option>桃红</option>
        </select>
        <hr/>
        <p>
            你的编程语言?
        </p>
        <ul id="language">
            <li id="java">Java</li>
            <li>PHP</li>
            <li>C++</li>
            <li>Python</li>
        </ul>
        <br>
        <br>
        <hr/>
        <p>
            个人介绍:
        </p>
        <textarea name="person" id="person">个人介绍</textarea>
    </div>
</div>
<div id="btnList">
    <div>
        <button id="btn01">查找 id=java 节点</button>
    </div>
    <div>
        <button id="btn02">查找所有 option 节点</button>
    </div>
    <div>
        <button id="btn03">查找 name=sport 的节点</button>
    </div>
    <div>
        <button id="btn04">查找 id=language下所有li节点</button>
    </div>
    <div>
        <button id="btn05">返回 id=sel01 的所有子节点</button>
    </div>
    <div>
        <button id="btn06">返回 id=sel01 的第一个子节点</button>
    </div>
    <div>
        <button id="btn07">返回 id=java 的父节点</button>
    </div>
    <div>
        <button id="btn08">返回 id=ct 的前后兄弟节点</button>
    </div>
    <div>
        <button id="btn09">读取 id=ct 的 value 属性值</button>
    </div>
    <div>
        <button id="btn10">设置#person 的文本域</button>
    </div>
</div>
</body>
</html>

11.3.5练习-乌龟吃鸡游戏

需求:如下图,有四个按钮,点击不同方向的按钮,乌龟向对应的方向移动;(假设鸡不会移动)当乌龟移动碰撞到鸡时,游戏结束,弹出提示框,提示信息为“乌龟好厉害呀~”。

按照上述要求,完成游戏的js编写。

image-20221102193425668

思路:

  1. 先把乌龟和公鸡和控制的表格,显示在网页

  2. 分析如何让乌龟动起来:

2.1先拿到id=wugui的dom对象

2.2获取wugui.style.left和wugui.style.top的值,通过修改就可以让乌龟动起来

2.3给四个按钮绑定onclick事件(这里用静态绑定)

  1. 代码实现让乌龟动起来:

3.1向上走wugui.style.top减小

3.2向下走wugui.style.top变大

3.3向左走wugui.style.left 减小

3.4向右走wugui.style.left变大

  1. 分析如何判断乌龟和公鸡碰撞

image-20221102221239556

4.1 得到乌龟和公鸡图片左上角的距离,记为纵向距离y

(1)如果乌龟在公鸡的**上**面,当 y< 乌龟图片的高度时,说明两者可能在纵向上发生重叠,使用yy记录

(2)如果乌龟在公鸡的**下**面,当y < 公鸡图片的高度时,说明两者可能在纵向上发生重叠,使用yy记录

4.2 得到乌龟和公鸡图片左上角的距离,记为横向距离x

(1)如果乌龟在公鸡的**左**边,当 x < 乌龟图片的宽度时,说明两者可能在横向上发生重叠,使用xx记录

(2)如果乌龟在公鸡的**右**边,当 x < 公鸡图片的宽度时,说明两者可能在横向上发生重叠,使用xx记录

4.3 如果xx和yy同时为真,说明一定发生了碰撞

  1. 代码判断乌龟和公鸡碰撞,并给出提示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>乌龟吃鸡</title>
    <script type="text/javascript">
        //定义公鸡的坐标(指图片的左上角)
        var cock_top = 200;
        var cock_left = 200;
        //定义乌龟的高度和宽度
        var wugui_height = 67;
        var wugui_width = 94;
        //定义公鸡的高度和宽度
        var cock_height = 73;
        var cock_width = 76;

        //编程思想,技巧-->不知道是什么就输出,或者日志,或者debug
        //编程技巧2:在不确定的情况下,可以输出看看
        function move(obj) {
            //alert(obj.value);
            //1.拿到wugui的dom对象
            var wugui = document.getElementById("wugui");

            //2.获取wugui.style.left和wugui.style.top的值,通过修改就可以让乌龟动起来
            var wugui_left = wugui.style.left;
            var wugui_top = wugui.style.top;
            //alert(wugui_left);//100px--字符串
            //alert(wugui_top);//120px--字符串

            //3.分析:wugui_left和wugui_top是string:‘100px’,要将其转成number类型
            //3.1首先截取出字符串的数字部分--从下标为0开始截取,到p字符的前一个位置截止
            //3.2将字符串转为number类型--parseInt() 解析一个字符串并返回一个整数。
            wugui_left = parseInt(wugui_left.substring(0, wugui_left.indexOf("p")));
            wugui_top = parseInt(wugui_top.substring(0, wugui_top.indexOf("p")));
            //alert(typeof wugui_left+wugui_left)//number

            //4.根据obj的val来进行上下左右的处理
            if ("向上走" == obj.value) {
                wugui_top -= 5;
                wugui.style.top = wugui_top + "px";
            } else if ("向下走" == obj.value) {
                wugui_top += 5;
                wugui.style.top = wugui_top + "px";
            } else if ("向左走" == obj.value) {
                wugui_left -= 5;
                wugui.style.left = wugui_left + "px";
            } else {
                wugui_left += 5;
                wugui.style.left = wugui_left + "px";
            }

            /*完成碰撞检测:
            4.1 得到乌龟和公鸡图片左上角的距离,记为纵向距离y
            (1)如果乌龟在公鸡的上面,当 y < 乌龟图片的高度时,说明两者可能在纵向上发生重叠,用yy记录
            (2)如果乌龟在公鸡的下面,当 y < 公鸡图片的高度时,说明两者可能在纵向上发生重叠,用yy记录
            4.2 得到乌龟和公鸡图片左上角的距离,记为横向距离x
            (1)如果乌龟在公鸡的左边,当 x < 乌龟图片的宽度时,说明两者可能在横向上发生重叠,用xx记录
            (2)如果乌龟在公鸡的右边,当 x < 公鸡图片的宽度时,说明两者可能在横向上发生重叠,用xx记录
            4.3 如果xx和yy同时为真,说明一定发生了碰撞
            */
            //纵向距离y
            var y = Math.abs(wugui_top - cock_top);
            //横向距离x
            var x = Math.abs(wugui_left - cock_left);
            var yy = 0;//默认纵向没有重叠
            var xx = 0;//默认横向没有重叠

            //通过判断乌龟和公鸡图片左上方坐标和整个页面左上方的距离来判断图片的相对位置
            //如果乌龟在公鸡的上面,当 y < 乌龟图片的高度时,说明两者可能在纵向上发生重叠,使用yy记录
            //如果乌龟在公鸡的下面,当 y < 公鸡图片的高度时,说明两者可能在纵向上发生重叠,使用yy记录
            if (wugui_top < cock_top) {//乌龟在公鸡的上面
                if (y < wugui_height) {//当 y < 乌龟图片的高度时
                    yy = 1;
                }
            } else {//乌龟在公鸡下
                if (y < cock_height) {//当 y < 公鸡图片的高度时
                    yy = 1;
                }
            }

            //如果乌龟在公鸡的左边,当 x < 乌龟图片的宽度时,说明两者可能在横向上发生重叠,使用xx记录
            //如果乌龟在公鸡的右边,当 x < 公鸡图片的宽度时,说明两者可能在横向上发生重叠,使用xx记录
            if (wugui_left < cock_left) {//乌龟在公鸡的左边
                if (x < wugui_width) {//当 x < 乌龟图片的宽度时
                    xx = 1;
                }
            } else {//乌龟在公鸡右边
                if (x < cock_width) {//当 x < 公鸡图片的宽度时
                    xx = 1;
                }
            }

            //如果xx和yy同时为真,说明一定发生了碰撞
            if (xx && yy) {
                alert("乌龟好厉害呀~");
                //把乌龟放到原来的位置
                wugui.style.left = "100px";
                wugui.style.top = "120px";
            }

        }
    </script>
</head>
<body>
<table border="1">
    <tr>
        <td></td>
        <td>
            <!--1.this指的是点击的button,而且是一个dom对象
                2.因此可以获取使用属性和方法-->
            <input type="button" value="向上走" onclick="move(this)"/>
        </td>
        <td></td>
    </tr>
    <tr>
        <td>
            <input type="button" value="向左走" onclick="move(this)"/>
        </td>
        <td></td>
        <td>
            <input type="button" value="向右走" onclick="move(this)"/>
        </td>
    </tr>
    <tr>
        <td></td>
        <td>
            <input type="button" value="向下走" onclick="move(this)"/>
        </td>
        <td></td>
    </tr>
</table>
<!--    1.style的position: absolute 表示绝对定位,参照的点是展示页面的左上角
        2.left: 100px 表示图片距离窗口原点的横坐标距离
        3.top: 120px  表示图片距离窗口原点的纵坐标距离
        4.针对图片而言,定位的点是图片的左上角
-->
<div id="wugui" style="position: absolute;left: 100px;top: 120px;">
    <!--把乌龟放在一个div-->
    <img src="imgs/1.bmp" border="1" alt=""/>
</div>

<div id="cock" style="left: 200px;position: absolute;top: 200px">
    <!--把鸡放在一个div-->
    <img src="imgs/2.bmp" border="1" alt=""/>
</div>
</body>
</html>