前端复习——js(三)

BOM

BOM概述

BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。

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

BOM 缺乏标准,JavaScript 语法的标准化组织是 ECMA, DOM 的标准化组织是 W3C, BOM最初是Netscape 浏览器标准的一部分。

DOM与BOM的对比:

DOMBOM
文档对象模型浏览器对象模型
DOM 就是把文档当作一个对象来看待浏览器当作一个对象来看待
DOM 的顶级对象是documentBOM 的顶级对象是window
DOM 主要学习的是操作页面元素BOM 学习的是浏览器窗口交互的一些对象
DOM 是 W3C 标准规范BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差
BOM的构成

BOM 比 DOM 更大。它包含 DOM。

window.document.querySelect();

在这里插入图片描述
window对象是浏览器的顶级对象,它具有双重角色。

  1. 它是 JS 访问浏览器窗口的一个接口。
  2. 它是一个全局对象。定义在全局作用域中的变量、函数都会变成 window对象的属性和方法。

在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert()、prompt()等。

注意:window下的一个特殊属性 window.name

// 定义在全局作用域中的变量会变成window对象的属性
var num = 10;
console.log(window.num);// 10
// 定义在全局作用域中的函数会变成window对象的方法
function fn() {
    console.log(11);
}
console.fn();// 11
var name = 10;  //不要用这个name变量,window下有一个特殊属性window.name
console.log(window.num);

window对象的常见事件

window.onload = function(){};
// 或者
window.addEventListener("load",function(){});

window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像,脚本文件,CSS文件等),就调用的处理函数。

注意:

  1. 有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数。
  2. window.onload传统注册事件方式,只能写一次,如果有多个,会以最后一个window.onload为准。
  3. 如果使用addEventListener则没有限制。
<script>
    window.onload = function() {
         var btn = document.querySelector('button');
         btn.addEventListener('click', function() {
             alert('点击我');
         })
    }
    window.onload = function() {
         alert(22);//冲突
    }
</script>
<button>点击</button>
document.addEventListener('DOMContentLoaded',function(){})
  1. DOMCountentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。
  2. ie9以上支持。
  3. 如果页面的图片很多的话, 从用户访问到onload触发可能需要较长的时间。
  4. 交互效果就不能实现,必然影响用户的体验,此时用 DOMContentLoaded事件比较合适。
<script>
    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更快一些
</script>
调整窗口大小事件
window.onresize = function() {};
// 或者
window.addEventListener('resize',function(){});

window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。

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

注意:

  • 只要窗口大小发生像素变化,就会触发这个事件
  • 我们经常利用这个事件完成响应式布局。window.innerWidth当前屏幕的宽度

定时器

window 对象给我们提供了两个定时器

  • setTimeout()
  • setInterval()
setTimeout()定时器
window.setTimeout(调用函数,[延迟的毫秒数]);

setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。

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

注意:

  1. window可以省略。
  2. 这个调用函数可以直接写函数,或者写函数名,或者采取字符串 ‘函数名()’ (不推荐)。
  3. 延迟的毫秒数省略默认是0,如果写,必须是毫秒。
  4. 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。

setTimeout()这个调用函数我们也称为回调函数callback,普通函数是按照代码顺序直接调用,而这个函数,需要等待事件,事件到了才会去调用这个函数,因此称为回调函数。

案例:5秒钟之后关闭的广告

<body>
	<img src="images/ad.jpg" alt="" class="ad">
	<script>
		var ad = docment.querySelector('.ad');
		setTimeout(function() {
			ad.style.display = 'none';
		},5000);
	</script>
</body>
停止setTimeout()定时器
window.clearTimeout(timeoutID)

clearTimeout()方法取消了先前通过调用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>

注意:

  • window可以省略
  • 里面的参数就是定时器的标识符
setInterval()定时器
window.setInterval(回调函数,[间隔的毫秒数]);

setInterval()方法重复调用一个函数,每隔这个时间,就去调用一次回调函数。

  • window可以省略。
  • 这个回调函数可以直接写函数或者写函数名,或者采取字符‘函数名()’三种形式。
  • 间隔的毫秒数省略默认是0,如果写,必须是毫秒,表示每隔多少毫秒,表示每隔多少毫秒就自动调用这个函数。
  • 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。
<body>
    <script>
        // 1. setInterval 
        // 语法规范:  window.setInterval(调用函数, 延时时间);
        setInterval(function() {
            console.log('继续输出');
        }, 1000);
        // 2. setTimeout  延时时间到了,就去调用这个回调函数,只调用一次 就结束了这个定时器
        // 3. setInterval  每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
    </script>
</body>

案例:倒计时

