WEB API-BOM要点

本文详细讲解了浏览器对象模型BOM的基本概念,包括其与DOM的关系、窗口对象的使用、页面加载事件(load和DOMcontentLoaded)、窗口大小调整、定时器的运用、location对象和navigator对象的功能,以及移动触摸事件和本地存储(sessionStorage和localStorage)。通过实例演示了轮播图制作和动画封装技巧。
摘要由CSDN通过智能技术生成

1.BOM概述

BOM即浏览器对象墨香,他提供了独立于内容而与浏览器窗口进行交互的对象。其核心对象是window。

BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。

  1. BOM与DOM的关系

BOM比DOM大。BOM包含DOM.

     2.BOM的顶级对象Window

   (1)他是js访问浏览器窗口的一个接口。

 (2)他是一个全局对象,定义在全局作用域的变量中,函数都会变成window对象的属性和方法。在调用的时候可以省略window。

alert()、prompt()等都是问对的对象方法。

2.页面加载事件

      在之前的学习中,我们始终无法解决如何把script标签放在元素的前面这个问题,但是现在学习了页面加载事件以后我们就可以把script标签想放在哪里就放在那里了。

     页面加载事件有两种方式

1.load

 他的特点是他需要等页面中所有的标签动画等都加载完毕之后在才执行script标签内的。

 window.addEventListener('load',function(){

        })

2.DOMcontentLoaded

  他的特点是:只需要等页面中主要的标签加载完毕,即可执行script里面的。他的优点是,如果页面有的图片有很多的话,从用户访问到load触发可能需要很长时间,那么交互效果就不能实现,必然影响用户体验,所以此时我们就可以用DOMcontentLoaded了。

   window.addEventListener('DOMcontentLoaded',function(){
            
        })

 

3.调整窗口大小事件

只要窗口的大小发生变化就会触发里面的函数。

我们经常利用这个事件来完成响应式布局。

window.innerWidth可以获得当前屏的宽度

  window.addEventListener('load', function() {
            //调整窗口大小事件
            window.addEventListener('resize', function() {
                console.log(window.innerWidth);
                //window.innerWidth 当前屏幕的宽度
            })
        })

4.定时器

1.setTimeout

   延迟几秒执行。只能执行一次。

  setTimeout(function() {
                alert('我是一秒后执行');
            }, 1000)

//函数调用的写法
     function back() {
            alert('嗨')
        }
        setTimeout(back, 2000)

2.setInterval

每隔多长时间执行一次。可以执行多次。


            setInterval(function() {
                console.log('每1秒来一次');
            }, 1000)

3.案例

5秒后自动跳转

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

<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>Document</title>
    <script>
        window.addEventListener('load', function() {
            var btn = document.querySelector('button')
            var div = document.querySelector('div');
            btn.addEventListener('click', function() {
                //点击立即跳转
                location.href = 'http://www.baidu.com'

            })
            var timer = 5;
            setInterval(function() {
                if (timer == 0) {
                    location.href = "http://www.baidu.com";
                } else {
                    div.innerHTML = '您将在' + timer + '秒钟后跳转';
                    timer--;
                }
            }, 1000)
        })
    </script>
</head>

<body>
    <button>点击返回首页</button>
    <div></div>

</body>

</html>

缓动动画

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

<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>Document</title>
    <style>
        div {
            position: absolute;
            left: 0;
            width: 300px;
            height: 300px;
            background-color: pink;
        }
    </style>
    <script>
        //缓动动画就是让元素慢慢的停下来的动画.
        //原理是 让动画每次移动的距离慢慢变小.
        //核心公式:(目标位置-现在的位置)/10
        //然后如果现在的位置等于目标则停定时器
        //步长值取整不然会有到不了目标值的bug。所以要向上取整。Math.ceil
        //回调函数,当作实惨传给形参。写在定时结束里面
        window.addEventListener('load', function() {
            var div = document.querySelector('div');

            function times(obj, tiaojian, callback) {
                clearInterval(obj.timer)
                obj.timer = setInterval(function() {
                    //步长写在定时器的里面.记得将步长值取整不然会有到不了目标值的bug。所以要向上取整。Math.ceil
                    var step = Math.ceil((tiaojian - obj.offsetLeft) / 10)
                    if (obj.offsetLeft == tiaojian) {
                        clearInterval(obj.timer);
                        if (callback) { //如果有callback这个函数就调用这个函数
                            callback(); //写在定时器的里面时等定时器结束才执行的。
                        }
                    } else {
                        obj.style.left = obj.offsetLeft + step + 'px'
                    }
                }, 15)
            }
            times(div, 500, function() { //第三个实参写的是一个函数。
                div.style.backgroundColor = 'red'
            })
        })
    </script>
