JavaScript-DOM案例学习笔记

学习链接:https://www.bilibili.com/video/BV1Sy4y1C7ha
JavaScript基础语法-dom-bom-js-es6新语法-jQuery-数据可视化echarts黑马pink老师前端入门基础视频教程 ,P204~P246


目录

1.操作元素

1.1 仿京东显示隐藏密码明文案例

 1.2 仿淘宝关闭二维码案例

 1.3 循环精灵图背景

 1.4 显示隐藏文本框内容

 1.5 密码框验证信息

1.6 总结

2. 排他思想

 2.1 百度换肤

2.2 表格隔行变色案例

2.3 表单的全选取消全选案例

2.4 自定义属性值操作

2.5 tab栏切换 (重点)

2.6 H5自定义属性

3. 节点操作

3.1 新浪下拉菜单

3.2 简单版发布留言案例

3.3 删除留言案例

3.4 动态生成表格

3.5 三种动态创建元素区别(document.write()、element.innerHTML()、document.createElement())


1.操作元素

1.1 仿京东显示隐藏密码明文案例

思路:点击眼睛按钮,把密码框类型改为文本框即可看到里面的密码

算法:利用一个变量,来判断变量的值,1为切换为文本框,0为切换为密码框

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>京东密码输入</title>
    <style>
        .box {
            position: relative;
            width: 400px;
            border-bottom: 1px solid #ccc;
            margin: 100px auto;
        }
        
        .box input {
            width: 370px;
            height: 30px;
            border: 0;
            outline: none;
        }
        
        .box img {
            position: absolute;
            top: 1px;
            right: 30px;
            width: 32px;
        }
    </style>
</head>

<body>
    <div class="box">
        <label for="">
            <img src="close.png" id="eye">
        </label>
        <input type="password" name="" id="pwd">
    </div>
    <script>
        var eye = document.getElementById('eye');
        var pwd = document.getElementById('pwd');
        var flag = 0;
        eye.onclick = function() {
            if (flag == 0) {
                pwd.type = 'text';
                eye.src = 'open.png';
                flag = 1;
            } else {
                pwd.type = 'password';
                eye.src = 'close.png';
                flag = 0;
            }
        }
    </script>
</body>
  1. outline是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。outline属性设置元素周围的轮廓线。outline:none去除轮廓线效果。
  2. pwd.type——更改输入框类型;eye.src——更改图片源,实现更换图片

 1.2 仿淘宝关闭二维码案例

通过JS修改元素的大小、颜色、位置等样式

  1. element.style 行内样式操作(P209)
  2. element.className 类名样式操作(P213)

 style注意:

  1. JS中样式采用驼峰命名法,如fontSzie、backgroundColor
  2. JS修改style样式操作,产生的是行内样式,css权重比较高

className注意: 

  1. className会直接更改元素的类名,会覆盖原先的类名
  2. 可以写成this.className = '原先的类名 新增的类名' 多类名选择器,保留原本的类

 思路:利用样式的显示和隐藏完成,display:none隐藏元素;display:block显示元素

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>淘宝二维码</title>
    <style>
        .close {
            position: absolute;
            width: 15px;
        }
        
        .tb {
            position: absolute;
            left: 25px;
            top: 2px;
            width: 60px;
            margin-top: 5px;
        }
    </style>
</head>

<body>
    <div class="box">
        <img src="x.png" class="close">
        <img src="tb.png" class="tb">
    </div>
    <script>
        //获取元素
        var x = document.querySelector('.close');
        var box = document.querySelector('.box');
        //注册事件
        x.onclick = function() {
            box.style.display = 'none';
        }
    </script>
</body>
  1.  获取class元素:document.querySelector('.获取的类名'),一定要加.;                                   获取id元素:documen.getElementById('获取的类名')
  2. 注册事件不能用this,因为不是指向div这个元素,而是x
  3. display也属于style的样式,默认为display:block;不显示在style中

 1.3 循环精灵图背景

思路:利用for循环,修改精灵图的背景位置background-position

<script>
    var lis = document.querySelectorAll('li');
    for(var i=0; i < lis.length; i++){
        //索引号乘44 就是每个li的背景y坐标
        var index = i * 44;
        lis[i].style.backgroundPosition = '0 -' + index +'px';
    }