<body>
	<div>
		<span class="hour">1</span>
		<span class="minute">2</span>
		<span class="second">3</span>
	</div>
	<script>
		var hour = document.querySelector('.hour');//小时的黑色盒子
		var minute = document.querySelector('.minute');//分钟的黑色盒子
		var second = document.querySelector('.second');//秒的黑色盒子
		var inputTime = +new Date('2022-4-13 18:00:00'); // 返回的是用户输入时间的总毫秒数
		setInterval(countDown, 1000);
		function countDown() {
		    var nowTime = +new Date(); //没有参数,返回的是当前时间总的毫秒数
		    var times = (inputTime - nowTime) / 1000; //times就是剩余时间的总的秒数
		    var h = parseInt(times / 60 / 60 % 24); //小时
		    h < 10 ? '0' + h : h;
		    hour.innerHTML = h; //把剩余的小时给小时黑盒子
		    var m = parseInt(times / 60 % 60); //分
		    m < 10 ? '0' + m : m;
		    minute.innerHTML = m; //把剩余的分钟给分支黑盒子
		    var s = parseInt(times % 60); //秒
		    s < 10 ? '0' + s : s;
		    second.innerHTML = s; //把剩余的秒数给秒数黑盒子
		}
	</script>
</body>
clearInterval()停止定时器

clearInterval( )方法取消了先前通过调用setInterval()建立的定时器。

注意:

  • window可以省略
  • 里面的参数就是定时器的标识符
<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>

案例:点击后60s内不能发送短信

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

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁。

现阶段,我们先了解一下几个this指向:

  • 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)。
  • 方法调用中谁调用this指向谁。
  • 构造函数中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执行队列

js同步和异步

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为Javascript这门脚本语言诞生的使命所致——JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

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

同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的,同步的,比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。

异步:你在做一件事情的时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情,比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。

他们的本质区别:这条流水线上各个流程的执行顺序不同。
在这里插入图片描述
结果:1、2、3

同步任务:同步任务都在主线程上执行,形成一个执行栈
在这里插入图片描述
异步任务: JS中的异步是通过回调函数实现的。

异步任务有以下三种类型:

  1. 普通事件,如click,resize等。
  2. 资源加载,如load,error等。
  3. 定时器,包括setInterval,setTimeout等。

异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)。

在这里插入图片描述
JS执行机制:

  1. 先执行执行栈中的同步任务
  2. 异步任务(回调函数)放入任务队列中。
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
    在这里插入图片描述
console.log(1);
document.onclick = function() {
    console.log('click');
}
console.log(2);
setTimeout(function() {
    console.log(3)
}, 3000)

在这里插入图片描述
同步任务放在执行栈中执行,异步任务由异步进程处理放到任务队列中,执行栈中的任务执行完毕会去任务队列中查看是否有异步任务执行。

由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)

location对象

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

统一资源定位符(uniform resouce locator)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

url

url 的一般语法格式为:

protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
组成说明
protocol通信协议 常用的http,ftp,maito等
host主机(域名) www.itheima.com
port端口号,可选
path路径由零或多个’/'符号隔开的字符串
query参数以键值对的形式,通过&符号分隔开来
fragment片段#后面内容,常见于链接、锚点
location对象属性
location对象属性返回值
location.href获取或者设置整个URL
location.host返回主机(域名)www.baidu.com
location.port返回端口号,如果未写返回空字符串
location.pathname返回路径
location.search返回参数
location.hash返回片段 #后面内容常见于链接 锚点

重点记住: href和search

案例:5s之后跳转页面

<body>
    <button>点击</button>
    <div></div>
    <script>
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        var timer = 5;
        setInterval(function() {
            if (timer == 0) {
                location.href = 'http://www.itcast.cn';
            } else {
                div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
                timer--;
            }
        }, 1000);
    </script>
</body>

案例:获取URL参数
login.html:

<body>
    <form action="index.html">
        用户名: <input type="text" name="uname">
        <input type="submit" value="登录">
    </form>
</body>

index.html

<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>
location对象方法返回值
location.assign()跟href一样,可以跳转页面(也称为重定向页面)
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相当于刷新按钮或者 f5 ,如果参数为true 强制刷新 ctrl+f5
<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对象

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

下面前端代码可以判断用户是用哪个终端打开页面的,实现跳转

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 = "";     //电脑
 }

history对象

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

history对象方法作用
back()可以后退功能
forward()前进功能
go(参数)前进后退功能,参数如果是 1 前进1个页面 如果是 -1 后退1个页面
<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办公系统中见到。

PC端网页特效

元素偏移量offset系列

offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。

  • 获得元素距离带有定位父元素的位置
  • 获得元素自身的大小(宽度高度)
  • 注意:返回数值都不带单位

offset系列常用属性:

offset系列属性作用
element.offsetParent返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
element.offsetTop返回元素相对带有定位父元素上方的偏移
element.offsetLeft返回元素相对带有定位父元素左边框的偏移
element.offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight返回自身包括padding、边框、内容区的高度,返回数值不带单位
<style>
	.father{width: 200px;height: 200px;background-color: pink;margin: 100px;position: relative;}
	.son{width: 100px;height: 100px;background-color: purple;margin-left: 45px;}
	.w{width: 200px;height: 200px;background-color: skyblue;margin: 0 auto 200px;padding: 10px;border: 15px solid red}
