【DOM】了解HTML DOM常用对象: 对常用元素的简化操作_05

目录

一. HTML DOM常用对象: 对常用元素的简化操作

1. img元素: 唯一的简化,就是创建img时

2. table元素: 逐级管理的方式

       (1). table管着行分组

       (2).行分组管着行:

       (3). 行管着格

       (4). 示例: 使用HTML DOM简化动态生成表格,并实现删除行

3. form元素

⬛总结: DOM 5件事: 增删改查+事件绑定:


【前文回顾】👉 DOM操作之如何添加、删除、替换元素_04 


一. HTML DOM常用对象: 对常用元素的简化操作

1. img元素: 唯一的简化,就是创建img时

         (1). var img元素=new Image();

         (2). 旧js中: var img元素=document.createElement("img");

     (3).强调: 常用的DOM元素中,只有img元素能用new创建。其余元素都只能用document.createElement()创建。

2. table元素: 逐级管理的方式

       (1). table管着行分组

         a. table可以创建行分组

                 1). var thead=table.createTHead(); //相当于旧js两句话

                         旧js: var thead=document.createElement("thead");//即创建

                                 table.appendChild(thead);//又添加

                 2). var tbody=table.createTBody(); //相当于旧js两句话

                 3). var tfoot=table.createTFoot(); //相当于旧js两句话

         b. table可以删除行分组

                  1). table.deleteTHead();

                  2). table.deleteTFoot();

         c. table可以获取行分组

                  1). table.tHead

                  2). table.tFoot

                  3). table.tBodies[i]

                  因为HTML标准中规定,其实一个table中可以有多个tbody。HTML DOM就将多个tbody集中保存在一个table.tBodies集合中。通过下标方式,访问某一个tBody。正是因为一个table下可以有多个tBody,所以table是没有deleteTBody()函数的,因为不知道该删除哪一个。

       (2). 行分组管着行

         a. 行分组可以添加行:

                  1).  var tr=行分组.insertRow(i); //一个函数干2件事

                  2). 意为: 先创建一个新行对象,再将新行对象添加到行分组中i位置。

                  3). 大概相当于旧js中:

                          var tr=document.createElement("tr");

                          行分组.appendChild(tr);

                  4). 固定套路:

                  i. 在当前行分组末尾追加新行: var tr=行分组.insertRow()//默认结尾

                  ii. 在当前行分组开头插入新行: var tr=行分组.insertRow(0)

         b. 行分组可以删除行:

                  1). 行分组.deleteRow(i)

                  2). 意为: 删除当前行分组内的第i行

                  3). 坑: 如果deleteRow.前使用行分组删除行时,则下标必须使用行在行分组内的相对下标位置!

                  4). 问题: 如果用户随便点击一行中的删除按钮,我们虽然可以根据按钮逐级向上找到父元素tr对象。但是,依然不知道用户点的这一行在整个行分组内是第几行。如果不知道下标,就无法删除当前行。

                  5). 解决: 其实每个行对象身上都自动就有一个属性rowIndex。记录着当前行对象在整个表中的下标位置。

                  6). 坑: 行对象的rowIndex属性记录的是行在整个表中的下标位置,不是在行分组内的相对位置。而受到表头行的影响,表体中的行的rowIndex值比行在行分组内的相对位置都要大!如果使用行分组作为主语,使用rowIndex作为删除行的参数值,结果实际删除的行一定是原本要删除行的下一行!

                  7). 解决: 今后要想删除任意一行,不要用行分组作为主语,而应该用table作为主语:

                  table.deleteRow(tr.rowIndex)

                 因为主语变成了table,所以参数值刚好也是行在整个table中的下标位置,参数与主语配套了!

         c. 行分组可以获取行

         行分组.rows[i] //行分组下的所有行对象都集中保存在名为rows的集合中

       (3). 行管着格

         a. 行可以添加格:

                  1). var 格对象=行.insertCell()//末尾插入!

                                                 插入 格

                  2). 意为: 先创建一个td对象,再将td对象追加到行中

         b. 行可以删除格:

                  行.deleteCell(i) //删除行中下标为i的一个单元格

         c. 行可以获取格:

                  行.cells[i] //行中的所有格对象已经被提前保存在了名为cells的集合中

       (4). 示例: 使用HTML DOM简化动态生成表格,并实现删除行

         1_createTable3_delete.html