</script>

 1.4 显示隐藏文本框内容

  1. 表单需要2个新事件,获得焦点onfocus 失去焦点onblur
  2. 获得焦点时,判断是否为默认文字,如果是则清空,否则保留
  3. 失去焦点时,判断文本框是否为空,如果为空则表单内容改为默认文字

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>显示隐藏文本框内容</title>
    <style>
        input {
            color: #999;
        }
    </style>
</head>

<body>
    <div class="box">
        <input id="" value="手机" type="text">
        <script>
            var text = document.querySelector('input');
            //获得焦点事件 onfocus
            text.onfocus = function() {
                    if (this.value === '手机') {
                        this.value = '';
                    }
                    //获得焦点时调整文本颜色为黑色
                    this.style.color = '#333'
                }
            //失去焦点事件 onblur
            text.onblur = function() {
                if (this.value === '') {
                    this.value = '手机';
                }
                //失去焦点时调整文本颜色回灰色
                this.style.color = '#999'
            }
        </script>
    </div>
</body>
  1. 获得焦点——onfocus;失去焦点——onblur
  2. this.value同等于text.value
  3. ===是等于的意思

 1.5 密码框验证信息

 判断的事件是失去焦点

<head>
    <style>
        .wrong{
            color:red;
            background-image: url(images/wrong.png);
        }
        .right{
            color:green;
            background-image: url(images/right.png);
        }
    </style>
</head>

<body>
    <div class="register">
        <input type="password" class="ipt">
        <p class="message">请输入6~16位密码</p>
    </div>
    <script>
        var ipt = document.querySelector('.ipt');
        var message = document.querSelector('.message');
        ipt.onblur = function(){
            if(this.value.length <6 || this.value.length >16){
                meaasge.className = 'message wrong';
                message.innerHTML = '您输入的位数不对 要求6~16位';
            }else{
                meaasge.className = 'message right';
                message.innerHTML = '您输入的正确';
            }
        }
    </script>
</body>
  1. 通过多类名方法修改,wrong、right属性

1.6 总结

2. 排他思想

  1. 所有元素全部清除样式(干掉其他人)
  2. 给当前元素设置样式(留下自己)
<body>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
    <script>
        var btns = document.getElementsByTagName('button');
        //btns得到的是伪数组 里面的每个元素btns[i]
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                //先把所有按钮背景颜色去掉
                for (var i = 0; i < btns.length; i++) {
                    btns[i].style.backgroundColor = '';
                }
                //才让当前的元素背景颜色为pink
                this.style.backgroundColor = 'pink';
            }
        }
    </script>
</body>

 2.1 百度换肤

思想:把当前图片的src路径取过来,给body作为背景即可

<!DOCTYPE html>
<html lang="en">

<head>
    <title>百度换肤</title>
    <style>
        body {
            background: url(fn.jpg)no-repeat center top;
        }
        
        li {
            list-style: none;
        }
        
        .baidu {
            overflow: hidden;
            margin: 100px auto;
            width: 410px;
            padding-top: 3px;
        }
        
        .baidu li {
            float: left;
            margin: 0 1px;
            cursor: pointer;
        }
        
        .baidu img {
            width: 100px;
        }
    </style>
</head>

<body>
    <ul class="baidu">
        <li><img src="fn.jpg"></li>
        <li><img src="fn1.jpg"></li>
        <li><img src="fn2.jpg"></li>
        <li><img src="fn3.jpg"></li>
    </ul>
    <script>
        //获取元素 lu->li,注意是querySelectorAll('img') ALL
        var imgs = document.querySelector('.baidu').querySelectorAll('img');
        //循环注册事件
        for (var i = 0; i < imgs.length; i++) {
            imgs[i].onclick = function() {
                //this.src为点击的图片的路径
                document.body.style.backgroundImage = 'url(' + this.src + ')';
            }
        }
    </script>
</body>

</html>

2.2 表格隔行变色案例

