BOM(浏览器对象模型)可以通过JS来操作浏览器,在BOM中为我们提供了一组对象,用来完成对浏览器的操作
BOM对象:Window、Navigator、Location、History、Screen
Window:代表的是整个浏览器的窗口,同时window也是网页中的全局对象
Navigator:代表当前浏览器的信息,通过该对象可以来识别不同的浏览器
由于历史原因,Navirgator对象中的大部分属性已经不能帮助我们识别浏览器了
一般我们只会使用userAgent来判断浏览器的信息
userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器回会有不同的userAgent
在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了
如果通过UserAgent不能判断,还可以通过一些浏览器中特有的对象来判断浏览器的信息,比如:ActiveXObject
IE11中调整过,浏览器中包含ActiveXObject但判断是否存在时又会返回false,所以使用"ActiveXObject" in window 来判断浏览器是否是IE
console.log(navigator.userAgent); //
//判断是否是火狐
var ua=navigator.userAgent;
if(/firefox/i.test(ua)){
alert("是火狐");
}else if("ActiveXObject" in window){
alert("是IE");
}
if(window.ActiveXObject){ //最好是调用window,这样不会报错,没有只会返回undefined
alert("是IE");
}else{
alert("不是IE");
}
Location:代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
History:代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录。由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后,而且该操作只在当次访问时有效
Screen:代表用户的屏幕信息,通过该对象可以获取到用户显示器的相关信息(pc端用的不太多,主要用于移动端)
这些BOM对象在浏览器种都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用
//两种写法都可以,因为window是全局对象
console.log(window.navigator)
console.log(navigator)
History:可以操作浏览器先前或向后翻页
length属性可以获取到当前访问的连接数量
back()可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward()可以跳转到下一个页面,作用和浏览器的前进按钮一样
go()可以用来跳转到指定的页面
它需要一个整数作为参数
1:表示向前跳转一个页面,2:表示向前跳转两个页面
-1:表示向后跳转一个页面,-2:表示向后跳转两个页面
Location:该对象中封装了浏览器的地址栏信息
如果直接打印locaation,可以获取到当前地址栏的信息(当前页面的完整路径)
如果直接将location属性修改为一个完整的路径,或相对路径,那么页面会自动跳转到该路径,并且会生成相应的历史记录
assign()用来跳转到其他页面,作用和直接修改location一样
reload()重新加载当前页面,作用与刷新按钮一样,如果在方法中传递一个true作为参数,则会强制清空缓存刷新页面
replace()可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,不会生成历史记录,不能使用回退按钮回退
location.reload(true); //没有true浏览器会缓存,文本框中的内容不会消失,加上true后文本框也被清空
Window
setInterval() 定时调用,可以将一个函数每隔一段时间被调用一次
参数:
1、回调函数,该函数会每隔一段时间被调用一次
2、每次调用间隔的时间,单位是毫秒
setInterval(function(){},1000)
返回值:返回一个Number类型的数据,这个数字用来作为定时器的唯一标识
clearInterval()可以用来关闭一个定时器,方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
可以接收任意参数,如果参数是一个有效的定时器标识,则停止对应的定时器,让如果参数不是一个有效的标识,那么什么也不做
var count = document.getElementById("count");
var num=1;
var timer=setInterval(function(){
count.innerHTML=num++;
for(i=1;i<100;i++){
if(num==11){
clearInterval(timer);
}
}
},100);
练习:切换图片 E:\web\basic\10.intervalPic
每点击一次按钮,就会开启一个定时器,点击多次会开启多个定时器,这就导致图片的切换速度过快,并且我们只能关闭最后一次开启的定时器
在开启定时器之前,需要将上一个定时器关闭
优化 移动Div的练习(长按方向键时div第一次移动后会先停顿一下,再连续移动
思路:用一个变量获取键盘按下的编码,设置一个定时器,当方向键被按下时,按照设定的时间均匀的增加位移,这样就可以避免浏览器自带的停顿
当方向键被松开时,应该将赋给定时器中编码的值设为0,这样box就不会再移动了。加速后松开ctrl键,box依旧处于加速状态,所以如果还需判断ctrl没被按下的情况,此时将speed改回原来的值。
setTimeout() 延时调用一个函数不马上执行,而是隔一段时间以后再执行,而且只会执行一次
延时调用和定时调用的区别:定时调用会执行多次,延时调用只会执行一次
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要来选择
clearTimeout() 关闭延时调用
练习:定时器的调用 E:\web\basic\js\12.setInterval
这一个练习需要多做做,遇到了很多问题
1、设置第一个按钮的功能时,将设置newValue的值和清除定时器放在同一个判断语句里,导致停止时会超过800的线。而且再次点击第一个按钮,box1依旧会往前移动一个速度距离
2、每一次都需要解决多次点击会导致速度加快的问题,所以在点击按钮前需要将定时器清除
创建一个可以执行简单动画的函数
参数:
obj:要执行动画的对象
speed:移动的速度
target:执行动画的目标位置,向左移动时,需要判断newValue是否小于target。向右移动时,判断newValue是否大于target
3、给函数传正负速度不好,需要用户自己判断box1此时所处的位置,如:box1处于1000,此时需传-10,box1处于600,此时需传10
在函数前面声明一个current,获取当前box1的位置,该值与定时器中第一次的oldValue值相同,但定时器中的oldValue是在不断变化的,而这里的只需获取一次用来判断速度的方向
4、创建2个box,当一个移动时,另一个如果处于移动状态也会被强制停止
目前定时器的标识由全局变量timer保存,所有正在执行的定时器都在这个变量中保存,所以执行下一个定时器时会将上一个定时器(无论上一个定时器是不是它的)清除
向执行动画的对象中添加一个timer属性,用来保存它自己的定时器标识
obj.timer=setInterval(function){},300)
再添加别属性
attr:要执行动画的样式,如:left、top、width
callback:回调函数,放在父函数的最后,这个函数将会在动画执行完毕以后再执行
将获取样式和处理box函数作为外部文件引入,需要注意的是一定要先创建一个js文件夹,然后再将tool.js放入
练习:轮播图
1、五张图宽度为540*5+10*2*5(padding)=2700,如果增加图片,ul的宽度不够,所以将ul的宽度在JS中设置
2、ul的absolute是相对于窗口的,所以还需要给父元素div开启相对定位
left: -560px; 每向左移动560px,就会显示下一张图片
3、绝对定位后图片脱离文档流,a会在最上方,且图片会将超链接盖住,所以a的div也需要开绝对定位
4、自动切换的过程中,定时器会一直切入下一张图片,回调函数为setA,即在图片切换过程中超链接无变化,切换完成后改变此时对应的超链接颜色。此时又在立马执行下一张图的切换。
需要解决显示最后第5张图片后回到第一张图片。通过上述原理,在最后再添加一个img标签,该图与第一张图片一样,在切换第6张图时,此时颜色改变的还是第5个超链接,如果index>=imgArr.length-1,说明接下来应该改变第一个a的颜色。完整显示第6张图后,此时第一个a改变颜色,视觉效果是又回到了第一张图。为了下一张图切入的是第二张图,此时的ul元素的left值应该设置为0。
5、图片自动切换,与点击超链接切换,两个效果叠加在一起,但是应该以点击超链接优先,所以点击超链接时应该关闭自动播放,在点击超链接事件结束时还需要再开启定时器
类的操作
通过style属性来修改元素的样式(行为和样式耦合),每修改一个样式,浏览器就需要重新渲染一次,这样执行的性能是比较差的,而且当我们要修改多个样式时,也不太方便
最好一行代码能修改多个样式,可以通过修改元素的class属性来间接的修改样式,这样我们值需要修改一次,就可以修改多个样式,浏览器只需要重新渲染一次,性能较好,而且这种方式可以使表现和行为进一步的分离
box.className="b2";
<button id="btn">点击按钮修改样式</button>
<br/>
<br/>
<div id="box1" class="b1"></div>
<style>
.b1 {
width: 100px;
height: 100px;
background-color: yellow;
}
.b2{
width: 200px;
background-color: red;
}
</style>
<script>
window.onload = function () {
var btn =document.getElementById("btn");
var box1=document.getElementById("box1");
btn.onclick=function(){
box1.className+=" b2"; //不去掉b1,且加上b2的样式
//addClass(box1,"b2");
};
};
</script>
定义一个函数,用来向一个元素中添加指定的class属性值
参数:
obj:要添加class的元素
cn:要添加的class值
function addClass(obj,cn){
//检查obj中是否含有cn
if(!hasClass(obj,cn)){
obj.className+=" "+cn;
}
}
上面的函数可以无限添加相同的class
判断一个元素中是否含有指定的class属性值,如果有则返回true,没有则返回false。需要创建一个正则表达式
function hasClass(obj,cn){
//var reg = /\bb2\b/; 这种方法不行,不能写入cn,只能加入固定的class
//使用构造函数创建
//var reg = new RegExp(cn); 输出/b2/,没有\b,还需要自己添加上
var reg = new RegExp("\\b"+cn+"\\b");
return reg.test(obj.className);
}
删除一个元素中指定的class属性
function removeClass(obj,cn){
var reg = new RegExp("\\b"+cn+"\\b");
obj.className = obj.className.replace (reg,"");
}
toggleClass可以用来切换一个类,如果元素中具有该类,则删除,如果元素中没有该类,则添加
function toggleClass(obj,cn){
if(hascClass(obj,cn)){
removeClass(obj,cn);
}else{
addClass(obj,cn);
}
}
练习:二级菜单
每一个菜单都是一个div,当div具有collapsed这个类时,div是折叠的状态,没有这个类时,div就是折叠状态
JSON
JS中的对象只有JS自己认识,其他的语言都不认识,JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言识别,并且可以转换为任意语言中的对象。JSON在开发中主要用来实现数据的交互
JSON(Javascript Object Notation)JS对象表现法
JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,其他的和JS语法一致
JSON分类:
1、对象{}
2、数组[]
JSON中允许的值:
1、字符串
2、数值
3、布尔值
4、null
5、对象
6、数组
var obj = '{"name":"孙悟空","age":"18","gender":"男"}'; //JSON对象
console.log(typeof obj); //输出string
var arr = '[1,2,3,"hello",true]'; //JSON数组
var obj2 = '{"arr":[1,2,3]}'; //是JSON
var arr2 = '[{"name":"孙悟空","age":"18","gender":"男"},{"name":"孙悟空","age":"18","gender":"男"}]'; //是JSON
将JSON字符串转换为JS中的对象
在JS中,为我们提供了一个工具类,就叫JSON,这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON
JSON–>js对象
JSON.parse() 可以将JSON字符串转换为js对象,需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
var json = '{"name":"孙悟空","age":"18","gender":"男"}';
var o = JSON.parse(json);
console.log(o); //输出object
console.log(o.age); //输出18
JS对象–>JSON
JSON.stringify()可以将一个JS对象转换为JSON字符串,需要一个js对象作为参数,会返回一个JSON字符串
var obj = {name:"孙悟空",age:"18",gender:"男"};
var str = JSON.stringify(obj);
console.log(typeof str); //输出string
console.log(str); //输出{"name":"孙悟空","age":"18","gender":"男"}
JSON这个对象在IE7及以下不支持,所以在这些浏览器中调用会报错
eval() 这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
如果使用eval()执行的字符串中含有{},它会将{}当成是代码块,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码,但是在开发中尽量不要使用,首先它的执行性能较差,而且它还具有安全隐患
var str = "alert('hello');"; //并不会执行,因为是一个字符串,虽然字符串的意思是一个JS代码
eval(str); //弹出hello
var str2 = '{"name":"孙悟空","age":"18","gender":"男"}';
eval(str2); //报错
var str2 = '({"name":"孙悟空","age":"18","gender":"男"})'; //可以解析
var str3 = '{"name":"孙悟空","age":"18","gender":"男"}';
var obj=eval("("+str3+")"); //也可以解析,且这种方法更直观
console.log(obj);
如果需要兼容I7及以下的JSON操作,可以通过引入一个外部的js文件来处理
<script src="js/json2.js"></script>
<script>
var obj = {
name: "孙悟空",
age: "18",
gender: "男"
};
var str = JSON.stringify(obj);
console.log(typeof str); //输出string
console.log(str);
</script>