Web APIs(DOM和BOM)

目录

Web APIs

API:

Web API:

 DOM

 DOM树

 获取元素

1.通过ID获取

 2.通过标签名获取

 3.H5新增获取元素的方法

 4.获取特殊元素 (body和html)

事件基础

 1.事件三要素

2.常见的鼠标事件

 操作元素

1.改变元素内容

2.改变元素内容(innerText和innerHTML的区别)

3.修改元素的属性(如src、href、id、alt、title等)

4.表单属性设置(type、value、checked、selected、disabled)

5.修改元素样式属性(style)

6.修改元素样式属性(className)

7.排他思想

8.换肤效果

 9.表格隔行变色

10.表单全选取消全选

11.自定义属性操作(获得属性getAttribute,设置属性值setAttribute,移除属性removeAttribute)

12.自定义属性操作-tab栏切换案例

13.H5自定义属性

节点操作

 1.节点概述

2.父节点操作(node.parentNode)

3.子节点操作(parentNode.childNodes和parentNode.children)

3.第一个和最后一个子节点(包括文本,元素),第一个子元素和最后一个子元素

4.兄弟节点

5.创建和添加节点(发布留言案例)

6.删除节点(删除留言案例)

7.克隆节点(动态生成表格案例)

8.三种创建元素方式区别

9.关于DOM操作

事件高级

 1.注册事件的两种方式

 2.删除事件

 3.DOM事件流

 4.事件对象

 5.事件对象的常见属性方法

6.事件对象阻止默认行为(让链接不跳转或让提交按钮不提交等)

7.阻止事件冒泡(点son不会影响father)

 8.事件委托

9.常见鼠标事件

 10.鼠标事件对象

 跟随鼠标案例

11.常用键盘事件

12.键盘事件对象-keyCode属性

13.键盘事件对象案例(模拟京东按键输入内容,模拟京东快递单查询)

BOM

 BOM顶级对象​

 window常见事件

1.窗口加载事件

2.调整窗口大小事件

定时器

1.setTimeout()定时器(5秒后自动关闭广告案例)

2. 停止 setTimeout() 定时器

3.setInterval() 定时器(倒计时案例)

4.停止 setInterval() 定时器(发送短信案例)

5.this指向问题

Js执行机制

 1.同步和异步

 2.执行机制

 location常见对象

1.URL

 2.location 对象的属性(5秒钟之后自动跳转页面案例)

3.获取URL参数query

4.location 对象的方法

1.判断用户所用终端打开页面,实现跳转到相应页面(例如从京东PC端首页跳转到手机端首页)

history 对象


Web APIs

 

API:

Web API:

 DOM

 DOM树

 获取元素

1.通过ID获取

        // 因为我们文档页面从上往下加载,
        //所以先有标签,我们script写到标签的下面
        // get获得 element 元素by 通过
        // 参数id是大小写敏感的字符串
        // 返回的是一个元素对象
        var timer = document.getElementById('time');
        console.log(timer);

        // 判断类型
        console.log(typeof timer);

        // console.dir 打印返回的元素对象 
        //更好的查看里面属性和方法
        console.dir(timer)

 2.通过标签名获取

        //返回的是获取过来元素对象的集合,以伪数组的形式存储
        var lis = document.getElementsByTagName('li');
        console.log(lis);
        console.log(lis[0]);

        // 依次打印里面的元素用遍历
        for (var i = 0; i < lis.length; i++) {
            console.log(lis[i]);
        }

        // 如果页面只有一个li返回的还是伪数组形式
        // 如果页面没有这个元素,返回的是空的伪数组形式


        // element.getElementsByTagName('标签名');父元素必须是指定的单个元素
        // var ol = document.getElementsByTagName('ol');
        // console.log(ol[0].getElementsByTagName('li'));
        var ol = document.getElementById('ol');
        console.log(ol.getElementsByTagName('li'));

 3.H5新增获取元素的方法

        // 根据类名获取元素集合
        var boxs = document.getElementsByClassName('box');
        console.log(boxs);

        // 返回指定选择器的第一个元素对象,注意里面要加符号. # 和''.
        var firstBox = document.querySelector('.box');
        console.log(firstBox);
        var nar = document.querySelector('#nav')
        console.log(nav);
        var li = document.querySelector('li');
        console.log(li);

        //返回指定选择器的所有元素对象集合
        var allBox = document.querySelectorAll('.box');
        console.log(allBox);
        var lis = document.querySelectorAll('li');
        console.log(lis);

 4.获取特殊元素 (body和html)

        // 1.获取body 元素
        var bodyEle = document.body;
        console.log(bodyEle);
        console.dir(bodyEle);

        // 2.获取html 元素
        // var htmlEle=document.html;
        var htmlEle = document.documentElement;
        console.log(htmlEle);

事件基础

 1.事件三要素

        // 点击一个按钮,弹出对话框
        // 1. 事件是有三部分组成  事件源  事件类型  事件处理程序   我们也称为事件三要素
        //(1) 事件源 事件被触发的对象   谁  按钮
        var btn = document.getElementById('btn');
        //(2) 事件类型  如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
        //(3) 事件处理程序  通过一个函数赋值的方式 完成
        btn.onclick = function() {
            alert('点秋香');
        }


        // 执行事件步骤
        // 点击div 控制台输出 我被选中了

        // 1. 获取事件源
        var div = document.querySelector('div');

        // 2.绑定事件 注册事件
        // div.onclick 

        // 3.添加事件处理程序 
        div.onclick = function() {
            console.log('我被选中了');

        }

2.常见的鼠标事件

 操作元素

1.改变元素内容(innerHTML)

        // 当我们点击了按钮,  div里面的文字会发生变化

        // 1. 获取元素 
        var btn = document.querySelector('button');
        var div = document.querySelector('div');

        // 2.注册事件
        btn.onclick = function() {
            //改变内容innerText,属性
            // div.innerText = '2022-3-21';
            div.innerText = getDate();
        }

        function getDate() {
            var date = new Date();
            //  2022年 3月 21日 星期三
            var year = date.getFullYear();
            var month = date.getMonth() + 1;
            var dates = date.getDate();
            var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
            var day = date.getDay();
            return '今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day];
        }

        // 我们元素可以不用添加事件
        var p = document.querySelector('p');

        p.innerHTML = getDate();

2.改变元素内容(innerText和innerHTML的区别)

        // innerText 和 innerHTML的区别 

        // 1. innerText:不识别html标签,非标准 ,去除空格和换行
        var div = document.querySelector('div');
        // div.innerText = '<strong>今天是:</strong> 2022';

        // 2. innerHTML:识别html标签,W3C标准,保留空格和换行的
        div.innerHTML = '<strong>今天是:</strong> 2022';

        // 这两个属性是可读写的 ,可以获取元素里面的内容
        var p = document.querySelector('p');
        console.log(p.innerText);
        console.log(p.innerHTML);