</style>
<body>
	<div class="father">
		<div class="son"></div>
	</div>
	<div class="w"></div>
	<script>
		//offset 系列
		var father = document.querySelector('.father');
		var son = document.querySelector('.son');
		//可以看到元素的偏移 位置 返回的不带单位的数值
		console.log(father.offsetTop);
		console.log(father.offsetLeft);
		//它以带有定位的父亲为准 如果没有父亲或者父亲没有定位 则以body为准
		console.log(son.offsetLeft);
		var w = document.querySelector('.w');
		//可以得到元素的大小 宽度和高度 是包含padding+margin+width
		console.log(w.offsetWidth);
		console.log(w.offsetHeight);
		//返回带有定位的父亲 否则返回的是body
		console.log(son.offsetParent);
		console.log(son.parentNode);// 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
	</script>
</body>
offset和style的区别

在这里插入图片描述

<style>
	.box{width: 200px;height: 200px;background-color: pink;}
</style>
<body>
	<div class="box"></div>
	<script>
		//offset与style的区别
		var box = document.querySelector('.box');
		console.log(box.offsetWidth);
		console.log(box.stylle.width);
		//box.offsetWidth = '300px'; //不能这么做
		box.stylle.width = '300px';
	</script>
</body>

案例:获取鼠标在盒子内的坐标

<style></style>
<body>
	<div class="box"></div>
	<script>
		var box = document.querySelector('.box');
		box.addElementListener('mousemove', function(){
			console.log(e.pageX);
			console.log(e.pageY);
			console.log(box.offsetLeft);
			var x = e.pageX - this.offsetLeft;
			var y = e.pageY - this.offsetTop;
			this.innerHTML = 'x坐标是:' + x + 'y坐标是:' + y;
		})
	</script>
</body>

案例:模态框拖拽

<style>...</style>
<body>
	<div class="login-header"><a id="link" href="javascript:;"></a></div>
	<div id="title" class="login-title">登录会员
		<span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
	</div>
	<div class="login-input-content">
		<div class="login-input">
			<label>用户名<label>
			...
		</div>
	</div>
	<!-- 遮盖层 -->
	<div id="bg" class="login-bg"></div>
	<script>
		//1.获取元素
		var login = document.querySelector('.login');
		var mask = document.querySelector('.login-bg');
		var link = document.querySelector('#link');
		var closeBtn = document.querySelector('#closeBtn');
		var title = document.querySelector('#title');
		//2.点击弹出层这个链接 link 让mask和login显示出来
		link.addEventListener('click', function(){
			mask.style.display = 'block';
			login.style.display = 'block';
		})
		//3. 点击closeBtn就隐藏mask和login
		closeBtn.addEventListener('click', function(){
			mask.style.display = 'none';
			login.style.display = 'none';
		})
		//4. 开始拖拽
		//(1)当我们鼠标按下,就获得鼠标在盒子内的坐标
		title.addEventListener('mousemove', function(e){
			var x = e.pageX - this.offsetLeft;
			var y = e.pageY - this.offsetTop;
			//(2)鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标就是模态框的left和top值
			document.addEventListener('mousemove', move);
			function move(e){
				login.style.left = e.pageX - x + 'px';
				login.style.top = e.pageY - y + 'px';
			}
			//(3)鼠标弹起,就让鼠标移动事件移除
			document.addEventListener('mouseup', function(e){
				.addEventListener('mousemove',move);
			})
		})
	</script>
</body>

案例:仿京东放大镜