<!DOCTYPE html>
<html>
  <head>
    <title>动态创建表格</title>
    <meta charset="utf-8" />
    <style>
      table {
        width: 600px;
        border-collapse: collapse;
        text-align: center;
      }

      td,
      th {
        border: 1px solid #ccc;
      }
    </style>
  </head>

  <body>
    <div id="data">
      <table>
        <thead>
          <tr>
            <th>ename</th>
            <th>salary</th>
            <th>age</th>
            <th></th>
          </tr>
        </thead>
      </table>
    </div>
    <script>
      var json = [
        { ename: "Tom", salary: 11000, age: 25 },
        { ename: "John", salary: 13000, age: 28 },
        { ename: "Mary", salary: 12000, age: 25 },
      ];

      var table = document.querySelector("#data>table");

      //创建tbody
      var tbody = document.createElement("tbody");

      //遍历json数组中每个员工对象
      for (var emp of json) {
        //每遍历一个员工对象,就要创建tr,添加到tbody下
        //每次都在末尾追加新行
        var tr = tbody.insertRow();
        //遍历当前员工对象中每个属性
        for (var key in emp) {
          //每遍历一个属性,就创建一个td,添加到tr下
          // var td=document.createElement("td");
          // tr.appendChild(td);
          var td = tr.insertCell();
          //设置当前td的内容为当前员工对象emp的当前属性值
          //对象底层的原理: js中对象底层其实也是一个关联数组
          td.innerHTML = emp[key]; //对象[变量或表达式]
        }
        //除了遍历当前对象的每个属性添加的数据格之外,额外再多添加一个格
        // var td=document.createElement("td");
        // tr.appendChild(td);
        var td = tr.insertCell();
        //每个td中要再添加一个按钮
        var btn = document.createElement("button");
        btn.innerHTML = "×";
        td.appendChild(btn);
        //为每个删除按钮绑定单击事件
        btn.onclick = function () {
          //根据当前点的按钮逐级找到当期要删除的行
          var tr =
            this.parentElement.parentElement; //td //tr
          //获取当前行中第一个td的内容
          // var ename=tr.children[0].innerHTML;
          var ename = tr.cells[0].innerHTML;
          //先跟用户确认是否删除
          var result = confirm(`是否继续删除 ${ename} 吗?`);
          //只有用户点确定,确认继续删除时,才执行删除操作
          if (result == true) {
            //删除table中一行的标准做法
            table.deleteRow(tr.rowIndex);
          } //否则如果用户点取消,说明用于反悔了!就什么也不做!
        };
      }

      //最后在查找table,将tbody一次性装入table中
      //只需要一次重绘页面即可!

      table.appendChild(tbody);
    </script>
  </body>
</html>

运行结果: 


🌱 扩展:对象底层的原理:
 

◼️对象底层的原理: js中对象底层其实也是一个关联数组。——整个js内存中,一切都是关联数组!


👉1). 都是保存的"名值对儿"的集合
 

👉2). 其实无论访问数组的元素,还是访问对象的成员,都可以用["下标名"]方式访问。只不过,如果属性名是自定义字符串,就可简写为".属性名"方式
 

➡️ 如果我们写".属性名"会被自动翻译["属性名"]
 

➡️ 总结: 今后,如果要访问的属性名是写死的固定不变的,既可以用[""],又可以用.
 

➡️ 但是, 今后,要访问的属性名来自于变量或动态拼接生成,不是固定的,只能用[变量或表达式],还不能加""