</head>

<body>
    <div></div>
</body>

</html>

5.this指向问题

1.全局作用域或普通函数中this指向window.定时器也指向window。

2.方法中调用是 谁调用指向谁。

3.构造函数中this指向构造函数的实例化。

6.同步和异步及js的执行机制

同步,通俗来说就是同一时间只能干一件事。

异步就是在同一时间可以干很多事。

js的执行机制: 

js从上往下开始执行,遇到异步任务(click 函数 定时器等),会把异步任务放到任务队列中,先去执行同步任务,执行完毕后,回到任务队列中查看有无需执行的异步任务,如果有则按顺序执行,执行完再回来看有没有需要执行的异步任务,一直到任务队列中的异步任务全部执行完毕。

这个不断回去查看有无异步任务,去执行任务,在查看获取任务,执行任务的过程被称为事件循环。

 

7.location对象常见属性

var button = document.querySelector('button')
            button.addEventListener('click', function() {
                location.href = 'http://www.baidu.com' //获取或设置整个url地址
              location.host//返回主机域名
              location.port//返回端口号
              location.pathname//返回路径
              location.search//返回参数
              location.hash//返回片段
            })

 

 案例:

两个页面,获取第一个页面中的参数,显示到第二个页面中来

//第一个页面写好表单,并连接到第二个界面
   <form action="index.html">
        用户名: <input type="text" name="uname">
        <input type="submit" value="登录">
    </form>
 //第二个页面,用search属性获取参数,并进行分割。
 <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>

 

8.navigator对象

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

   下面代码可以判断用户打开的终端是移动端还是pc端并实现跳转。

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 = "";     //手机
 } else {
    window.location.href = "";     //电脑
 }

9.history对象

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

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


        back() //可以后退功能
        forward() //可以前进功能
        go(1) //前进后退功能 参数如果是1前进1个页面 -1后退一个页面

10.offset系列

 注意点:transform:reanslate在offset系列里面计算不到。

  var btn = document.querySelector('button')
            var div = document.querySelector('div')
            btn.addEventListener('click', function() {
                console.log(div.offsetWidth); //返回 自身的宽,包括padding和border
                console.log(div.offsetHeight); //返回 自身的高,包括padding和border
                console.log(div.offsetLeft); //返回 距离最近一级有定位的父亲的左边偏移量
                console.log(div.offsetTop); //返回 距离最近一级有定位的父亲的上边偏移量
            })

11.client系列

 btn.addEventListener('click', function() {
                console.log(div.clientWidth); //返回 自身的宽,包括padding但不包括border
                console.log(div.clientHeight); //返回 自身的高,包括padding但不包括border
                console.log(div.clientLeft); //返回 左边框的宽度
                console.log(div.clientTop); //返回 上边框的宽度
            })

12.scroll系列

使用scroll系列相关的属性,可以动态的得到该元素的大小,滚动距离。

补充一个 window.scroll(x,y)滚动至文档中指定位置,不跟单位。

 btn.addEventListener('click', function() {
                console.log(div.scrollTop); //返回 元素内容被卷去的头部。
                console.log(div.scrollLeft); //返回 元素内容被卷去的左侧。
                console.log(div.scrollWidth); //返回 自身实际的宽,包括padding但不包括border
                console.log(div.scrollHeight); //返回 自身实际的高,包括padding但不包括border
            })

三大系列总结

offset系列主要用于获取元素位置 offsetTop /  offsetLeft

client系列主要用于获取元素的大小 clienWidth / clientHeight

scroll系列主要用于获取滚动的距离  scrollTop / scrollLeft'

页面滚动的距离是window.pageXoffset /  window.pageYoffset。要注意区别于scroll系列。 

13.定时器封装动画

动画的本质就是利用setInterval动画不断地移动盒子。

   // 简单动画函数封装obj目标对象 target 目标位置
        // 给不同的元素指定了不同的定时器
        function animate(obj, target) {
            // 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
            // 解决方案就是 让我们元素只有一个定时器执行
            // 先清除以前的定时器,只保留当前的一个定时器执行
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                if (obj.offsetLeft >= target) {
                    // 停止动画 本质是停止定时器
                    clearInterval(obj.timer);
                }
                obj.style.left = obj.offsetLeft + 1 + 'px';

            }, 30);
        }

        var div = document.querySelector('div');
        var span = document.querySelector('span');
        var btn = document.querySelector('button');
        // 调用函数
        animate(div, 300);
        btn.addEventListener('click', function() {
            animate(span, 200);
        })

