JavaScript学习笔记(浏览器)
(最近刚来到简书平台,以前在CSDN上写的一些东西,也在逐渐的移到这儿来,有些篇幅是很早的时候写下的,因此可能会看到一些内容杂乱的文章,对此深感抱歉,以下为正文)
正文
众所周知,我们编写的程序是跑在浏览器之中的,在前面的学习中,我们知道了JavaScript是基于对象的,其实浏览器也是由各种对象组成的。JavaScript在运行时,我们可以访问到浏览器的对象,像之前曾使用过的alert方法和prompt方法其实就是浏览器对象window的方法。除了window对象,我们前面用过的document对象也是属于浏览器对象,它代表着页面本身,所以我们当时调用其write方法可以直接改变页面。
浏览器为JavaScript提供的对象集合,我们可以称其为浏览器对象模型(BOM),也许不是很熟悉,但你应该听过另一个对象模型,那就是DOM了,它是文档对象模型。
值得遗憾的是,BOM因为没有标准实现方式,所以导致了不同的浏览器对其支持是不一样的,所以如果不注意的话,很有可能你的程序在某个浏览器上是可以正常运行的,换了个浏览器就出错了。不幸中的万幸是BOM中的核心功能一般不会被修改,因为那样会降低交互操作性,所以我们暂且就看看这些核心功能吧。
下面用一张图来展示下后面要提到的一些核心基础对象:
核心基础对象
下面来依依介绍这些对象。
window对象:
window对象可以理解为窗口,它位于BOM层次结构中的顶层。其中包含了大量的方法和属性。当JavaScript在浏览器中运行时,该对象将自动创建,无需我们显式的创建它们。window对象是一个全局变量,所以我们访问其方法和属性时无需使用其名称调用,像我们前面使用过的alert方法就是window对象的方法。直接调用alert()方法和调用window.alert()方法效果是等同的。window对象有几个重要的属性,有document,navigator,history,screen和location等。这些即是其属性的同时,其本身也是对象,后面将分别介绍他们。
这里有个值得注意的地方,就是既然BOM对象是自动生成的,那么我们平常命名的时候就应该避免与它们重名,否则将会发生冲突。其原理是因为在全局作用域中定义的任何函数和变量都会添加到window对象中去,如果重名的话,就会覆盖原有的变量和方法,举例说明:
<!DOCTYPE html>
<html lang="en">
<head>
<title>just a test</title>
</head>
<body>
<script>
var history = "Hello";
window.history.back();
</script>
</body>
</html>
执行上述代码可以得到看到以下情况:
执行效果
正常情况下调用window对象history属性的back方法是会返回上一个页面,但因为命名是取了同名的变量名称,默认将history变量添加到window对象中,发现同名的属性,然后就覆盖了,所有执行上述代码不能返回页面的上一页。
history对象:
history对象,顾范名思义表示着历史记录,浏览器访问的每一个页面都会被它记录下来,用户可以通过点击浏览器中的前进后退按钮来重新访问自己想要访问的页面。
history对象常用的有3个方法,back(),forward(),go(index)。
back方法表示返回前一个页面。
forward方法表示返回后一个页面。
go方法带参,可以传入一个参数,通过该参数来确定所要进行的操作,如go(1)表示向后一页等同于forward()方法,go(-1)表示向前一页等同于back()方法。
location对象:
location对象包含了当前页面的大量信息,包括了当前页面的URL,保存该页面的服务器,连接服务器的端口号以及所使用的协议等。这些信息可以通过location对象的href,hostname,port和protocol等属性来获得,这些信息会因为访问位置而改变,下面以CSDN的官网为例来试试这些属性:
location对象还可以重定位当前的页面,它有两种方法实现这个功能,一直是重新指定当前location对象的href属性,还有一种则是通过location对象的replace方法来实现。两者虽然都能实现页面的重定位,但略有差别。replace方法会将当前页面在history中删除掉,并加入新的页面,此时调用之前的history对象的back方法,将无法返回该页面,因为history中已经没有该条记录,而使用href属性来跳转的话,则不会再history中删除当前页面的信息,而是在history的最顶端推入新的页面,因此当使用history的back方法时,可以顺利返回重定位页面之前的页面。
还是以CSDN官网首页为例:
-
使用location的href属性跳转页面
示例
示例
使用href属性后,看一从图片中红框处看到,返回按钮可以使用,点击后就可以返回上一个页面。
-
使用location的replace方法进行重定位:
示例
示例
使用replace方法后可以发现红框处所标的back按钮无法使用。
navigator对象:
navigator对象包含了浏览器和当前运行浏览器的系统的大量信息。前面也说过,因为浏览器的五花八门,导致了应用开发需要考虑浏览器之间的差异性。navigator对象则经常用于处理浏览器之间的差异性。通过它的属性我们可以确定用户的浏览器,浏览器版本,操作系统等信息,从而可以根据这些信息执行不同的代码。这种技术称为“浏览器嗅探”,还有一种代替该技术的技术叫做“特性检测”,专门用于检测当前浏览器是否支持某种特性。
geolocation对象:
geolocation是html5中为navigator对象添加的新的属性,再用户给予权限的情况下,可以获取当前设备的位置。
该对象有一个核心方法叫做getCurrentPosition。使用该方法时至少需要向方法内传入一个回调函数才可以,该函数会在确定完设备位置后执行。假设该函数命名为success,它将有一个参数,position,其是一个对象,可以通过其属性coords的属性latitude,longitude,altitude,speed属性来获取设备的纬度,经度,海拔以及计算机的速率等信息。该方法还可以传入第二个参数,其也是一个回调函数,该函数在获取位置失败后将会执行,该函数也有一个参数errorObj,该属性也是一个对象,其有两个属性,分别为code和message,分别对应失败原因的数值以及错误描述的信息,错误数值有以下几种:
- 页面无权限设备的位置
- 发生了内部错误
- 获取信息超时
下面通过一个小例子来加深印象:
<!DOCTYPE html>
<html lang = "en">
<head>
<title>just a test</title>
</head>
<body>
<script>
function success(position){
var coords = position.coords;
var latitude = coords.latitude;
var longitude = coords.longitude;
alert("u r at "+latitude+":"+longitude);
}
function fail(errorObj){
alert(errorObj.code+":"+errorObj.message);
}
navigator.geolocation.getCurrentPosition(success,fail);
</script>
</body>
</html>
执行上述代码可以看到如下效果:
执行效果
在开发者工具中输入如下代码可以得到如下效果:
示例
直接打开时,并没有询问我是否允许获取地理位置,这里有待研究。当我在开发者工具中输入代码时,弹出是否允许的消息,点击同意后,成功获取地理位置的信息。
screen对象:
screen对象同样也是window对象下的一个属性,其中包含了大量有关客户机显示的能力。
常用的属性有height,width,colorDepth等属相,分别用于查探屏幕的垂直,水平尺寸(单位:像素),以及屏幕的色彩位数。
document对象:
document对象是BOM中最重要和最常用的对象之一。因为通过它我们可以访问页面上的HTML元素及其属性和方法。
document对象有很多关联属性,如forms,images,links等。在之后的笔记中将会单独讲述dom对象的操作,所以在此不过多讲述。
images集合:
images是document对象的一个属性,它是一个集合,可以将它看做一个数组来使用。页面上的每一个img对象都将保存到该集合当中,我们可以通过对应的索引来获取对应的img对象。
links集合:
同images一样,links也是document对象的属性之一,它也是一个集合,只不过其中存放的都是页面中的超链接元素a对象。
上面讲述了一些浏览器常用对象,下面就来说说之前所讲述的浏览器“特性检测”技术和“浏览器嗅探”技术。
1.特性检测技术:
我们知道不同厂商的浏览器对于浏览器特性的支持是不一样的,所以当我们使用某一种特性时,很有必要先检测当前浏览器是否支持该特性,如果不支持则不应该执行相应的特性操作。
该方法的使用原理其实很简单,就是使用typeof运算符来返回所要使用的特性的描述值。
在javascript中,有一个神奇的特性,在条件语句中,它可以将任何值当做true或者false。除了boolean类型值false外,以下值在条件语句中也可以被看做false:
- 0
- “”(空字符串)
- null
- undefined
- [](空数组)
- false
除了以上,其它都会被看做true,因此我们可以通过typeof运算符检测所想使用特性的返回值,从而判断是否可以使用该特性,举例说明:
比如我们想要使用navigator.geolocation特性我们可以这样:
if(typeof navigator.geolocation != "underfined"){
...//可以使用该特性
}else{
...//不可以使用该特性\
}
正常情况如果可以使用,返回值应该是个object,不支持的时候则返回defined。可以根据不同特性的返回值来判断当前浏览器是否支持所想要使用的特性。
2.浏览器嗅探技术:
浏览器嗅探技术通常不被推荐,因为其有很多限制条件,但并不妨碍我们去了解一下。其工作原理是分析navigator对象appName属性和userAgent等属性。
userAgent属性是一个字符串,该字符串表示了一个浏览器的信息,但浏览器厂商可以自己进行修改,所以这也是限制因素之一。该值会因为不同浏览器而返回不同的值,所以使用时应多加注意,下面举例说明:
<!DOCTYPE html>
<html lang="en">
<head>
<title>just a test</title>
</head>
<body>
<script>
function getBrowserName() {
var lsBrowser = navigator.userAgent;
if (lsBrowser.indexOf("MSIE") >= 0) {
return "MSIE";
} else if (lsBrowser.indexOf("Firefox") >= 0) {
return "Firefox";
} else if (lsBrowser.indexOf("Chrome") >= 0) {
return "Chrome";
} else if (lsBrowser.indexOf("Safari") >= 0) {
return "Safari";
} else if (lsBrowser.indexOf("Opera") >= 0) {
return "Opera";
} else {
return "UNKNOWN";
}
}
function getBrowserVersion() {
var ua = navigator.userAgent;
var browser = getBrowserName();
var findIndex = ua.indexOf(browser) + browser.length + 1;
var browserVersion = parseFloat(ua.substring(findIndex, findIndex + 3));
return browserVersion;
}
var browserName = getBrowserName();
var browserVersion = getBrowserVersion();
if (browserName == "MSIE") {
if (browserVersion < 9) {
document.write("Your version of Internet Explorer is too old");
} else {
document.write("Your version of Internet Explorer is fully supported");
}
} else if (browserName == "Firefox") {
document.write("Firefox is fully supported");
} else if (browserName == "Safari") {
document.write("Safari is fully supported");
} else if (browserName == "Chrome") {
document.write("Chrome is fully supported");
} else if (browserName == "Opera") {
document.write("Opera is fully supported");
} else {
document.write("Sorry this browser version is not supported.");
}
</script>
</body>
</html>
使用该技术首先要对navigator.userAgent的返回值的格式要有一定的熟悉,否则无法正确的解析字符串,就无法来做出正确的判断。
因为其限制性比较大,所以最终还是推荐使用特性检测,除非是针对单个浏览器以外。
以上为本篇内容,回头看看,感觉记得内容着实有点儿乱,看到什么写什么,主要还是因为才开始接触javascript,理解不够深,相信随着学习的深入,笔记会越发的富有价值。