3. form元素

     (1). 获取<form>时: document已经将网页中的所有<form>元素,都集中保存在了document.forms集合中,可通过下标方式访问网页中某一个<form>

                  document.forms[i]

         (2). 还可以进一步简化获取<form>内的各种表单元素:

         a. 标准: form对象已经将表单中所有的表单元素都集中保存在了名为elements的集合中。

         var 一个表单元素=form对象.elements[i/name/id]

         b. 更简写: 如果要找的表单元素有name属性,可以直接

         form对象.name名

         (3). 自动获得焦点: 表单元素.focus()

         (4). 示例: 使用HTML DOM简写带样式的表单验证:

         0_valiWithCss.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>实现带样式的表单验证</title>
    <style>
      table {
        width: 700px;
      }

      td:first-child {
        width: 60px;
      }

      td:nth-child(2) {
        width: 200px;
      }

      /*IE*/
      td:first-child + td {
        width: 200px;
      }

      td span {
        color: red;
      }

      .vali_info {
        display: none;
      }

      .txt_focus {
        border-top: 2px solid black;
        border-left: 2px solid black;
      }

      .vali_success,
      .vali_fail {
        background-repeat: no-repeat;
        background-position: left center;
        display: block;
      }
      /*如果验证文本框中的内容通过,则修改文本框旁边的div的class为vali_success,文本框旁边的div就变成了验证通过的样式!*/
      .vali_success {
        background-image: url("images/ok.png");
        padding-left: 20px;
        width: 0px;
        height: 20px;
        overflow: hidden;
      }
      /*当验证文本框的内容没通过,则修改文本框旁边的div的class为vali_fail,就能让文本框旁边的div变成验证失败的样子*/
      .vali_fail {
        background-image: url("images/err.png");
        border: 1px solid red;
        background-color: #ddd;
        color: Red;
        padding-left: 30px;
      }
    </style>
  </head>

  <body>
    <form id="form1">
      <h2>增加管理员</h2>
      <table>
        <tr>
          <td>姓名:</td>
          <td>
            <input name="username" />
            <span>*</span>
          </td>
          <td>
            <div class="vali_info">10个字符以内的字母、数字或下划线的组合</div>
          </td>
        </tr>
        <tr>
          <td>密码:</td>
          <td>
            <input type="password" name="pwd" />
            <span>*</span>
          </td>
          <td>
            <div class="vali_info">6位数字</div>
          </td>
        </tr>
        <tr>
          <td></td>
          <td colspan="2">
            <input type="submit" value="保存" />
            <input type="reset" value="重填" />
          </td>
        </tr>
      </table>
    </form>
    <script>
      //想获得网页中唯一的一个form
      //旧DOM:
      //var form=document.getElementById("form1");
      //HTML DOM:
      var form = document.forms[0];
      console.log(form);
      //DOM 4步
      //1. 查找触发事件的元素
      //本例中: 姓名、密码文本框失去焦点时触发验证
      //用name属性分别找到两个文本框
      // var inputName=document.getElementsByName("username")[0];//复习第一天查找元素
      // var inputName=form.elements["username"];
      var inputName = form.username;
      var inputPwd = form.pwd;
      //希望页面一加载,姓名或是密码文本框就自动获得焦点!
      //如果希望实现点哪个文本框,哪个文本框就获得焦点,需要同时给2个文本框绑定获得焦点事件处理函数,请参看valiWithCSS.html
      inputName.focus();
      // inputPwd.focus();
      //2. 绑定事件处理函数
      //为两个文本框绑定失去焦点函数

      //当姓名文本框失去焦点时,自动执行
      inputName.onblur = function () {
        //3. 查找要修改的元素
        //本例中: 要修改当前文本框的爹的下一个兄弟的第一个孩子
        var div = this.parentElement.nextElementSibling.children[0];
        //4. 修改元素
        //先定义验证姓名的正则表达式
        var reg = /^\w{1,10}$/;
        //如果用正则表达式验证当前姓名文本框的内容通过
        if (reg.test(this.value) == true) {
          //就修改div的class为验证通过的样式类名
          div.className = "vali_success";
        } else {
          //否则如果验证不通过
          //就修改div的class为验证不通过的样式类名
          div.className = "vali_fail";
        }
      };

      //当密码文本框失去焦点时,自动执行
      inputPwd.onblur = function () {
        //3. 查找要修改的元素
        //本例中: 要修改当前文本框的爹的下一个兄弟的第一个孩
        var Pdiv = this.parentElement.nextElementSibling.children[0];
        //4. 修改元素
        //先定义验证密码的正则表达式
        var reg = /^\d{6}$/;
        //如果用正则表达式验证当前密码文本框的内容通过
        if (reg.test(this.value) == true) {
          //就修改Pdiv的class为验证通过的样式类名
          Pdiv.className = "vali_success";
        } else {
          //否则如果验证不通过
          //就修改div的class为验证不通过的样式类名
          Pdiv.className = "vali_fail";
        }
      };
    </script>
  </body>
</html>

 运行结果:

⬛总结: DOM 5件事: 增删改查+事件绑定

1. 查找元素: 4种查找方式

2. 修改元素: 3种东西可修改

3. 添加/删除元素

4. HTML DOM常用对象:(了解即可)

(1). var img=new Image()

(2). table
         a. table管着行分组:

      1). 添加行分组:

      var thead=table.createTHead()

      var tbody=table.createTBody()

      var tfoot=table.createTFoot()

      2) 删除行分组:

      table.deleteTHead(); table.deleteTFoot()

      3). 获取行分组:

      table.tHead  table. tFoot  table.tBodies[i]

         b. 行分组管着行:

      1). 添加行:

                i. 任意行插入新行: var tr=行分组.insertRow(i);

               ii. 开头插入新行: var tr=行分组.insertRow(0)

               iii. 末尾追加新行: var tr=行分组.insertRow()

      2). 删除行: table.deleteRow(tr.rowIndex)

      3). 获取行: 行分组.rows[i]

c. 行管着格:

      1). 添加格: var td=tr.insertCell()

      2). 删除格: tr.deleteCell(i)

      3). 获取格: tr.cells[i]

(3). form:

a. 获取form元素: document.forms[i]

b. 获取form中的表单元素:

      1). 标准: form.elements[i或id或name名]

      2). 简写: 如果有name属性: form.name名

c. 让表单元素自动获得焦点: 表单元素.focus()

 【后文传送门】👉 深入浅出浏览器对象模型—BOM基础知识详解_06 

​​

如果这篇【文章】有帮助到你,希望可以给【青春木鱼】点个👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【前端技术】感兴趣的小可爱,也欢迎关注❤️❤️❤️青春木鱼❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值