缓动动画

原理是利用定时器和定义一个步长的变量让他在相同的事件移动不同的距离。


            //缓动动画
            function move(obj, target, callback) {
                clearInterval(obj.timer);//开始之前先清除上一次的定时器,防止重复执行
                obj.timer = setInterval(function() {
                    var step = (target - obj.offsetLeft) / 10; //计算步长 每次执行定时器,步长则减少一点
                    step = step > 0 ? Math.ceil(step) : Math.floor(step);//对步长进行取整。避免因为小数问题到不了终点
                    if (obj.offsetLeft >= target) {//终止定时器的条件
                        clearInterval(obj.timer);
                        callback && callback()//利用短路& 查看是否有回调函数,如果有则执行。
                    }
                    obj.style.left = obj.offsetLeft + step + 'px'
                }, 30)
            }
            move(div, 200)//调用函数

 

14.轮播图

重在理解思路,以后会用插件来做

window.addEventListener('load', function() {

    // 1. 获取元素

    var arrow_l = document.querySelector('.arrow-l');

    var arrow_r = document.querySelector('.arrow-r');

    var focus = document.querySelector('.focus');

    var focusWidth = focus.offsetWidth;

    // 2. 鼠标经过focus 就显示隐藏左右按钮

    focus.addEventListener('mouseenter', function() {

        arrow_l.style.display = 'block';

        arrow_r.style.display = 'block';

        clearInterval(timer);

        timer = null; // 清除定时器变量

    });

    focus.addEventListener('mouseleave', function() {

        arrow_l.style.display = 'none';

        arrow_r.style.display = 'none';

        timer = setInterval(function() {

            //手动调用点击事件

            arrow_r.click();

        }, 2000);

    });

    // 3. 动态生成小圆圈  有几张图片,我就生成几个小圆圈

    var ul = focus.querySelector('ul');

    var ol = focus.querySelector('.circle');

    // console.log(ul.children.length);

    for (var i = 0; i < ul.children.length; i++) {

        // 创建一个小li

        var li = document.createElement('li');

        // 记录当前小圆圈的索引号 通过自定义属性来做

        li.setAttribute('index', i);

        // 把小li插入到ol 里面

        ol.appendChild(li);

        // 4. 小圆圈的排他思想 我们可以直接在生成小圆圈的同时直接绑定点击事件

        li.addEventListener('click', function() {

            // 干掉所有人 把所有的小li 清除 current 类名

            for (var i = 0; i < ol.children.length; i++) {

                ol.children[i].className = '';

            }

            // 留下我自己  当前的小li 设置current 类名

            this.className = 'current';

            // 5. 点击小圆圈,移动图片 当然移动的是 ul

            // ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 注意是负值

            // 当我们点击了某个小li 就拿到当前小li 的索引号

            var index = this.getAttribute('index');

            // 当我们点击了某个小li 就要把这个li 的索引号给 num  

            num = index;

            // 当我们点击了某个小li 就要把这个li 的索引号给 circle  

            circle = index;

            // num = circle = index;

            console.log(focusWidth);

            console.log(index);

            animate(ul, -index * focusWidth);

        })

    }

    // 把ol里面的第一个小li设置类名为 current

    ol.children[0].className = 'current';

    // 6. 克隆第一张图片(li)放到ul 最后面

    var first = ul.children[0].cloneNode(true);

    ul.appendChild(first);

    // 7. 点击右侧按钮, 图片滚动一张

    var num = 0;

    // circle 控制小圆圈的播放

    var circle = 0;

    // flag 节流阀

    var flag = true;

    arrow_r.addEventListener('click', function() {

        if (flag) {

            flag = false; // 关闭节流阀

            // 如果走到了最后复制的一张图片,此时 我们的ul 要快速复原 left 改为 0

            if (num == ul.children.length - 1) {

                ul.style.left = 0;

                num = 0;

            }

            num++;

            animate(ul, -num * focusWidth, function() {

                flag = true; // 打开节流阀

            });

            // 8. 点击右侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放

            circle++;

            // 如果circle == 4 说明走到最后我们克隆的这张图片了 我们就复原

            if (circle == ol.children.length) {

                circle = 0;

            }

            // 调用函数

            circleChange();

        }

    });

    // 9. 左侧按钮做法

    arrow_l.addEventListener('click', function() {

        if (flag) {

            flag = false;

            if (num == 0) {

                num = ul.children.length - 1;

                ul.style.left = -num * focusWidth + 'px';

            }

            num--;

            animate(ul, -num * focusWidth, function() {

                flag = true;

            });

            // 点击左侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放

            circle--;

            // 如果circle < 0  说明第一张图片,则小圆圈要改为第4个小圆圈(3)

            // if (circle < 0) {

            //     circle = ol.children.length - 1;

            // }

            circle = circle < 0 ? ol.children.length - 1 : circle;

            // 调用函数

            circleChange();

        }

    });

    function circleChange() {

        // 先清除其余小圆圈的current类名

        for (var i = 0; i < ol.children.length; i++) {

            ol.children[i].className = '';

        }

        // 留下当前的小圆圈的current类名

        ol.children[circle].className = 'current';

    }

    // 10. 自动播放轮播图

    var timer = setInterval(function() {

        //手动调用点击事件

        arrow_r.click();

    }, 2000);

})