3.修改元素的属性(如src、href、id、alt、title等)

        // 修改元素属性  src和title
        // 获取元素
        var ldh = document.getElementById('ldh');
        var zxy = document.getElementById('zxy');
        var img = document.querySelector('img');

        // 注册事件和处理程序
        zxy.onclick = function() {
            img.src = 'images/zxy.jpg';
            img.title = '张学友';
        }
        ldh.onclick = function() {
            img.src = 'images/ldh.jpg';
            img.title = '刘德华';
        }

分时问候并显示不同图片案例

       // 根据系统不同时间来判断,所以需要用到日期内置对象
        // 利用多分支语句来设置不同的图片
        // 需要一个图片,并且根据时间修改图片,就需要用到操作元素src属性
        // 需要一个div元素,显示不同问候语,修改元素内容即可
        // 获取元素
        var img = document.querySelector('img');
        var div = document.querySelector('div');

        // 获取当前小时数
        var date = new Date();
        var h = date.getHours();

        // 判断小时改变图片和文字
        if (h < 12) {
            img.src = 'images/s.gif';
            div.innerHTML = '上午好!!!';
        } else if (h < 18) {
            img.src = 'images/x.gif';
            div.innerHTML = '下午好!!!';
        } else {
            img.src = 'images/w.gif';
            div.innerHTML = '晚午好!!!';
        }

4.表单属性设置(type、value、checked、selected、disabled)

        // 获取元素
        var btn = document.querySelector('button');
        var input = document.querySelector('input');

        // 注册事件,处理程序
        btn.onclick = function() {
            // 表单里面的值即文字内容是通过value修改的
            input.value = '被点击了';

            // 如果想要某个表单被禁用,不能再点击,要这个按钮button被禁用
            // btn.disabled = true;
            // this指向是事件函数的调用者
            this.disabled = true;
        }

显示隐藏密码案例

<body>
    <div class="box">
        <label for="">
           <img src="images/close.png" alt="" id="eye">
       </label>
        <input type="password" id="pwd">
    </div>
    <script>
        // 核心思路:  点击眼睛按钮,把密码框类型改为文本框就可以看见里面的密码
        // 一个按钮两个状态,点击一次,切换为文本框,继续点击一次切换为密码框
        // 算法:利用一个flag变量,来判断flag的值,
      //如果是1 就切换为文本框,flag 设置为0,如果是0 就切换为密码框,flag设置为1
        // 获取元素
        var eye = document.getElementById('eye');
        var pwd = document.getElementById('pwd');

        // 注册事件 处理程序
        var flag = 0;
        eye.onclick = function() {
            // 点击一次,flag一定要变化
            if (flag == 0) {
                pwd.type = 'text';
                eye.src = 'images/open.png';
                flag = 1; //赋值操作
            } else {
                pwd.type = 'password';
                eye.src = 'images/close.png';
                flag = 0;
            }

        }
    </script>
</body>

 

5.修改元素样式属性(style)

        // 1. 获取元素
        var div = document.querySelector('div');


        // 2. 注册事件 处理程序
        div.onclick = function() {
            //div.style里面属性用驼峰命名法
            this.style.backgroundColor = 'green';
            this.style.width = '300px';
        }

循环精灵图案例( 利用for循环  修改精灵图片的 背景位置 background-position)

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        li {
            list-style-type: none;
        }
        
        .box {
            width: 250px;
            margin: 100px auto;
        }
        
        .box li {
            float: left;
            width: 24px;
            height: 24px;
            background-color: pink;
            margin: 15px;
            background: url(images/sprite.png) no-repeat;
        }
    </style>
</head>

<body>
    <div class="box">
        <ul>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
    <script>
        // 获取元素
        var lis = document.querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            //让索引号乘以44就是每个li的背景坐标 index就是y坐标
            var index = i * 44;
            lis[i].style.backgroundPosition = '0 -' + index + 'px';
        }
    </script>
</body>

 显示隐藏文本框内容案例

    <style>
        input {
            color: #999;
        }
    </style>
</head>

<body>
    <input type="text" value="手机">
    <script>
        // 1.获取元素
        var text = document.querySelector('input');
        // 2.注册事件 获得焦点事件 onfocus 
        text.onfocus = function() {
                // console.log('得到了焦点');
                if (this.value === '手机') {
                    this.value = '';
                }
                // 获得焦点需要把文本框里面的文字颜色变黑
                this.style.color = '#333';
            }
            // 3. 注册事件 失去焦点事件 onblur
        text.onblur = function() {
            // console.log('失去了焦点');
            if (this.value === '') {
                this.value = '手机';
            }
            // 失去焦点需要把文本框里面的文字颜色变浅色
            this.style.color = '#999';
        }
    </script>

6.修改元素样式属性(className)

    <style>
        div {
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        
        .change {
            background-color: purple;
            color: #fff;
            font-size: 25px;
            margin-top: 100px;
        }
    </style>
</head>


<body>
    <div class="first">文本</div>
    <script>
        // 1. 使用 element.style 获得修改元素样式 
        // 如果样式比较少 或者 功能简单的情况下使用
        var test = document.querySelector('div');
        test.onclick = function() {
            // this.style.backgroundColor = 'purple';
            // this.style.color = '#fff';
            // this.style.fontSize = '25px';
            // this.style.marginTop = '100px';



            // 2. 我们可以通过 修改元素的className更改元素的样式
             //适合于样式较多或者功能复杂的情况
            // this.className = 'change';

            // 3. className会覆盖之前的类名
            //如果想要保留原先的类名,可以写成多类名选择器
            this.className = 'first change';
        }

密码框格式提示错误信息案例

    <style>
        div {
            width: 600px;
            margin: 100px auto;
        }
        
        .message {
            display: inline-block;
            font-size: 12px;
            color: #999;
            background: url(images/mess.png) no-repeat left center;
            padding-left: 20px;
        }
        
        .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>
        // 首先判断的事件是表单失去焦点 onblur
        // 如果输入正确则提示正确的信息颜色为绿色小图标变化
        // 如果输入不是6到16位,则提示错误信息颜色为红色 小图标变化
        // 因为里面变化样式较多,我们采取className修改样式
        // 1.获取元素
        var ipt = document.querySelector('.ipt');
        var message = document.querySelector('.message');

        //2. 注册事件 失去焦点
        ipt.onblur = function() {
            // 根据表单值的长度ipt.value.length
            if (this.value.length < 6 || this.value.length > 16) {
                message.className = 'message wrong';
                message.innerHTML = '您输入的位数不对要求6~16位'
            } else {
                message.className = 'message right';
                message.innerHTML = '您输入的正确';
            }
        }
    </script>

开关灯案例

<body>
    <button id="btn">开关灯</button>
    <script>
        var btn = document.getElementById('btn');
        var flag = 0;
        btn.onclick = function() {
            if (flag == 0) {
                document.body.style.backgroundColor = 'black';
                flag = 1;
            } else {
                document.body.style.backgroundColor = '#fff';
                flag = 0;
            }
        }
    </script>
</body>

7.排他思想

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
    <script>
        // 1. 获取所有按钮元素
        var btns = document.getElementsByTagName('button');
        // btns得到的是伪数组  里面的每一个元素 btns[i]
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                // (1) 我们先把所有的按钮背景颜色去掉  干掉所有人,内层for循环
                for (var i = 0; i < btns.length; i++) {
                    btns[i].style.backgroundColor = '';
                }
                // (2) 然后才让当前的元素背景颜色为pink 留下我自己
                this.style.backgroundColor = 'green';
            }
        }
        //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想
    </script>