思路:

        鼠标经过tr行,当前的行变背景颜色,鼠标离开去掉当前的背景颜色,第一行颜色不变,获取的是tbody的行

    <script>
        //获取tbody里面的所有行
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        //利用循环绑定注册事件
        for (var i = 0; i < trs.length; i++) {
            //鼠标经过事件 onmouseover
            trs[i].onmouseover = function() {
                this.className = 'bg';
            }
            trs[i].onmouseout = function() {
                this.className = ''
            }
        }
    </script>

2.3 表单的全选取消全选案例

<head>
    <title>表格全选</title>
    <style>
        table {
            border: #999 solid 1px;
            width: 200px;
            height: 200px;
        }
    </style>
</head>

<body>
    <table>
        <thead>
            <tr>
                <th>
                    <input type="checkbox" id="j_cbAll" />
                </th>
                <th>商品</th>
                <th>价钱</th>
            </tr>
        </thead>
        <tbody id="j_tbs">
            <tr>
                <td>
                    <input type="checkbox" />
                </td>
                <td>iphone11</td>
                <td>5000</td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox" />
                </td>
                <td>iphone12</td>
                <td>6000</td>
            </tr>
            <tr>
                <td>
                    <input type="checkbox" />
                </td>
                <td>iphone13</td>
                <td>6500</td>
            </tr>
        </tbody>
    </table>
    <script>
        //1.全选和取消全选做法
        var j_cbAll = document.getElementById('j_cbAll'); //全选按钮
        var j_tbs = document.getElementById('j_tbs').getElementsByTagName('input'); //下面所有的复选框
        //全选按钮注册时间 被选中属性 checked='checked' 将全选按钮状态赋值给下面所有的复选框
        //this.checked可以获得当前复选框状态(true选中/false未选中)
        j_cbAll.onclick = function() {
                for (var i = 0; i < j_tbs.length; i++) {
                    j_tbs[i].checked = this.checked;
                }
            }
        //2.下面复选框需要全部选中,上面全选才能选中
        for (var i = 0; i < j_tbs.length; i++) {
            j_tbs[i].onclick = function() {
                var flag = true; //判断全部按钮是否被选中
                //每次点击下面的复选框都要循环检查小按钮是否全部被选中
                for (var i = 0; i < j_tbs.length; i++) {
                    if (!j_tbs[i].checked) {
                        flag = false;
                        break;
                    }
                }
                j_cbAll.checked = flag;
            }
        }
    </script>
</body>
  1. 复选框被选中状态为checked="checked"
  2. this.checked可以获得当前复选框状态(true 选中/false 未选中)

  3. 设置flag变量,判断选取复选框是否都有被选中

2.4 自定义属性值操作

自定义属性——程序员自己添加的属性

获取自定义属性

var div = document.querSelector('div');

 (1)element.属性

        div.id

 (2)element.getAttribute('属性')

        div.getAttribute('id')

设置自定义属性

(1)element.属性 = '值' 

        div.id = 'test';

 (2)element.getAttribute('属性','值')

        div.getAttribute('id' , '2')/div.getAttribute('class' , '2')

移除自定义属性

        div.removeAttribute('属性')

2.5 tab栏切换 (重点)

 思路:

  1. 划分为两大模块,导航栏加内容栏,分别放在两个div,并由一个大的div包裹着
  2. 给上面的tab_list里面的所有小li添加自定义属性,属性值从0开始编号,当我们点击tab_list里面某个li,让tab_con里面对应序号的内容显示,其余隐藏(排他思想)

<head>
    <title>tab栏切换布局</title>
    <style>
        .tab {
            position: relative;
        }
        
        .tab_con {
            position: absolute;
            top: 60px;
            left: 50px;
        }
        
        li {
            list-style: none;
        }
        
        .tab_list li {
            float: left;
            height: 39px;
            line-height: 39px;
            padding: 0 20px;
            text-align: center;
            cursor: pointer;
        }
        
        .tab_list .current {
            background-color: tomato;
            color: white;
        }
        
        .item_info {
            padding: 20px 0 0 20px;
        }
        
        .item {
            display: none;
        }
    </style>
</head>

