JavaScript(day2)BOM

目录

 

页面加载事件 

调整窗口大小事件

定时器

setTimeout()定时器

停止setTimeout计时器

setInterval()定时器

倒计时效果

清除setInterval定时器

 发送短信案例

this 指向问题

 同步和异步

同步

异步

任务队列

事件循环(event loop)

简述setTimeout中的输出事件的执行:

setTimeout中的输出事件实例:

解决同时输出方法 

同步任务和异步任务执行过程


 

页面加载事件 

64e1ed7fa7164694bc7f78a8ce3fe319.png


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

        // }
        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);
        })
    </script>
</head>
<body>
    <button>点击</button>
</body>

调整窗口大小事件

787915595db948e99d19b396534aaede.png

 


<body>
    <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>
    <div></div>
</body>

定时器

setTimeout()定时器

233704c5fb2e4c2194ae03739457b86d.png

<script>
        function callback(){
            console.log('爆炸了');
        }
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 6000);
        var timer3 = setTimeout(function call(){
            console.log('bomb');
        },8000);
    </script>

停止setTimeout计时器

ebfaec08a9614ad89861202d4481f45d.png

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

setInterval()定时器

6663acf4e58c477085e0c599749aab9c.png

<script>
        setInterval(function(){
            console.log('继续输出');
        },2000);
    </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>

    <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-9-11 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>

清除setInterval定时器

b936c65146364b1fa02dc3b20d5f1bcc.png

<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 = 3; // 定义剩下的秒数
        btn.addEventListener('click', function() {
            btn.disabled = true;
            var timer = setInterval(function() {
                if (time == 0) {
                    // 清除定时器和复原按钮
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '发送';
                } else {
                    btn.innerHTML = '还剩下' + time + '秒';
                    time--;
                }
            }, 1000);

        })
    </script>
</body>

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();

8ff9a889a1ce4031a8570dea269eed3d.png

 同步和异步

为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。于是,JavaScript就出现了同步和异步。

同步

同步任务是在主线程(这个线程用来解释和执行 JavaScript 代码)上排队执行的任务。

异步

异步任务:不进入主线程、而进入任务队列的任务。只有当主线程上的所有同步任务执行完毕之后,主线程才会读取任务队列,将任务放到执行栈,开始执行任务。(例如:ajax请求、io操作、setTimeout等事件调用的回调函数)。

任务队列

当遇到计时器(setTimeout)、DOM事件监听或者是网络请求的任务时,JS引擎会将它们直接交给 webapi,也就是浏览器提供的相应线程(如定时器线程为setTimeout计时、异步http请求线程处理网络请求)去处理,而JS引擎线程继续后面的其他任务,这样便实现了 异步非阻塞。

定时器触发线程也只是为 setTimeout(…, 1000) 定时而已,时间一到(1s过后),还会把它对应的回调函数(callback)交给 任务队列 去维护,JS引擎线程会在适当的时候去任务队列取出任务并执行。

所以我们可以说:任务队列存储了来自webapi的回调函数,这些函数等待被系统调用到执行栈(也就是主线程)上去运行。


事件循环(event loop)

js引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将这个事件挂起(交给webapi处理),继续执行执行栈中的其他任务。当一个异步事件返回结果后(例如延时时间到了、ajax得到结果了等),js会将这个事件加入与当前执行栈不同的另一个队列,我们称之为任务(事件)队列。被放入任务队列不会立刻执行其回调,而是等待当前执行栈中的所有任务都执行完毕, 主线程处于闲置状态时,主线程会去查找事件队列是否有任务。如果有,那么主线程会从中取出排在第一位的事件,并把这个事件对应的回调放入执行栈中,然后执行其中的同步代码…,如此反复,这样就形成了一个无限的循环。这就是这个过程被称为“事件循环(Event Loop)”的原因。


简述setTimeout中的输出事件的执行:

1. 首先在主线程上,运行到setTimeout函数时,把它交给webapi处理。
2. wepapi对setTimeout函数进行处理,即1s后,setTimeout的延时任务完成,应该调用回调函数(输出)了。但并不会立即将回调函数送入主线程,不然就会乱套,得排队。
3. 1s后,webapi将setTimeout(consloe.log(i))交给任务队列,此时setTimeout函数在任务队列中排队。
4. 当主线程中所有任务完成后,此时将任务队列的排第一事件(setTimeout)取出来放到执行栈中去执行,运行其中的同步函数(回调函数)。
5. 当输出运行完以后,如果任务队列不为空,又将排第一的事件取出来执行,如此往复,就形成了上述的事件循环(event loop)。

setTimeout中的输出事件实例:

 for(var i = 0; i < 10; i++){
    setTimeout(()=>{
        console.log(i);
    }, 1000*i)
}
/**
 * 实际输出:
 * 输出:
 * 10(立刻输出)
 * 10(1s)
 * 10(2s)
 * 10(3s)
 * 10(4s)
 * 10(5s)
 * 10(6s)
 * 10(7s)
 * 10(8s)
 * 10(9s)
 */

解决同时输出方法 

使用let定义i,此时i的作用域便不是全局了

 for(let i = 0; i < 10; i++){
    setTimeout(()=>{
        console.log(i);
    }, 1000*i)
}
/**
 * 实际输出:
 * 输出:
 * 0(立刻输出)
 * 1(1s)
 * 2(2s)
 * 3(3s)
 * 4(4s)
 * 5(5s)
 * 6(6s)
 * 7(7s)
 * 8(8s)
 * 9(9s)
 */

同步任务和异步任务执行过程

<script>
        // 第一个问题
        // console.log(1);

        // setTimeout(function() {

        //     console.log(3);

        // }, 1000);

        // console.log(2);

        // 2. 第二个问题
        // console.log(1);

        // setTimeout(function() {

        //     console.log(3);

        // }, 0);

        // console.log(2);

        // 3. 第三个问题

        console.log(1);
        document.onclick = function() {
            console.log('click');
        }
        console.log(2);
        setTimeout(function() {
            console.log(3)
        }, 3000)
    </script>

 location常见属性

1cc70676f4a64d2e991d20bdd95d740d.png

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

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

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java码蚁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值