</body>

8.换肤效果

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        body {
            background: url(images/1.jpg) no-repeat center top;
        }
        
        li {
            list-style: none;
        }
        
        .baidu {
            overflow: hidden;
            margin: 100px auto;
            background-color: #fff;
            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="images/1.jpg"></li>
        <li><img src="images/2.jpg"></li>
        <li><img src="images/3.jpg"></li>
        <li><img src="images/4.jpg"></li>
    </ul>
    <script>
        // 核心算法: 把当前图片的src 路径取过来,给 body 做为背景即可
        // 1. 获取元素 
        var imgs = document.querySelector('.baidu').querySelectorAll('img');
        // console.log(imgs);
        // 2. 循环注册事件 
        for (var i = 0; i < imgs.length; i++) {
            imgs[i].onclick = function() {
                // console.log(this.src);
                // this.src 就是我们点击图片的路径   images/2.jpg
                document.body.style.backgroundImage = 'url(' + this.src + ')';
                // 把这个路径 this.src 给body 就可以了
            }
        }
    </script>
</body>

 9.表格隔行变色

    <style>
        table {
            width: 800px;
            margin: 100px auto;
            text-align: center;
            border-collapse: collapse;
            font-size: 14px;
        }
        
        thead tr {
            height: 30px;
            background-color: skyblue;
        }
        
        tbody tr {
            height: 30px;
        }
        
        tbody td {
            border-bottom: 1px solid #d7d7d7;
            font-size: 12px;
            color: blue;
        }
        
        .bg {
            background-color: pink;
        }
    </style>
</head>

<body>
    <table>
        <thead>
            <tr>
                <th>代码</th>
                <th>名称</th>
                <th>最新公布净值</th>
                <th>累计净值</th>
                <th>前单位净值</th>
                <th>净值增长率</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
        </tbody>
    </table>
    <script>
        // 核心思路:鼠标经过 tr 行,当前的行变背景颜色
         //鼠标离开去掉当前的背景颜色
        // 注意:第一行(thead里面的行)不需要变换颜色,因此我们获取的是 tbody 里面的行
        // 1.获取元素 获取的是 tbody 里面所有的行
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        // 2. 利用循环绑定注册事件
        for (var i = 0; i < trs.length; i++) {
            // 3. 鼠标经过事件 onmouseover
            trs[i].onmouseover = function() {
                    // console.log(11);
                    this.className = 'bg';
                }
                // 4. 鼠标离开事件 onmouseout
            trs[i].onmouseout = function() {
                this.className = '';
            }
        }
    </script>
</body>

10.表单全选取消全选

    <style>
        * {
            padding: 0;
            margin: 0;
        }
        
        .wrap {
            width: 300px;
            margin: 100px auto 0;
        }
        
        table {
            border-collapse: collapse;
            border-spacing: 0;
            border: 1px solid #c0c0c0;
            width: 300px;
        }
        
        th,
        td {
            border: 1px solid #d0d0d0;
            color: #404060;
            padding: 10px;
        }
        
        th {
            background-color: #09c;
            font: bold 16px "微软雅黑";
            color: #fff;
        }
        
        td {
            font: 14px "微软雅黑";
        }
        
        tbody tr {
            background-color: #f0f0f0;
        }
        
        tbody tr:hover {
            cursor: pointer;
            background-color: #fafafa;
        }
    </style>

</head>

<body>
    <div class="wrap">
        <table>
            <thead>
                <tr>
                    <th>
                        <input type="checkbox" id="j_cbAll" />
                    </th>
                    <th>商品</th>
                    <th>价钱</th>
                </tr>
            </thead>
            <tbody id="j_tb">
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>iPhone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>iPad Pro</td>
                    <td>5000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>iPad Air</td>
                    <td>2000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>Apple Watch</td>
                    <td>2000</td>
                </tr>

            </tbody>
        </table>
    </div>
    <script>
        // 1. 全选和取消全选做法:  让下面所有复选框的checked属性(选中状态)
        //跟随 全选按钮即可

        // 获取元素:全选按钮,下面所有的复选框
        var j_cbAll = document.getElementById('j_cbAll');
        var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); 
        // 注册事件
        j_cbAll.onclick = function() {
                // this.checked 它可以得到当前复选框的选中状态如果是true 就是选中
                //如果是false 就是未选中
                console.log(this.checked);
                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() {
                // flag 控制全选按钮是否选中
                var flag = true;
                // 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中
                for (var i = 0; i < j_tbs.length; i++) {
                    if (!j_tbs[i].checked) {
                        flag = false;
                        break; // 退出for循环 这样可以提高执行效率 
                                //因为只要有一个没有选中,剩下的就无需循环判断了
                    }
                }
                j_cbAll.checked = flag;
            }
        }
    </script>

11.自定义属性操作(获得属性getAttribute,设置属性值setAttribute,移除属性removeAttribute)

<body>
    <div id="demo" index="1" class="nav"></div>
    <script>
        var div = document.querySelector('div');
        // 1. 获取元素的属性值

        // 方法(1) element.属性,只能获取内置属性如id,class
        console.log(div.id);

        //方法(2) element.getAttribute('属性')  get得到获取 attribute 属性的意思 
        //我们程序员自己添加的属性我们称为自定义属性 index
        console.log(div.getAttribute('id'));
        console.log(div.getAttribute('index'));

        

        // 2. 设置元素属性值

        // 方法(1) element.属性= '值'
        div.id = 'test';
        div.className = 'navs';

        // 方法(2) element.setAttribute('属性', '值');  主要针对于自定义属性
        div.setAttribute('index', 2);
        div.setAttribute('class', 'footer'); 
        // 注意:class 特殊 ,这里面写的就是class,不是className

        // 3 移除属性 removeAttribute(属性)    
        div.removeAttribute('index');
    </script>

