DOM常用操作与Demo

蓦然回首

本文算是《JavaScript DOM编程艺术》这本书的学习记录,回想起来,刚开始学前端的时候就是在实验室看这本书,后来接触了库和框架,原生的这些DOM操作就很少使用了,去年年底的时候 winter 在极客时间开了专栏:重学前端,一时间传的沸沸扬扬。现在一年多过去了,确实有必要停下脚步来回头看看。

DOM

DOM (Document Object Model),对文档的内容进行抽象和概念化的方法,主要功能就是处理网页内容。DOM包含着许多不同类型的节点,主要讨论以下三种:

  • 元素节点,标签名即为元素名
  • 文本节点,总是被包含在元素节点的内部
  • 属性节点,对元素进行更具体的描述

获取元素

  • getElementById,调用后返回一个(元素)对象
  • getElementsByTagName,调用后返回一个对象数组,用document.getElementsByTagName(“li”).length查看个数,通过循环来遍历数组,也可以配合getElementById进行二次精确查询:
let ul = document.getElementById('flowers');
let items = ul.getElementsByTagName('li');
  • getElementsByClassName,要指定多个类名时,用空格分隔即可,而且类名添加的顺序不会影响查询结果

元素属性

  • object.getAttribute(‘title’),只能通过元素节点对象来调用
  • object.setAttribute(‘src’,value),做出的修改不会反映在文档的源码中,这和DOM的工作模式有关,先加载文档静态内容,再动态刷新,后者不会影响前者。
  • element.childNodes,获取元素的所有子元素,返回一个数组
  • node.nodeType,元素=1 / 属性=2 / 文本=3
  • node.nodeValue,改变文本节点的值
  • node.firstChild
// 元素内容为: <p id = 'description '> hah </p> 
// <p>元素包含的文本是它的第一个子节点
let description = document.getElementById('description');
description.firstChild.nodeValue = 'hello world'

创建元素

两种传统方法

  • document.write,把字符串插入到文档中
  • x.innerHTML,原有内容将被全部替换
// 元素内容为: <p id = 'description '> hah </p> 
// <p>元素包含的文本是它的第一个子节点
document.write('<p> hah has been inserted</p>');
x.innerHTML = '<p> text has been repalced </p>'

DOM方法

  • document.createElement(‘x’),第一步创建新元素
  • node.appendChild(x),第二步把新元素插入节点树
  • document.createTextNode(‘some text’),创建文本节点
// 通过appendChild把文本节点赋给<p>元素
let textContent = document.createTextNode('some text');
let para = document.getElementById('para');
    para.appendChild(textContent)
  • parentElement.insertBefore(newElement,targetElement),在指定元素前插入新元素。在元素后插入需要自定义函数来实现。
function insertAfter(newElement, targetElement) {   //参数均为元素节点名称
   //insert的使用要有parent
   let parent = targetElement.parentNode;
   if(parent.lastChild == targetElement){
       parent.appendChild(newElement)
   }else{
       let xElement = targetElement.nextSibling;  //目标元素的下一个兄弟元素
       parent.insertBefore(newElement,xElement)
   }
}

图片库DEMO

DEMO的需求是点击上方的缩略图,可以在下面显示大图和图片描述。其中图片显示区域和文字描述区域都是用上面所讲的DOM方法动态插入的

效果图:

在这里插入图片描述
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gallery</title>
    <link rel="stylesheet" href="main.css">
    <script type="text/javascript" src="main.js"></script>
</head>
<body>

    <h1>赏花指南</h1>
    <ul id="gallery">
        <li>
            <a href="./images/lihua.png" title="梨花 - 花香宜人">
                <img src="./images/li-s.png" width="100px" height="100px"></a>
        </li>
        <li>
            <a href="./images/meihua.png" title="梅花 - 花香浓郁">
                <img src="./images/mei-s.png" width="100px" height="100px"></a>
        </li>
        <li>
            <a href="./images/taohua.png" title="桃花 - 花开有叶">
                <img src="./images/tao-s.png" width="100px" height="100px"></a>
        </li>
        <li>
            <a href="./images/xinhua.png" title="杏花 - 先花后叶">
                <img src="./images/xin-s.png" width="100px" height="100px"></a>
        </li>
    </ul>
    <!--
    查找:ctrl f    替换:ctrl r
    -->
</body>
</html>

main.js


//自定义函数,功能为在元素后插入新元素
function insertAfter(newElement, targetElement) {   //参数均为元素节点名称
   //insert的使用要有parent
   let parent = targetElement.parentNode;
   if(parent.lastChild == targetElement){
       parent.appendChild(newElement)
   }else{
       let xElement = targetElement.nextSibling;
       parent.insertBefore(newElement,xElement)
   }
}

//创建图片展示区和文字说明区并插入DOM文档中
function palceHolder() {

   let picHolder = document.createElement('img');
       picHolder.setAttribute('id','demo');
       picHolder.setAttribute('src','./images/placeholder.jpg');
       
   let description = document.createElement('p');
       description.setAttribute('id','description');

   let textContent = document.createTextNode('Choose an image');
       description.appendChild(textContent);
   
   let gallery = document.getElementById('gallery');

   insertAfter(picHolder,gallery);
   insertAfter(description,picHolder);
}

//绑定点击事件
function galleryEvent() {

   //要进行二次get
   let gallery = document.getElementById('gallery');
   let liElements = gallery.getElementsByTagName('a');

   for(let i=0; i<liElements.length;i++){
       liElements[i].onclick = function (){
           showPic(this);  //this 当前的元素标签
           return false;
       }
   }
}

//替换函数
function showPic(whichPic) {

   let src = whichPic.getAttribute('href');
   let picHolder = document.getElementById('demo');
       picHolder.setAttribute('src',src);

   let text = whichPic.getAttribute('title');
   let description = document.getElementById('description');
       description.firstChild.nodeValue = text;


}

window.onload = function () {
   palceHolder();
   galleryEvent();
}


后记

国外的技术书都是以需求为导向来讲的,产生新的需求,进而提出新的解决办法,这样比很多教材枯燥地列出各种API要好很多。
这段时间身体一直不是很好,不过最近状态有所恢复,简历写好了准备找实习,狗哥也开始找工作了,过程很艰难,希望能有好的结果吧。在校的时间也不多了,认真一点,时间是金。

猜你喜欢

转载自blog.csdn.net/qq_41366268/article/details/88399136