<style>
	.preview_img{height: 398px;border: 1px solid #ccc;}
	.mask{position: absolute;top: 0;left: 0;width: 300px;height: 300px;background-color: #FEDE4F;opacity: .5;cursor: move;}
	.big{width: 500px;height: 500px;background-color: pink;position: absolute;left: 410px;top: 0;z-index: 999;}
</style>
<body>
	<div class="preview_img">
		<img src="upload/s3.png" alt="">
		<div class="mask">1</div>
		<div class="big">
			<img src="upload/big.jpg" alt="" class="bigImg">
		</div>
	</div>
	<script>
		window.addEventListener('load',function(){
			var preview_img = document.querySelector('.preview_img');
			var mask = document.querySelector('.mask');
			var big = document.querySelector('.big');
			//1.当我们鼠标经过preview_img就显示和隐藏mask遮挡层和big大盒子
			preview_img.addEventListener('mouseover', function(){
				mask.style.display = 'block';
				big.style.display = 'block';
			})
			preview_img.addEventListener('mouseout', function(){
				mask.style.display = 'none';
				big.style.display = 'none';
			})
			//2.鼠标移动的时候,让黄色的盒子跟着鼠标来走
			preview_img.addEventListener('mouseover', function(e){
				//(1)先计算出鼠标在盒子内的坐标
				var x = e.pageX - this.offsetLeft;
				var y = e.pageY - this.offsetTop;
				//console.log(x,y);
				//(2)减去盒子高度 300的一半是 150 就是mask的最终的left和top值
				//(3)我们mask移动的距离
				var maskX = x - mask.offsetLeft / 2;
				var maskY = y - mask.offsetTop / 2;
				//(4)如果s坐标小于了0 就让他停在0的位置
				//遮挡层的最大移动距离
				var maskMax = preview_img.offsetWidth - mask.offsetWidth;
				if(maskX <= 0){
					maskX = 0;
				}else if(maskX >= maskMax){
					maskX = maskMax;
				}
				if(maskY <= 0){
					maskY = 0;
				}else if(maskY >= maskMax){
					maskY = maskMax;
				}
				mask.style.left = maskX + 'px';
				mask.style.top = maskY + 'px';
				//大图片的移动距离 = 遮挡层移动距离 + 大图片最大移动距离 / 遮挡层的最大移动距离
				//大图
				var bigImg = document.querySelector('.bigImg');
				//大图片的最大移动距离
				var bigMax = bigImg.offsetWidth - big.offsetWidth;
				//大图片的移动距离 X Y
				var bigX = maskX * bigMax / maskMax;
				var bigY = maskY * bigMax / maskMax;
				bigImg.style.left = -bigX + 'px';
				bigImg.style.top = -bigY + 'px';
			})
		})
	</script>
</body>

元素可视区client系列

client翻译过来就是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息,通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

client系列属性作用
element.clientTop返回元素上边框的大小
element.clientLeft返回元素左边框的大小
element.clientWidth返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element.clientHeight返回自身包括padding、内容区的高度,不含边框,返回数值不带单位
<style>
	div{width: 200px;height:200px;background-color: pink;border: 10px solid red;padding: 10px;}
</style>
<body>
	<div></div>
	<script>
		//client 宽度 和我们offsetWidth最大的区别就是 不包含边框
		var div = document.querySelector('div');
		console.log(div.clientWidth);
	</script>
</body>

案例:淘宝flexible.js源码分析

立即执行函数(function(){})()
主要作用:创建一个独立的作用域

//1.立即执行函数:不需要调用,立马能够自己执行的函数
function fn(){
	console.log(1); //1
}
fn();
//2.写法 (function(){})();  或者  (function(){}());
//也可以传递参数进来
(function(a,b){
	console.log(2); //2
	console.log(a + b); //4
	var num = 10;
})(1,3); //第二个小括号可以看作是调用函数
(function sum(a,b){
	console.log(a + b); //5
	var num = 10; //局部变量
}(2,3));
//3.立即执行函数的最大作用就是独立创建一个作用域,里面所有的变量都是局部变量 不会有命名冲突的情况

dpr 物理像素比
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

元素滚动scroll系列

scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等。

scroll系列属性作用
element.scrollTop返回被卷去的上侧距离,返回数值不带单位
element.scrollLeft返回被卷去的左侧距离,返回数值不带单位
element.scrollWidth返回自身实际的宽度,不含边框,返回数值不带单位
element.scrollHeight返回自身实际的高度,不含边框,返回数值不带单位
<style>
	div{width: 200px;height:200px;background-color: pink;border: 10px solid red;padding: 10px;overflow: auto;/*自动显示滚动条*/}
</style>
<body>
	<div>我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容</div>
	<script>
		//scroll 不包含边框和padding 超出
		var div = document.querySelector('div');
		console.log(div.scrollWidth); //314
		console.log(div.clientWidth); //220
		//scroll滚动事件,当我们滚动条发生变化时会触发的事件
		div.addEventListener('scroll',function(){
			console.log(div.scrollTop);
		});
	</script>
</body>

在这里插入图片描述
如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条,当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部,滚动条在滚动时会触发onscroll事件。

案例:仿淘宝固定右侧侧边栏

<style>
	.slider-bar{position: absolute;left: 50%;top: 300px;margin-left: 600px;width: 45px;height: 130px;background-color: pink;}
	.w{width: 1200px;margin: 10px auto;}
	.header{height: 150px;background-color: purple;}
	.banner{height: 250px;background-color: skyblue;}
	.main{height: 1000px;background-color: yellowgreen;}
	span{display: none;position: absolute;bottom: 0;}
</style>
<body>
	<div class="silder-bar">
		<span class="goBack">返回顶部</span>
	</div>
	<div class="header w">头部区域</div>
	<div class="banner w">banner区域</div>
	<div class="main w">主体部分</div>
	<script>
		//1.获取元素
		var silderbar = document.querySelector('.silder-bar');
		var banner = document.querySelector('.banner');
		//banner.offsetTop 就是被卷去头部的大小 一定要写到滚动的外面
		//console.log(banner.offsetTop);
		var bannerTop = banner.offsetTop;
		//当我们侧边栏固定定位之后应该变化的数值
		var silderbarTop = sliderbar.offseTop - bannerTop;
		//获取main 主体元素
		var main = document.querySelector('.main');
		var goBack = document.querySelector('.goBack');
		var mainTop = main.offsetTop;
		//2. 页面滚动事件 scroll
		document.addEventListener('scroll',function(){
			//console.log(11);
			//window.pageYOffset 页面被卷去的头部
			//console.log(window.pageYOffset);
			//3.当我们页面被卷去的头部大于等于了172,此时,侧边栏就要改为固定定位
			if(window.pageYOffset >= bannerTop){
				sliderbar.style.position = 'fixed';
				sliderbar.style.top = silderbarTop + 'px';
			}else{
				sliderbar.style.position = 'absolute';
				sliderbar.style.top = '300px';
			}
			//4.当我们页面滚动到main盒子,就显示goBack模块
			if(window.pageYOffset >= mainTop){
				goBack.style.position = 'block';
			}else{
				goBack.style.position = 'none';
			}
		});
	</script>
</body>

在这里插入图片描述
在这里插入图片描述
他们的主要用法:

  1. offset系列经常用于获得元素位置 offsetLeft offsetTop
  2. client经常用于获取元素大小 clientWidth clientHeight
  3. scroll经常用于获取滚动距离 scrollTop scrollLeft
  4. 注意页面滚动的距离通过 window.pageXOffset获得

mouseenter 鼠标事件

  • 当鼠标移动到元素上时就会触发mouseenter事件
  • 类似mouseover,它们两者之间的差别是
  • mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发
  • 之所以这样,就是因为mouseenter不会冒泡
  • 跟mouseenter搭配 鼠标离开mouseleave同样不会冒泡
<body>
	<div class="father">
		<div class="son"></div>
	</div>
	<script>
		var father = document.querySelector('.father');
		var son = document.querySelector('.son');
		father.addEventListener('mouseover',function(){
			console.log(11); //2次
		})
		father.addEventListener('mouseenter',function(){
			console.log(22); //1次
		})
	</script>
</body>

动画函数封装

动画函数原理

核心原理:通过定时器setIntterval()不断移动盒子的位置。
实现步骤:

  1. 获得盒子当前位置
  2. 让盒子在当前位置加上1个移动距离
  3. 利用定时器不断重复这个操作
  4. 加一个结束定时器的条件
  5. 注意此元素需要添加定位,才能使用element.style.left
<style>
	div{position: absolute;left: 0;width:100px;height: 100px;background-color: pink;}
</style>
<body>
	<div></div>
	<script>
		//动画原理
		var div = document.querySelector('div');
		var timer = setInterval(function() {
			if(div.offsetLeft >= 400){
				//停止动画 本质是停止定时器
				clearInterval(timer);
			}
			div.style.left = div.offsetLeft + 1 + 'px';
		},30);
	</script>
</body>
动画函数简单封装

注意函数需要传递2个参数,动画对象移动到的距离

<style>
	div{position: absolute;left: 0;width:100px;height: 100px;background-color: pink;}
	span{display: block;width: 150px;height: 150px;background-color: purple;position: absolute;left: 0;top: 200px;}
</style>
<body>
	<div></div>
	<span>夏雨荷</span>
	<script>
		//简单函数封装 obj目标对象 target 目标位置
		function animate(obj,target){
			var timer = setInterval(function() {
				if(obj.offsetLeft >= target){
					//停止动画 本质是停止定时器
					clearInterval(timer);
				}
				obj.style.left = obj.offsetLeft + 1 + 'px';
			},30);
		}
		var div = document.querySelector('div');
		var span = document.querySelector('span');
		//调用
		animate(div,400);
		animate(span,300);
	</script>
</body>
动画函数给不同元素记录不同定时器

如果多个元素都使用这个动画函数,每次都要var声明定时器,我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)。

核心原理:利用js是一门动态语言,可以很方便的给当前对象添加属性。

<style>
	div{position: absolute;left: 0;width:100px;height: 100px;background-color: pink;}
	span{display: block;width: 150px;height: 150px;background-color: purple;position: absolute;left: 0;top: 200px;}
</style>
<body>
	<button>点击夏雨荷才走</button>
	<div></div>
	<span>夏雨荷</span>
	<script>
		//var obj = {};
		//obj.name = 'andy';
		//简单函数封装 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,400);
		btn.addEventListener('click',function(){
			animate(span,300);
		})
	</script>
</body>
缓动动画原理

缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来。

思路:

  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
  2. 核心算法:(目标值 - 现在的位置) / 10 做为每次移动的距离 步长
  3. 停止的条件是:让当前盒子位置等于目标位置就停止定时器
  4. 步长值需要取整
<style>
	span{display: block;width: 150px;height: 150px;background-color: purple;position: absolute;left: 0;top: 200px;}
</style>
<body>
	<button class="btn500">点击夏雨荷走500</button>
	<button class="btn800">点击夏雨荷走800</button>
	<span>夏雨荷</span>
	<script>
		//停止条件是:让当前盒子位置等于目标位置就停止定时器
		//把我们步长值改为整数 不要出现小数的问题
		function animate(obj,target){
			clearInterval(obj.timer);
			obj.timer = setInterval(function() {
				//步长值写到定时器的里面
				//停止动画 本质是停止定时器
				//var step = Math.ceil((target - obj.offsetLeft) / 10);
				var step = (target - obj.offsetLeft) / 10;
				step = step > 0 ? Math.ceil(step) : Math.floor(step);
				if(obj.offsetLeft == target){
					clearInterval(obj.timer);
				}
				//把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
				obj.style.left = obj.offsetLeft + step + 'px';
			},30);
		}
		var span = document.querySelector('span');
		var btn500 = document.querySelector('btn500');
		var btn800 = document.querySelector('btn800');
		btn500.addEventListener('click',function(){
			animate(span,500);
		})
		btn800.addEventListener('click',function(){
			animate(span,800);
		})
		//匀速动画 就是盒子是当前位置 + 固定的值 10
		//缓动动画就是盒子当前的位置 + 变化的值(目标值 - 现在的值) / 10
	</script>
</body>
动画函数添加回调函数

回调函数原理:函数可以作为一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调
回调函数写的位置:定时器结束的位置。

<style>
	span{display: block;width: 150px;height: 150px;background-color: purple;position: absolute;left: 0;top: 200px;}
</style>
<body>
	<button class="btn500">点击夏雨荷走500</button>
	<button class="btn800">点击夏雨荷走800</button>
	<span>夏雨荷</span>
	<script>
		function animate(obj,target,callback){
			//console.log(callback); callback = function(){} 调用的时候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);
					//回调函数写到定时器结束里面
					if(callback){
						//调用函数
						callback();
					}
				}
				obj.style.left = obj.offsetLeft + step + 'px';
			},30);
		}
		var span = document.querySelector('span');
		var btn500 = document.querySelector('btn500');
		var btn800 = document.querySelector('btn800');
		btn500.addEventListener('click',function(){
			animate(span,500,1);
		})
		btn800.addEventListener('click',function(){
			animate(span,800,function(){
				//alert('你好吗');
				span.style.backgroundColor = 'red';
			});
		})
		//匀速动画 就是盒子是当前位置 + 固定的值 10
		//缓动动画就是盒子当前的位置 + 变化的值(目标值 - 现在的值) / 10
	</script>