涉及知识点 :

  1. transtionend  监听过渡完成的事件
  2. classList属性 返回元素类名
  • 删除类名  element . classList.remove('类名')
  • 添加类名  element . classList.add('类名')
  • 切换类名  element . classList.toggle('类名')

15.移动端touch事件

   div.addEventListener('touchstart', function() {
                console.log('我被手指触摸了');
            })

            div.addEventListener('touchmove', function() {
                console.log('我被手指按着移动了');
            })
            div.addEventListener('touchend', function() {
                console.log('手指拿走了');
            })

touch触摸事件对象

  div.addEventListener('touchstart', function(e) {
                console.log(e.touches);//返回触摸屏幕的手指列表
                console.log(e.targetTouches);//返回触摸元素的手指列表
                console.log(e.changedTouches);//返回手指装填发生了变化的列表
            })

16.本地储存

1.sessionStorage 临时存储

  • 生命周期为关闭浏览器窗口
  • 在同一窗口下数据可共享
  • 以键值对的形式存储
  • 提供的API 有以下几个
 <input type="text">
    <button class="set">存储数据</button>
    <button class="get">获取数据</button>
    <button class="remove">删除数据</button>
    <button class="del">清空所有数据</button>
    <script>
        // console.log(localStorage.getItem('username'));

        var ipt = document.querySelector('input');
        var set = document.querySelector('.set');
        var get = document.querySelector('.get');
        var remove = document.querySelector('.remove');
        var del = document.querySelector('.del');
        set.addEventListener('click', function() {
            // 当我们点击了之后,就可以把表单里面的值存储起来
            var val = ipt.value;
            sessionStorage.setItem('uname', val);
            sessionStorage.setItem('pwd', val);
        });
        get.addEventListener('click', function() {
            // 当我们点击了之后,就可以把表单里面的值获取过来
            console.log(sessionStorage.getItem('uname'));

        });
        remove.addEventListener('click', function() {
            // 
            sessionStorage.removeItem('uname');

        });
        del.addEventListener('click', function() {
            // 当我们点击了之后,清除所有的
            sessionStorage.clear();

        });
    </script>

2.localStorage 永久存储

  • 生命周期永久,除非手动清除,否则关闭页面也存在
  • 可以多窗口共享多页面,同一浏览器可以共享
  • 以键值对的形式存储
  • 提供的API与上面一致
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <input type="text">
    <button class="set">存储数据</button>
    <button class="get">获取数据</button>
    <button class="remove">删除数据</button>
    <button class="del">清空所有数据</button>
    <script>
        var ipt = document.querySelector('input');
        var set = document.querySelector('.set');
        var get = document.querySelector('.get');
        var remove = document.querySelector('.remove');
        var del = document.querySelector('.del');
        set.addEventListener('click', function() {
            var val = ipt.value;
            localStorage.setItem('username', val);
        })
        get.addEventListener('click', function() {
            console.log(localStorage.getItem('username'));

        })
        remove.addEventListener('click', function() {
            localStorage.removeItem('username');

        })
        del.addEventListener('click', function() {
            localStorage.clear();

        })
    </script>
</body>

</html>

案例:记住用户名

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <input type="text" id="username"> <input type="checkbox" name="" id="remember"> 记住用户名
    <script>
        var username = document.querySelector('#username');
        var remember = document.querySelector('#remember');
        if (localStorage.getItem('username')) {
            username.value = localStorage.getItem('username');
            remember.checked = true;
        }
        remember.addEventListener('change', function() {
            if (this.checked) {
                localStorage.setItem('username', username.value);
            } else {
                localStorage.removeItem('username');
            }
        })

        // console.log(localStorage.getItem('username'));
    </script>
</body>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值