<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="current">商品介绍</li>
                <li>规格与包装</li>
                <li>售后保障</li>
                <li>商品评价</li>
            </ul>
        </div>
        <div class="tab_con">
            <div class="item" style="display: block;">
                商品介绍模块内容
            </div>
            <div class="item">
                规格与包装模块内容
            </div>
            <div class="item">
                售后保障模块内容
            </div>
            <div class="item">
                商品评价模块内容
            </div>
        </div>
    </div>
    <script>
        //第一部分 模块选项卡
        var tab_list = document.querySelector('.tab_list');
        var lis = tab_list.querySelectorAll('li');
        var items = document.querySelectorAll('.item')
        for (var i = 0; i < lis.length; i++) {
            //开始给li设置索引号
            lis[i].setAttribute('index', i)
            lis[i].onclick = function() {
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = '';
                }
                this.className = 'current';

                //第二部分 内容块
                var index = this.getAttribute('index');
                //排他思想 只留下对应的item
                for (var i = 0; i < lis.length; i++) {
                    items[i].style.display = 'none';
                }
                items[index].style.display = 'block';
            }
        }
    </script>
</body>
  1. lis和items全都是多元素,需要使用querySelectorAll
  2. 运用了排他思想自定义属性的方法
  3. 自定义属性:在模块选择卡区域定义自定义属性index,内容模块获取index从而知道要显示对应的是什么模块 

2.6 H5自定义属性

1.H5规定以data-开头作为属性名并赋值,例

element.setAttribute('data-index',2)

 2.H5新增element.dataset.index / element.dataset['index']获取自定义属性方法(ie11以上)

         dataset是一个集合里面存放了所有以data开头的自定义属性

 3.如果有两个或以上-链接的自定义属性,例 data-index="2" data-list-name="andy"

        data-list-name="andy" -> div.dataset.listName 驼峰命名法

3. 节点操作

        利用节点层级关系获取元素,常见父子兄层级关系

节点基本属性
nodeType节点类型
nodeName节点名称
nodeValue节点值
  • 元素节点 nodeType为1
  • 属性节点 nodeType为2
  • 文本节点 nodeType为3 (文本节点包含文字、空格、换行...)、
父节点parentNode返回最近的父节点
子节点childNodes(不提倡使用)返回全部子节点
children(更推荐使用)返回全部子元素节点
firstChild / lastChild获取第一个/最后一个 子节点
firstElementChild /lastElementChild返回第一个/最后一个子元素节点(有兼容性问题)
children.[0]/children.[length-1]返回第一个/最后一个子元素节点(无兼容性问题)
兄弟节点nextSibling获得下一个兄弟节点
previousSibling获得上一个兄弟节点
nextElementSibling获得下一个兄弟元素节点(有兼容性问题)
previousElementSibling获得上一个兄弟元素节点(有兼容性问题)

创建节点

        1.document.createElement('tagName') 创建元素节点

        2.node.appendChild(child) 添加节点到后面 父级——node 子级——child

           node.insertBefore(child,指定元素) 添加到指定节点前

删除节点

        1. node.removeChild(child)

复制节点

        1.node.cloneNode()

        如果括号参数为空/false,只是浅拷贝,只复制节点本身,不克隆里面的内容 

        2.node.cloneNode(true) 深拷贝

3.1 新浪下拉菜单

    <script>
        var nav = document.querySelector('nav');
        var lis = nav.children;
        for (var i = 0; i < lis.length; i++) {
            lis[i].onmouseover = function() {
                this.children[1].style.display = 'block';
            }
            lis[i].onmouseout = function() {
                this.children[1].style.display = 'none';
            }
        }
    </script>

3.2 简单版发布留言案例

思路:点击按钮后动态创建一个li,添加到ul中