</body>

以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可。

  1. 单独建立一个JS文件。
  2. 引用文件

案例:引用animate动画函数

<style>...</style>
<script src="animate.js"></script>
<body>
	<div class="sliderbar">
		<span></span>
		<div class="con">问题反馈</div>
	</div>
	<script>
		var sliderbar = document.querySelector('.sliderbar');
		var con = document.querySelector('.con');
		sliderbar.addEventListener('mousenter',function(){
			//animate(obj,target,callback);
			animate(con,-160,function(){
				//当我们动画执行完毕,←改成→
				sliderbar.children[0].innerHTML = '→';
			});
		})
		sliderbar.addEventListener('mouseleave',function(){
			//animate(obj,target,callback);
			animate(con,0,function(){
				sliderbar.children[0].innerHTML = '←';
			});
		})
	</script>
</body>

常见网页特效案例

节流阀

防止轮播图按钮连续点击造成播放过快。
上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发。

核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

  1. 开始设置一个变量var flag = true;
  2. if(flag){flag=false;do something} 关闭水龙头
  3. 利用回调函数 动画执行完毕,flag = true;打开水龙头

案例:返回顶部
滚动窗口至文档中的特定位置。
window.scroll(x,y)
在这里插入图片描述

<style>
	.slider-bar{position: absolute;left: 50%;top: 300px;margin-left: 600px;width: 45px;height: 130px;background-color: pink;}
	.w{width: 1200px;margin: 10px auto;}
	.header{height: 150px;background-color: purple;}
	.banner{height: 250px;background-color: skyblue;}
	.main{height: 1000px;background-color: yellowgreen;}
	span{display: none;position: absolute;bottom: 0;}