12.自定义属性操作-tab栏切换案例

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        li {
            list-style-type: none;
        }
        
        .tab {
            width: 978px;
            margin: 100px auto;
        }
        
        .tab_list {
            height: 39px;
            border: 1px solid #ccc;
            background-color: #f1f1f1;
        }
        
        .tab_list li {
            float: left;
            height: 39px;
            line-height: 39px;
            padding: 0 20px;
            text-align: center;
            cursor: pointer;
        }
        
        .tab_list .current {
            background-color: #c81623;
            color: #fff;
        }
        
        .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>商品评价(50000)</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">
                商品评价(50000)模块内容
            </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循环绑定点击事件
        for (var i = 0; i < lis.length; i++) {
            // 开始给5个小li 设置索引号 
            lis[i].setAttribute('index', i);
            lis[i].onclick = function() {
                // 1. 上的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变
                //(排他思想) 修改类名的方式

                // 干掉所有人 其余的li清除 class 这个类
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = '';
                }
                // 留下我自己 
                this.className = 'current';
                // 2. 下面的显示内容模块
                var index = this.getAttribute('index');
                console.log(index);
                // 干掉所有人 让其余的item 这些div 隐藏
                for (var i = 0; i < items.length; i++) {
                    items[i].style.display = 'none';
                }
                // 留下我自己 让对应的item 显示出来
                items[index].style.display = 'block';
            }
        }
    </script>

13.H5自定义属性

<body>
    <div getTime="20" data-index="2" data-list-name="andy"></div>
    <script>
        var div = document.querySelector('div');
        //getTime为自定义属性,无法直接div.获取
        // console.log(div.getTime);

        //兼容性获取element.getAttribute('');
        console.log(div.getAttribute('getTime'));
        // h5新增的获取自定义属性的方法 它只能获取data-开头的        
        div.setAttribute('data-time', 20);
        console.log(div.getAttribute('data-index'));
        console.log(div.getAttribute('data-list-name'));


        // dataset是一个集合里面存放了所有以data开头的自定义属性,ie11以上才兼容
        console.log(div.dataset);
        console.log(div.dataset.index);
        console.log(div.dataset['index']);


        // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取驼峰命名法
        console.log(div.dataset.listName);
        console.log(div.dataset['listName']);
    </script>
</body>

节点操作

 1.节点概述

利用DOM树区分父子节点和兄弟节点

2.父节点操作(node.parentNode)

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
        // 1. 父节点 parentNode
        var erweima = document.querySelector('.erweima');
        // var box = document.querySelector('.box');


        // 得到的是离元素最近的父级节点(亲爸爸)
        // 如果找不到父节点就返回为 null
        console.log(erweima.parentNode);
    </script>
</body>

3.子节点操作(parentNode.childNodes和parentNode.children)

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>

    </ul>
    <ol>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ol>

    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
        // DOM 提供的方法(API)获取
        var ul = document.querySelector('ul');
        // var lis = ul.querySelectorAll('li');

        // 1. 子节点  childNodes 所有的子节点包含:元素节点、文本节点等等
        console.log(ul.childNodes);
        console.log(ul.childNodes[0].nodeType);
        console.log(ul.childNodes[1].nodeType);

        // 2. children 获取所有的子元素节点
        //是我们实际开发常用的,非标准,受到了各个浏览器支持
        console.log(ul.children);
    </script>

3.第一个和最后一个子节点(包括文本,元素),第一个子元素和最后一个子元素

<body>
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
        <li>我是li5</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        // 注意firstChild第一个子节点,不管是文本节点还是元素节点
        console.log(ol.firstChild);
        console.log(ol.lastChild);


        // 2. firstElementChild 返回第一个子元素节点,有兼容性问题:ie9才支持
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);


        // 3. 实际开发的写法 :既没有兼容性问题又返回第一个子元素
        console.log(ol.children[0]);
        //最后一个
        console.log(ol.children[ol.children.length - 1]);
    </script>
</body>

新浪下拉菜单案例

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        li {
            list-style-type: none;
        }
        
        a {
            text-decoration: none;
            font-size: 14px;
        }
        
        .nav {
            margin: 100px;
        }
        
        .nav>li {
            position: relative;
            float: left;
            width: 80px;
            height: 41px;
            text-align: center;
        }
        
        .nav li a {
            display: block;
            width: 100%;
            height: 100%;
            line-height: 41px;
            color: #333;
        }
        
        .nav>li>a:hover {
            background-color: #eee;
        }
        
        .nav ul {
            display: none;
            position: absolute;
            top: 41px;
            left: 0;
            width: 100%;
            border-left: 1px solid #FECC5B;
            border-right: 1px solid #FECC5B;
        }
        
        .nav ul li {
            border-bottom: 1px solid #FECC5B;
        }
        
        .nav ul li a:hover {
            background-color: #FFF5DA;
        }
    </style>
</head>

<body>
    <ul class="nav">
        <li>
            <a href="#">微博</a>
            <ul>
                <li>
                    <a href="">私信</a>
                </li>
                <li>
                    <a href="">评论</a>
                </li>
                <li>
                    <a href="">@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li>
                    <a href="">私信</a>
                </li>
                <li>
                    <a href="">评论</a>
                </li>
                <li>
                    <a href="">@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li>
                    <a href="">私信</a>
                </li>
                <li>
                    <a href="">评论</a>
                </li>
                <li>
                    <a href="">@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li>
                    <a href="">私信</a>
                </li>
                <li>
                    <a href="">评论</a>
                </li>
                <li>
                    <a href="">@我</a>
                </li>
            </ul>
        </li>
    </ul>
    <script>
        // 1. 获取元素
        var nav = document.querySelector('.nav');
        var lis = nav.children; //得到4个li

        //循环注册事件
        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>

4.兄弟节点

<body>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        // nextSibling 下一个兄弟节点,包含元素节点或者文本节点等等
        console.log(div.nextSibling);

        // 上一个兄弟节点
        console.log(div.previousSibling);


        // 2. nextElementSibling 得到下一个兄弟元素节点(有兼容性问题)
        console.log(div.nextElementSibling);

        // 上一个兄弟元素节点
        console.log(div.previousElementSibling);
    </script>