<head>
    <title>发布留言案例</title>
    <style>
        li {
            width: 200px;
            background-color: pink;
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
</head>

<body>
    <textarea>123</textarea>
    <button>发布</button>
    <ul>
        <li>123</li>
    </ul>
    <script>
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        btn.onclick = function() {
            if (text == '') {
                alert('你没有输入内容');
                return false;
            } else {
                //创建元素
                var li = document.createElement('li');
                //给li传递内容innerHTML text.value
                li.innerHTML = text.value;
                //添加元素
                ul.insertBefore(li, ul.children[0]);
            }

        }
    </script>
</body>

3.3 删除留言案例

删除节点语法:node.removeChild(child) 删除父节点里的孩子

    <script>
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        btn.onclick = function() {
            if (text == '') {
                alert('你没有输入内容');
                return false;
            } else {
                //创建元素
                var li = document.createElement('li');
                //给li传递内容innerHTML text.value 阻止链接跳转javascript:;
                li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
                //添加元素
                ul.insertBefore(li, ul.children[0]);
                //删除元素 删除当前的li this.parentNode->li 
                var as = document.querySelectorAll('a');
                for (var i = 0; i < as.length; i++) {
                    as[i].onclick = function() {
                        ul.removeChild(this.parentNode);
                    }
                }
            }
        }
    </script>
  1. 阻止链接跳转需要添加javascript:void(0);/javascript:;
  2. 删除li: ul.removeChild(this.parentNode);                                                                                              this->as this.parentNode->li li是ul的child

  3. 将全部的<a>获取后循环判断点击的是哪一个<a>,并进行删除操作

 3.4 动态生成表格

<head>
    <title>Document</title>
    <style>
        table {
            width: 500px;
            margin: 100px auto;
            border-collapse: collapse;
            text-align: center;
        }
        
        td,
        th {
            border: 1px solid #333;
        }
        
        thead tr {
            height: 40px;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <script>
        //1.创建数据
        var datas = [{
            name: '玲娜贝儿',
            subject: '太极',
            score: 100
        }, {
            name: '饼饼',
            subject: '烘培',
            score: 100
        }, {
            name: '露露',
            subject: '芭蕾',
            score: 100
        }];
        //2. 往tbody里面创建行:有几个人就创建几行(通过数组的长度)
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) { //外面for循环管行 tr
            //2.1. 创建tr行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);
            //2.2. 行里面创建单元格(与数据有关的3个单元格) td 单元格数量取决于属性个数
            for (var j in datas[i]) { //里面的for管 td j得到属性名 datas[i]得到属性值
                //创建单元格
                var td = document.createElement('td');
                //2.3.把对象里面的属性值datas[i][j] 给 td
                td.innerHTML = datas[i][j];
                tr.appendChild(td);
            }
            //3. 创建删除单元格
            var td = document.createElement('td');
            td.innerHTML = '<a href="javascript:;">删除</a>';
            tr.appendChild(td);
        }
        //4. 删除操作
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
            as[i].onclick = function() {
                //点击删除 删除当前所在行 node.removeChild(child)
                tbody.removeChild(this.parentNode.parentNode)
            }
        }
    </script>
</body>
  1. 创建数据->创建tbody的行->创建每一行的每一单元格->添加数据->删除操作                            层级关系:行->单元格->数据
  2. 创建数据:以数组的形式保存每一行数据
  3. 创建行:docunment.queryElement( 'tr' ) + tbody.appendChild( tr )
  4. 创建单元格:for(var j in datas[i]) j获得属性名 datas[i]获得属性值
  5. 添加数据:td.innerHTML = datas[i][j]
  6. 删除操作:tbody.removeChild(this.parentNode.praentNode)                                            tbody指单元格,this指删除标签,删除行,行是单元格的父亲的父亲 

3.5 三种动态创建元素区别(document.write()、element.innerHTML()、document.createElement())

  1. document.write 直接将内容写入页面的内容流,但文档流执行完毕会导致页面全部重绘
  2. innerHTML 将内容写入某个DOM节点,不会导致页面全部重绘
  3. innerHTML 创建多个元素效率更高,结构会稍微复杂
  4. createElement 创建多个元素效率略低,但是结构清晰

总结:不同浏览器下,innerHTML 效率要比 createElement 高

 4. DOM总结

功能操作内容
创建document.write
innerHTML
createElement
增加appendChild添加到后面
insertBefore添加到前面
删除removeChild
更改src、href、title修改元素属性
innerHTML、innerText修改普通元素内容
value、type、disabled修改表单元素
style、className修改元素样式
查询getElementById、getElementByTagNameDOM提供的API方法(古老)
querySelector、querySelectorALLH5提供的新方法
父(parentNode)、子(children)、兄(previousElementSibling)节点操作获取元素
属性操作setAttribute设置DOM的属性值
getAttribute得到DOM的属性值
removeAttribute移除属性
事件操作事件源.事件类型 = 事件处理程序

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值