</style>
<body>
	<div class="silder-bar">
		<span class="goBack">返回顶部</span>
	</div>
	<div class="header w">头部区域</div>
	<div class="banner w">banner区域</div>
	<div class="main w">主体部分</div>
	<script>
		//1.获取元素
		var silderbar = document.querySelector('.silder-bar');
		var banner = document.querySelector('.banner');
		//banner.offsetTop 就是被卷去头部的大小 一定要写到滚动的外面
		//console.log(banner.offsetTop);
		var bannerTop = banner.offsetTop;
		//当我们侧边栏固定定位之后应该变化的数值
		var silderbarTop = sliderbar.offseTop - bannerTop;
		//获取main 主体元素
		var main = document.querySelector('.main');
		var goBack = document.querySelector('.goBack');
		var mainTop = main.offsetTop;
		//2. 页面滚动事件 scroll
		document.addEventListener('scroll',function(){
			//console.log(11);
			//window.pageYOffset 页面被卷去的头部
			//console.log(window.pageYOffset);
			//3.当我们页面被卷去的头部大于等于了172,此时,侧边栏就要改为固定定位
			if(window.pageYOffset >= bannerTop){
				sliderbar.style.position = 'fixed';
				sliderbar.style.top = silderbarTop + 'px';
			}else{
				sliderbar.style.position = 'absolute';
				sliderbar.style.top = '300px';
			}
			//4.当我们页面滚动到main盒子,就显示goBack模块
			if(window.pageYOffset >= mainTop){
				goBack.style.position = 'block';
			}else{
				goBack.style.position = 'none';
			}
		});
		//3. 当我们点击了返回顶部模块。就让窗口滚动的页面的最上方、
		goBack.addEventListener('click',function(){
			//alert(1);
			//里面的x y是不跟单位的 直接写数字即可
			//window.scroll(0,0);
			//因为是窗口滚动 所以对象是window
			animate(window,0);
		});
		function animate(obj,target,callback){
			clearInterval(obj.timer);
			obj.timer = setInterval(function() {
				var step = (target - window.pageYOffset) / 10;
				step = step > 0 ? Math.ceil(step) : Math.floor(step);
				if(window.pageYOffset== target){
					clearInterval(obj.timer);
					callback && callback();
				}
				//obj.style.left = window.pageYOffset + step + 'px';
				window.scroll(0,window.pageYOffset + step);
			},30);
		}
	</script>