5.创建和添加节点(发布留言案例)

<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        // 1. 创建节点元素节点
        var li = document.createElement('li');

        // 2. 添加节点 node.appendChild(child)  node 父级  child 是子级 
        //后面追加元素  类似于数组中的push
        var ul = document.querySelector('ul');
        ul.appendChild(li);

        // 3. 添加节点 node.insertBefore(child, 指定元素);
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        // 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
    </script>
</body>

简单版发布留言案例

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        body {
            padding: 100px;
        }
        
        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }
        
        ul {
            margin-top: 50px;
        }
        
        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
</head>

<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>

    </ul>
    <script>
        // 1. 获取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注册事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您没有输入内容');
                return false;
            } else {
                // console.log(text.value);
                // (1) 创建元素
                var li = document.createElement('li');
                // 先有li 才能赋值
                li.innerHTML = text.value;
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
            }
        }
    </script

6.删除节点(删除留言案例)

<body>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        // 获取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');

        // 删除元素 node.removeChild
        // ul.removeChild(ul.children[0]);

        // 点击按钮依次删除里面的孩子节点
        btn.onclick = function() {
            if (ul.children.length == 0) {
                //禁用按钮
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }

        }
    </script>
</body>

 删除留言案例

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        body {
            padding: 100px;
        }
        
        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }
        
        ul {
            margin-top: 50px;
        }
        
        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }
        /* 让删除在右边 */
        
        li a {
            float: right;
        }
    </style>
</head>

<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>

    </ul>
    <script>
        // 1. 获取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注册事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您没有输入内容');
                return false;
            } else {
                // console.log(text.value);

                // (1) 创建元素
                var li = document.createElement('li');

                // 先有li 才能赋值
                // 阻止链接跳转需要添加javascript:void(0);或者javascript:;

                li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";

                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);

                // 删除元素,删除的是当前链接li 即a的父亲
                var as = document.querySelectorAll('a');
                for (var i = 0; i < as.length; i++) {
                    as[i].onclick = function() {
                        // node.removeChild(child);删除的是li,即node是li的父亲
                        ul.removeChild(this.parentNode);
                    }
                }

            }
        }
    </script>
</body>

7.克隆节点(动态生成表格案例)

<body>
    <ul>
        <li>1111</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // node.cloneNode();克隆节点,括号为空或里面是false浅拷贝,只复制标签不复制内容
        // 如果括号是true,深拷贝,则复制全部
        var lili = ul.children[0].cloneNode(true);
        // 克隆完要添加克隆的节点才显示
        ul.appendChild(lili);
    </script>
</body>

动态生成表格案例

   <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: 'JavaScript',
            score: 100
        }, {
            name: '弘历',
            subject: 'JavaScript',
            score: 98
        }, {
            name: '傅恒',
            subject: 'JavaScript',
            score: 99
        }, {
            name: '明玉',
            subject: 'JavaScript',
            score: 88
        }, {
            name: '大猪蹄子',
            subject: 'JavaScript',
            score: 0
        }];
        // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) {
            // 外面的for循环管行 tr
            // 1. 创建 tr行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);

            // 2. 行里面创建单元格(跟数据有关系的3个单元格) 
        //td 单元格的数量取决于每个对象里面的属性个数  for循环遍历对象 datas[i]

            // for(var k in obj) {
            //     k 得到的是属性名
            //     obj[k] 得到是属性值
            // }
            for (var k in datas[i]) {
                // 里面的for循环管列 td

                // 创建单元格 
                var td = document.createElement('td');

                // 把对象里面的属性值 datas[i][k] 给 td  
                td.innerHTML = datas[i][k];

                // 把单元格放入tr行中
                tr.appendChild(td);
            }
            // 3. 创建有删除2个字的单元格 
            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() {
                // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸)node.removeChild(child)  
                tbody.removeChild(this.parentNode.parentNode);
            }
        }
    </script>
</body>

8.三种创建元素方式区别

<body>
    <button>点击</button>
    <p>abc</p>
    <div class="inner"></div>
    <div class="create"></div>
    <script>
        // window.onload = function() {
        //         document.write('<div>123</div>');

        //     }

        // 三种创建元素方式区别 
        // 1. document.write() 创建元素 
        //如果页面文档流加载完毕,再调用这句话会导致页面重绘
        // var btn = document.querySelector('button');
        // btn.onclick = function() {
        //     document.write('<div>123</div>');
        // }

        // 2. innerHTML 创建元素
        var inner = document.querySelector('.inner');
        // for (var i = 0; i <= 100; i++) {
        //     inner.innerHTML += '<a href="#">百度</a>'
        // }
        // 通过数组形式拼接进行创建,效率最高,结构稍微复杂
        var arr = [];
        for (var i = 0; i <= 100; i++) {
            arr.push('<a href="#">百度</a>');
        }
        inner.innerHTML = arr.join('');

        // 3. document.createElement() 创建元素,效率稍低一点点,结构更清晰
        var create = document.querySelector('.create');
        for (var i = 0; i <= 100; i++) {
            var a = document.createElement('a');
            create.appendChild(a);
        }
    </script>
</body>

9.关于DOM操作

关于dom操作,我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。

 

 

事件高级

 1.注册事件的两种方式

<body>
    <button>传统注册事件</button>
    <button>方法监听注册事件</button>
    <button>ie9 attachEvent</button>
    <script>
        var btns = document.querySelectorAll('button');
        // 1. 传统方式注册事件,同一个事件只执行后面的,前面被覆盖
        btns[0].onclick = function() {
            alert('hi');
        }
        btns[0].onclick = function() {
            alert('hao a u');
        }

        // 2. 事件侦听注册事件 addEventListener 
        // (1) 里面的事件类型是字符串,必定加引号,而且不带on
        // (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
        btns[1].addEventListener('click', function() {
            alert(22);
        })
        btns[1].addEventListener('click', function() {
                alert(33);
            })
            // 3. attachEvent ie9以前的版本支持
        btns[2].attachEvent('onclick', function() {
            alert(11);
        })
    </script>