</body>

案例:筋斗云案例
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

移动端网络特效

触屏事件

移动端浏览器兼容性较好,我们不需要考虑以前的JS的兼容性问题,可以放心的实验原生JS书写效果,但是移动端也有自己独特的地方,比如触屏事件touch(也称触摸事件),Android和IOS都有。
touch对象代表一个触摸点,触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板的操作。

触屏touch事件说明
touchstart手指触摸到一个DOM元素时触发
touchmove手指在一个DOM元素上滑动时触发
touchend手指从一个DOM元素上移开时触发
<style>
	div{width: 100px;height: 100px;background-color: pink;}
</style>
<body>
	<div></div>
	<script>
		//手指触摸DOM元素事件
		var div = document.querySelector('div');
		div.addEventListener('touchstart',function(){
			console.log('我摸了你!');
		})
		//手指在DOM元素身上移动
		div.addEventListener('touchmove',function(){
			console.log('我继续摸!');
		})
		//手指离开DOM元素事件
		div.addEventListener('touchend',function(){
			console.log('我走了!');
		})
	</script>
</body>
触摸事件对象(TouchEvent)

touchstart、touchmove、touchend三个事件都会各自有事件对象。

TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件,这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等。

触摸列表说明
touches正在触摸屏幕的所有手指的一个列表
targetTouches正在触摸当前DOM元素上的手指的一个列表
changedTouches手指状态发生了改变的列表,从无到有,从有到无变化
<style>
	div{width: 100px;height: 100px;background-color: pink;}
</style>
<body>
	<div></div>
	<script>
		//手指触摸DOM元素事件
		var div = document.querySelector('div');
		div.addEventListener('touchstart',function(e){
			console.log(e);
			//touches正在触摸屏幕的所有手指列表
			//targetTouches正在触摸当前DOM元素的手指列表
			//如果倾听的是一个DOM元素,他们两个是一样的
			//changedTouches手指状态发生了改变的列表 从无到有 从有到无
			//因为我们一般都是触摸元素 所以最经常使用的是 targetTouches
			//console.log(e.targetTouches[0]);
			//targetTouches[0]就可以得到正在触摸dom元素的第一个手指的相关信息比如手指的坐标等等
		})
		//手指在DOM元素身上移动
		div.addEventListener('touchmove',function(){
			
		})
		//手指离开DOM元素事件
		div.addEventListener('touchend',function(e){
			console.log(e);
			//当我们手指离开屏幕的时候,就没有了touches和targetTouches列表 但会有changerdTouches
		})
	</script>
</body>

因为平时我们都是给元素注册触摸事件,所以重点记住targetTouches。

移动端拖动元素
  1. touchstart、touchmove、touchend可以实现拖动元素
  2. 但是拖动元素需要当前手指的坐标值 我们可以使用targetTouches[0]里面的pageX和pageY
  3. 移动端拖动的原理:手指移动中,计算出手指移动的距离,然后用盒子原来的位置 + 手指移动的位置
  4. 手指移动的距离:手指滑动中的位置减去 手指开始触摸的位置

拖动元素三步曲:
(1)触摸元素touchstart:获取手指初始坐标,同时获得盒子原来的位置
(2)移动手指touchmove:计算手指的滑动距离,并且移动盒子
(3)离开手指touchend

注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault();

<style>
	div{width: 100px;height: 100px;background-color: pink;}