</body>

 2.删除事件

    <style>
        div {
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        var divs = document.querySelectorAll('div');
        divs[0].onclick = function() {
            alert(11);
            // 1. 传统方式删除事件
            divs[0].onclick = null;
        }

        // 2. removeEventListener 删除事件
        divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号

        function fn() {
            alert(22);
            divs[1].removeEventListener('click', fn);
        }

        // 3. detachEvent
        divs[2].attachEvent('onclick', fn1);

        function fn1() {
            alert(33);
            divs[2].detachEvent('onclick', fn1);
        }
    </script>
</body>

 3.DOM事件流

    <style>
        .father {
            overflow: hidden;
            width: 300px;
            height: 300px;
            margin: 100px auto;
            background-color: pink;
            text-align: center;
        }
        
        .son {
            width: 200px;
            height: 200px;
            margin: 50px;
            background-color: purple;
            line-height: 200px;
            color: #fff;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        // dom 事件流 三个阶段
        // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
        // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。

        // 3. 捕获阶段 如果addEventListener 第三个参数是 true
        // 那么则处于捕获阶段  document -> html -> body -> father -> son
        // var son = document.querySelector('.son');
        // son.addEventListener('click', function() {
        //     alert('son');
        // }, true);
        // var father = document.querySelector('.father');
        // father.addEventListener('click', function() {
        //     alert('father');
        // }, true);

        // 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略
        // 那么则处于冒泡阶段  son -> father ->body -> html -> document
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        document.addEventListener('click', function() {
            alert('document');
        })
    </script>
</body>

 4.事件对象

        // 事件对象
        var div = document.querySelector('div');
        div.onclick = function(e) {
                // console.log(e);
                // console.log(window.event);
                // e = e || window.event;
                console.log(e);


            }
            // div.addEventListener('click', function(e) {
            //         console.log(e);

        //     })
// 1. event 就是一个事件对象,写到我们侦听函数的 小括号里面,当形参来看

// 2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数

// 3. 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 
//比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,
//如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了哪个键

// 4. 这个事件对象我们可以自己命名,比如 event 、 evt、 e。

// 5. 事件对象也有兼容性问题 ie678 
//通过 window.event 兼容性的写法  e = e || window.event;

 5.事件对象的常见属性方法

    <script>
        // 常见事件对象的属性和方法
        // 1. e.target 返回的是触发事件的对象(元素)
        //  this 返回的是绑定事件的对象(元素)
        
        // 区别 : e.target 点击了哪个元素,就返回那个元素;
        //this 哪个元素绑定了这个点击事件,那么就返回谁
        var div = document.querySelector('div');
        div.addEventListener('click', function(e) {
            console.log(e.target);
            console.log(this);

        })
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
                // 我们给ul 绑定了事件  那么this 就指向ul  
                console.log(this);

                // e.target 指向我们点击的那个对象
           //谁触发了这个事件,我们点击的是li e.target 指向的就是li
                console.log(e.target);

        // 2. 了解 跟 this 有个非常相似的属性 currentTarget  ie678不认识
                console.log(e.currentTarget);

            })

            // 了解兼容性
            // div.onclick = function(e) {
            //     e = e || window.event;
            //     var target = e.target || e.srcElement;
            //     console.log(target);
            // }
    </script>

6.事件对象阻止默认行为(让链接不跳转或让提交按钮不提交等)

<body>
    <div>123</div>
    <a href="http://www.baidu.com">百度</a>
    <form action="http://www.baidu.com">
        <input type="submit" value="提交" name="sub">
    </form>
    <script>
        // 常见事件对象的属性和方法
        // 1. 返回事件类型
        var div = document.querySelector('div');
        div.addEventListener('click', fn);
        div.addEventListener('mouseover', fn);
        div.addEventListener('mouseout', fn);

        function fn(e) {
            console.log(e.type);

        }

        // 2. 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
            e.preventDefault(); //  dom 标准写法
        })

        // 3. 传统的注册方式
        a.onclick = function(e) {
            // 普通浏览器 e.preventDefault();  方法
            // e.preventDefault();

            // 低版本浏览器 ie678  returnValue  属性
            // e.returnValue;

            // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 
            // 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
            return false;
            alert(11);
        }
    </script>
</body>

7.阻止事件冒泡(点son不会影响father)

<body>
    <div class="father">
        <div class="son">son儿子</div>
    </div>
    <script>
        // 常见事件对象的属性和方法
        // 阻止冒泡  dom 推荐的标准 stopPropagation() (面试)
        var son = document.querySelector('.son');
        son.addEventListener('click', function(e) {
            alert('son');
            e.stopPropagation(); // stop 停止  Propagation 传播 
            e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
        }, false);

        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        document.addEventListener('click', function() {
            alert('document');
        })
    </script>
</body>

 8.事件委托

<body>
    <ul>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
    </ul>
    <script>
        // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            // alert('知否知否,点我应有弹框在手!');
            // e.target 这个可以得到我们点击的对象
            e.target.style.backgroundColor = 'pink';


        })
    </script>
</body>

9.常见鼠标事件

 

<body>
    我是一段不愿意分享的文字
    <script>
        // 1. contextmenu 我们可以禁用右键菜单
        document.addEventListener('contextmenu', function(e) {
            e.preventDefault();
        })

        // 2. 禁止选中文字 selectstart
        document.addEventListener('selectstart', function(e) {
            e.preventDefault();

        })
    </script>
</body>

 10.鼠标事件对象

    <style>
        body {
            height: 3000px;
        }
    </style>
</head>

<body>
    <script>
        // 鼠标事件对象 MouseEvent
        document.addEventListener('click', function(e) {
            // 1. client 鼠标在可视区的x和y坐标
            console.log(e.clientX);
            console.log(e.clientY);
            console.log('---------------------');

            // 2. page 鼠标在页面文档的x和y坐标
            console.log(e.pageX);
            console.log(e.pageY);
            console.log('---------------------');

            // 3. screen 鼠标在电脑屏幕的x和y坐标
            console.log(e.screenX);
            console.log(e.screenY);

        })
    </script>
</body>

 跟随鼠标案例

    <style>
        img {
            position: absolute;
            top: 2px;
        }
    </style>
</head>

<body>
    <img src="images/angel.gif" alt="">
    <script>
        var pic = document.querySelector('img');
        document.addEventListener('mousemove', function(e) {
            // 1. mousemove只要我们鼠标移动1px 就会触发这个事件
            // console.log(1);
            // 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标,
            // 把这个x和y坐标做为图片的top和left 值就可以移动图片
            var x = e.pageX;
            var y = e.pageY;
            console.log('x坐标是' + x, 'y坐标是' + y);
            //3 . 千万不要忘记给left 和top 添加px 单位
            pic.style.left = x - 50 + 'px';
            pic.style.top = y - 40 + 'px';


        });
    </script>