</style>
<body>
	<div></div>
	<script>
		var div = document.querySelector('div');
		var startX = 0;
		var startY = 0;
		var x = 0;//获得盒子原来的位置
		var y = 0;
		div.addEventListener('touchstart',function(){
			//获取手指初始坐标
			startX = e.targetTouches[0].pageX;
			startY = e.targetTouches[0].pageY;
			x = this.offsetLeft;
			y = this.offsetTop;
		div.addEventListener('touchmove',function(){
			//计算手指的移动距离,手指移动之后的坐标减去手指初始的坐标
			var moveX = e.targetTouches[0].pageX - startx;
			var moveY = e.targetTouches[0].pageY - startY;
			//移动我们的盒子 盒子原来的位置 + 手指移动的距离
			this.style.left = x + moveX + 'px';
			this.style.top = y + moveY + 'px';
			e.preventDefault();//阻止屏幕滚动的默认行为
		})
		div.addEventListener('touchend',function(){
			console.log();
		})
	</script>
</body>

移动端常见特效

classList属性

classList属性是HTML5新增的一个属性,返回元素类名,但是ie10以上版本支持。

该属性用于在元素中添加,移除及切换CSS类,有以下方法:

添加类:element.classList.add('类名');

focus.classList.add('current');

移除类:element.classList.remove('类名');

focus.classList.remove('current');

切换类:element.classList.toggle('类名');

focus.classList.toggle('current');

在这里插入图片描述
在这里插入图片描述

click延时解决方案

移动端click事件会有300ms的延时,原因是移动端屏幕双击会缩放(double tap to zoom)页面。
解决方案:

  1. 禁用缩放,浏览器禁用默认的双击缩放行为并且去掉300ms的点击延迟。<meta name="viewport" content="user-scalable=no">
  2. 利用touch事件自己封装这个事件解决300ms延迟。

原理就是:
(1)当我们手指触摸屏幕,记录当前触摸时间。
(2)当我们手指离开屏幕,用离开的时间减去触摸的时间。

在这里插入图片描述
3. 使用插件。fastclick插件解决300ms延迟。

移动端要求的是快速开发,所以我们经常会借助于一些插件来帮我们完成操作,什么是插件?
JS插件是js文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件。我们以前写的animate.js也算一个最简单的插件。

特点:它一般是为了解决某个问题而专门存在,其功能单一,并且比较小。

fastclick插件解决300ms延迟,使用延迟。
在这里插入图片描述
在这里插入图片描述

移动端常用开发插件

Swiper插件的使用

中文官网地址:http://www.swiper.com.cn/

  1. 引入插件相关文件
  2. 按照规定语法使用
其他移动端常见插件

superslide:http://www.superslide2.com/
iscroll:https://github.com/cubiq/iscroll

插件的使用总结
  1. 确认插件实现的功能
  2. 去官网查看使用说明
  3. 下载插件
  4. 打开semo实例文件,查看需要引入的相关文件,并且引入
  5. 复制demo实例文件中的结构html,样式css以及js代码
移动端视频插件 zy.media.js

H5给我们提供了video标签,但是浏览器的支持情况不同。
不同的视频格式文件,我们可以通过source解决。
但是外观样式,还有暂停、播放、全屏等功能我们只能自己写代码解决。
这个时候我们可以使用插件方式来制作。

移动端常用开发框架

框架,顾名思义就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案。框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。

前端常用的框架有Bootstrap、Vue、Angular、React等,既能开发PC端,也能开发移动端。
前端常用的移动端插件有swiper、superslide、iscroll等。

框架:大而全,一整套解决方案。
插件:小而专一,某一个功能的解决方案。

Bootstrap

Bootstrap是一个简洁、直观、强悍的前端开发框架,它让web开发更迅速、简单。
它能开发PC端,也能开发移动端。
Bootstrap JS插件使用步骤:

  1. 引入相关js文件
  2. 复制HTML结构
  3. 修改对应样式
  4. 修改相应JS参数

本地存储

本地存储特性:

  1. 数据存储在用户浏览器中
  2. 设置、读取方便,甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage约5M,localStorage约20M
  4. 只能存储字符串,可以将对象JSON.stringify()编码后存储

window.sessionStorage

  1. 生命周期为关闭浏览器窗口
  2. 在同一个窗口(页面)下数据可以共享
  3. 以键值对的形式存储使用

存储数据:

sessionStorage.setItem(key,value);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

获取数据:

sessionStorage.getItem(key);

删除数据:

sessionStorage.removeItem(key);

删除所有数据:

sessionStorage.clear();

window.localStorage

  1. 生命周期永久生效,除非手动删除,否则关闭页面也会存在
  2. 可以多窗口(页面)共享(同一浏览器可以共享)
  3. 以键值对的形式存储使用
    存储数据:
localStorage.setItem(key,value);

获取数据:

localStorage.getItem(key);

删除数据:

localStorage.removeItem(key);

删除所有数据:

localStorage.clear();

在这里插入图片描述
在这里插入图片描述
案例:记住用户名

<body>
	<input type="text" id="username"> <input type="checkbox" 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');
			}
		})
	</script>
</body>

——To Be Continued

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值