11.常用键盘事件


        // 常用的键盘事件
        //1. keyup 按键弹起的时候触发 
        // document.onkeyup = function() {
        //         console.log('我弹起了');

        //     }
        document.addEventListener('keyup', function() {
            console.log('我弹起了');
        })

        //3. keypress 按键按下的时候触发  不能识别功能键 比如 ctrl shift 左右箭头啊
        document.addEventListener('keypress', function() {
            console.log('我按下了press');
        })

        //2. keydown 按键按下的时候触发  能识别功能键 比如 ctrl shift 左右箭头啊
        document.addEventListener('keydown', function() {
                console.log('我按下了down');
            })
            // 4. 三个事件的执行顺序  keydown -- keypress -- keyup

12.键盘事件对象-keyCode属性

    <script>
        // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
        // 1. 我们的keyup 和keydown事件不区分字母大小写  a 和 A 得到的都是65
        // 2. 我们的keypress 事件 区分字母大小写  a  97 和 A 得到的是65
        document.addEventListener('keyup', function(e) {
            // console.log(e);
            console.log('up:' + e.keyCode);
            // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
            if (e.keyCode === 65) {
                alert('您按下的a键');
            } else {
                alert('您没有按下a键')
            }

        })
        document.addEventListener('keypress', function(e) {
            // console.log(e);
            console.log('press:' + e.keyCode);

        })
    </script>

13.键盘事件对象案例(模拟京东按键输入内容,模拟京东快递单查询)

案例1:模拟京东按键输入内容

<body>
    <input type="text">
    <script>
        // 核心思路: 检测用户是否按下了s 键,如果按下s 键,就把光标定位到搜索框里面
        // 使用键盘事件对象里面的keyCode 判断用户按下的是否是s键
        // 搜索框获得焦点: 使用 js 里面的 focus() 方法
        var search = document.querySelector('input');
        document.addEventListener('keyup', function(e) {
            console.log(e.keyCode);
            if (e.keyCode === 83) {
                search.focus();
            }
        })
    </script>
</body>

案例2:模拟京东快递单查询

当我们在文本框中输入内容时,文本框上面自动显示大字号的内容。

    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .search {
            position: relative;
            width: 178px;
            margin: 100px;
        }
        
        .con {
            display: none;
            position: absolute;
            top: -40px;
            width: 171px;
            border: 1px solid rgba(0, 0, 0, .2);
            box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
            padding: 5px 0;
            font-size: 18px;
            line-height: 20px;
            color: #333;
        }
        
        .con::before {
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            top: 28px;
            left: 18px;
            border: 8px solid #000;
            border-style: solid dashed dashed;
            border-color: #fff transparent transparent;
        }
    </style>
</head>

<body>
    <div class="search">
        <div class="con">123</div>
        <input type="text" placeholder="请输入您的快递单号" class="jd">
    </div>
    <script>
        // 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
        //同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
        //如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子 
        //注意: keydown 和 keypress 在文本框
         //里面的特点: 他们两个事件触发的时候,文字还没有落入文本框中。
        //keyup事件触发的时候, 文字已经落入文本框里面了
        //当我们失去焦点,就隐藏这个con盒子
        //当我们获得焦点,并且文本框内容不为空,就显示这个con盒子

        var con = document.querySelector('.con');
        // 表单检测用户输入: 给表单添加键盘事件
        var jd_input = document.querySelector('.jd');
        jd_input.addEventListener('keyup', function() {
            // console.log('输入内容啦');

            // 同时把快递单号里面的值(value)获取过来赋值
            //给 con盒子(innerText)做为内容,如果快递单号里面内容为空
            //则隐藏大号字体盒子(con)盒子
            if (this.value == '') {
                con.style.display = 'none';
            } else {
                con.style.display = 'block';
                con.innerText = this.value;
            }
        })

        // 当我们失去焦点,就隐藏这个con盒子
        jd_input.addEventListener('blur', function() {
                con.style.display = 'none';
            })
            // 当我们获得焦点,就显示这个con盒子
        jd_input.addEventListener('focus', function() {
            if (this.value !== '') {
                con.style.display = 'block';
            }
        })
    </script>

BOM

 BOM顶级对象

 window常见事件

1.窗口加载事件

        // window.onload = function() {
        //     var btn = document.querySelector('button');
        //     btn.addEventListener('click', function() {
        //         alert('点击我');
        //     })
        // }
        // window.onload = function() {
        //     alert(22);
        // }
        window.addEventListener('load', function() {
            var btn = document.querySelector('button');
            btn.addEventListener('click', function() {
                alert('点击我');
            })
        })
        window.addEventListener('load', function() {

            alert(22);
        })
        document.addEventListener('DOMContentLoaded', function() {
                alert(33);
            })
            // load 等页面内容全部加载完毕,包含页面dom元素 图片 flash  css 等等
            
            // DOMContentLoaded 是DOM 加载完毕,
            //不包含图片 falsh css 等就可以执行 加载速度比 load更快一些

2.调整窗口大小事件

    <script>
        window.addEventListener('load', function() {
            var div = document.querySelector('div');
            window.addEventListener('resize', function() {
                console.log(window.innerWidth);

                console.log('变化了');
                if (window.innerWidth <= 800) {
                    div.style.display = 'none';
                } else {
                    div.style.display = 'block';
                }

            })
        })
    </script>

定时器

1.setTimeout()定时器(5秒后自动关闭广告案例)

    <script>
        // 1. setTimeout 
        // 语法规范:  window.setTimeout(调用函数, 延时时间);
        // 1. 这个window在调用的时候可以省略
        // 2. 这个延时时间单位是毫秒 但是可以省略,如果省略默认的是0
        // 3. 这个调用函数可以直接写函数 还可以写 函数名 还有一个写法 '函数名()'
        // 4. 页面中可能有很多的定时器,我们经常给定时器加标识符 (名字)
        // setTimeout(function() {
        //     console.log('时间到了');

        // }, 2000);
        function callback() {
            console.log('爆炸了');

        }
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 5000);
        // setTimeout('callback()', 3000); // 我们不提倡这个写法
    </script>

5秒后自动关闭广告案例

<body>
    <img src="images/ad.jpg" alt="" class="ad">
    <script>
        var ad = document.querySelector('.ad');
        setTimeout(function() {
            ad.style.display = 'none';
        }, 5000);
    </script>
</body>

2. 停止 setTimeout() 定时器

<body>
    <button>点击停止定时器</button>
    <script>
        var btn = document.querySelector('button');
        var timer = setTimeout(function() {
            console.log('爆炸了');

        }, 5000);
        btn.addEventListener('click', function() {
            clearTimeout(timer);
        })
    </script>
</body>

3.setInterval() 定时器(倒计时案例)

    <script>
        // 1. setInterval 
        // 语法规范:  window.setInterval(调用函数, 延时时间);
        setInterval(function() {
            console.log('继续输出');

        }, 1000);
        // 2. setTimeout  延时时间到了,就去调用这个回调函数
        //只调用一次 就结束了这个定时器
        
        // 3. setInterval  每隔这个延时时间,就去调用这个回调函数
        //会调用很多次,重复调用这个函数
    </script>

倒计时案例

    <style>
        div {
            margin: 200px;
        }
        
        span {
            display: inline-block;
            width: 40px;
            height: 40px;
            background-color: #333;
            font-size: 20px;
            color: #fff;
            text-align: center;
            line-height: 40px;
        }
    </style>
</head>

<body>
    <div>
        <span class="hour">1</span>
        <span class="minute">2</span>
        <span class="second">3</span>
    </div>
    <script>
        // 1. 获取元素 
        var hour = document.querySelector('.hour'); // 小时的黑色盒子
        var minute = document.querySelector('.minute'); // 分钟的黑色盒子
        var second = document.querySelector('.second'); // 秒数的黑色盒子
        var inputTime = +new Date('2022-3-24 18:00:00'); // 返回的是用户输入时间总的毫秒数

        countDown(); // 我们先调用一次这个函数,防止第一次刷新页面有空白 

        // 2. 开启定时器
        setInterval(countDown, 1000);

        function countDown() {
            var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
            var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数 
            var h = parseInt(times / 60 / 60 % 24); //时
            h = h < 10 ? '0' + h : h;
            hour.innerHTML = h; // 把剩余的小时给 小时黑色盒子
            var m = parseInt(times / 60 % 60); // 分
            m = m < 10 ? '0' + m : m;
            minute.innerHTML = m;
            var s = parseInt(times % 60); // 当前的秒
            s = s < 10 ? '0' + s : s;
            second.innerHTML = s;
        }
    </script>
</body>

4.停止 setInterval() 定时器(发送短信案例)

<body>
    <button class="begin">开启定时器</button>
    <button class="stop">停止定时器</button>
    <script>
        var begin = document.querySelector('.begin');
        var stop = document.querySelector('.stop');

        var timer = null; // 全局变量  null是一个空对象
        begin.addEventListener('click', function() {
            timer = setInterval(function() {
                console.log('ni hao ma');

            }, 1000);
        })
        stop.addEventListener('click', function() {
            clearInterval(timer);
        })
    </script>
</body>

发送信息案例

<body>
    手机号码: <input type="number"> <button>发送</button>
    <script>
        // 按钮点击之后,会禁用 disabled 为true 
        // 同时按钮里面的内容会变化, 注意 button 里面的内容通过 innerHTML修改
        // 里面秒数是有变化的,因此需要用到定时器
        // 定义一个变量,在定时器里面,不断递减
        // 如果变量为0 说明到了时间,我们需要停止定时器,并且复原按钮初始状态
        var btn = document.querySelector('button');
        var time = 10; //定义剩下的秒数
        btn.addEventListener('click', function() {
            btn.disabled = true;
            var timer = setInterval(function() {
                if (time == 0) {
                    //清除定时器和复原按钮
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '发送';
                    time = 10;
                } else {
                    btn.innerHTML = '还剩下' + time + '秒';
                    time--;
                }


            }, 1000);
        })
    </script>
</body>

5.this指向问题

<body>
    <button>点击</button>
    <script>
        // this 指向问题 一般情况下this的最终指向的是那个调用它的对象

        // 1. 全局作用域或者普通函数中this指向全局对象window
//( 注意定时器里面的this指向window)
        console.log(this);

        function fn() {
            console.log(this);

        }
        window.fn();
        window.setTimeout(function() {
            console.log(this);

        }, 1000);

        // 2. 方法调用中谁调用this指向谁
        var o = {
            sayHi: function() {
                console.log(this); // this指向的是 o 这个对象

            }
        }
        o.sayHi();
        var btn = document.querySelector('button');
        // btn.onclick = function() {
        //     console.log(this); // this指向的是btn这个按钮对象

        // }
        btn.addEventListener('click', function() {
            console.log(this); // this指向的是btn这个按钮对象

        })


        // 3. 构造函数中this指向构造函数的实例
        function Fun() {
            console.log(this); // this 指向的是fun 实例对象

        }
        var fun = new Fun();
    </script>
</body>

Js执行机制

 1.同步和异步

 

 2.执行机制

 

 location常见对象

 window 对象给我们提供了一个 location 属性用于获取或设置窗体的 URL,并且可以用于解析 URL 。 因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象

1.URL

 2.location 对象的属性(5秒钟之后自动跳转页面案例)

 5秒钟之后自动跳转页面案例

<body>
    <button>点击</button>
    <div></div>
    <script>
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.addEventListener('click', function() {
            // console.log(location.href);
            location.href = 'http://www.itcast.cn';
        })
        var timer = 5;
        countdown();
        setInterval(countdown, 1000);

        function countdown() {
            if (timer == 0) {
                location.href = 'http://www.itcast.cn';
            } else {
                div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
                timer--;
            }

        }
    </script>
</body>

3.获取URL参数query

<body>
    <div></div>
    <script>
        console.log(location.search); // ?uname=andy
        // 1.先去掉?  substr('起始的位置',截取几个字符);
        var params = location.search.substr(1); // uname=andy
        console.log(params);
        // 2. 利用=把字符串分割为数组 split('=');
        var arr = params.split('=');
        console.log(arr); // ["uname", "ANDY"]
        var div = document.querySelector('div');
        // 3.把数据写入div中
        div.innerHTML = arr[1] + '欢迎您';
    </script>
</body>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // 记录浏览历史,所以可以实现后退功能
            // location.assign('http://www.itcast.cn');
            // 不记录浏览历史,所以不可以实现后退功能
            // location.replace('http://www.itcast.cn');
            location.reload(true);
        })
    </script>

4.location 对象的方法

<body>
    <button>点击</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // 记录浏览历史,所以可以实现后退功能
            // location.assign('http://www.itcast.cn');
            // 不记录浏览历史,所以不可以实现后退功能
            // location.replace('http://www.itcast.cn');
            location.reload(true);
        })
    </script>
</body>

navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是 userAgent,该属性可以返回由客户机发送服务器的 user-agent 头部的值。

1.判断用户所用终端打开页面,实现跳转到相应页面(例如从京东PC端首页跳转到手机端首页)

    <script>
        if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
            window.location.href = "../H5/index.html"; //手机
        }
    </script>

history 对象

window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的 URL。

<body>
    <a href="list.html">点击我去往列表页</a>
    <button>前进</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            // history.forward();
            history.go(1);
        })
    </script>
</body>

history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值