title: JavaScript学习记录四

toc: true

date: 2018-09-16 20:31:22


——《JavaScript高级程序设计(第2版)》学习笔记

要多查阅MDN Web 文档


BOM

Browser Object Model,浏览器对象模型。

BOM提供了很多用于访问浏览器的功能,这些功能与任何网页内容无关。

BOM缺少事实上的规范,因此浏览器之间共有的对象就成了事实上的标准。

没有所谓的标准BOM实现或者标准BOM接口。

图片来源于网络:

window对象

window文档

BOM的核心对象是window,表示浏览器的一个实例。

在浏览器中,window对象有双重角色:

  • 通过JavaScript访问浏览器窗口的一个接口
  • ECMAScript规定的Global对象

因此window对象有权访问parseInt()等方法。

全局作用域

因为window对象又是ECMAScript中的Global对象,因此在全局作用域中声明的所有变量、函数都会变成window对象的属性和方法。

在全局作用域中,this指向window。

!窗口关系及框架

因为书中使用的frameset和frame已经被HTML5废弃,用iframe取代,因此在看了HTML5后再来补充这一部分。

top、parent、一个框架一个window对象

!窗口位置

screenLeft、screenX、moveTo等属性等看完文档再来详细记。

!窗口大小

innerWidth、outerWidth、clientWidth、pageWidth、resizeTo()等属性等看完文档再来详细记。

导航和打开窗口

window.open() 方法用于打开一个新的浏览器窗口或查找一个已命名的窗口,返回指向新窗口的引用。

window.open(URL,name,specs,replace),具体格式看这里

新创建的window对象有一个opener属性,保存着打开它的原始窗口对象。

安全限制

弹窗广告问题。

为了解决这个问题,有些浏览器开始在弹出窗口配置方面增加限制。

弹出窗口屏蔽程序

弹出窗口被屏蔽有两种可能:

  • 被浏览器内置的屏蔽程序阻止,则window.open()很有可能返回null
  • 被浏览器扩展或其他程序阻止,则window.open()通常会抛出异常

因此要想准确地检测弹出窗口是否被屏蔽:

var blocked = false;
try {
var popup = window.open("https://blog.zmj97.top", "_blank");
if (popup == null) {
blocked = true;
}
} catch(e) {
blocked = true;
}
if (blocked) {
alert("The Popup was blocked!");
}

检测弹出窗口是否被屏蔽并不会阻止浏览器显示与被屏蔽窗口的相关信息。

超时调用

setTimeout()函数接受两个参数,要执行的代码和执行代码前要等待多少毫秒。

第一个参数可以是一个包含JavaScript代码的字符串(不推荐,就和在eval()函数中使用的字符串一样),

也可以是一个函数:

setTimeout("alert('Hello World!')", 1000); // 不推荐

// 推荐的调用方式
setTimeout(function() {
alert('Hello World!');
}, 1000);

调用setTImeout()后,该方法会返回一个数值ID,表示超时调用,

可以用它作为参数调用clearTimeout()来取消超时调用。

超时调用ID是计划执行代码的唯一标识符。

// 设置超时调用
var timeoutId = setTimeout(function() {
alert('Hello World!');
}, 1000);
// 把它取消
clearTimeout(timeoutId);

超时调用的代码都是在全局作用域中执行的,因此函数中的this的值通常指向window对象。

间歇调用

setInterval()函数接受两个参数,要执行的代码和每次执行代码前要等待多少毫秒。

setInterval("alert('Hello World!')", 1000); // 不推荐

// 推荐的调用方式
setInterval(function() {
alert('Hello World!');
}, 1000);

取消间歇调用:

var num = 0;
var max = 10;
var intervalId = null; function incrementNumber() {
num++;
// 如果执行次数到达max,则取消间歇调用
if (num == max) {
clearInterval(intervalId);
alert("Done");
}
} intervalId = setInterval(incrementNumber, 500);

实际上,使用超时调用来模拟间歇调用被认为是最佳模式,因为后一个间歇调用可能会在前一个间歇调用结束之前启动。

var num = 0;
var max = 10; function incrementNumber() {
num++;
// 如果执行次数未到达max,则设置另一次超时调用
if (num < max) {
setTimeout(incrementNumber, 500);
} else {
alert("Done");
}
} setTimeout(incrementNumber, 500);

系统对话框

alert()只有一个确认按钮

confirm()有确认和取消两个按钮,返回true表示点了确认,false表示点了取消

prompt(),提示框,有一个文本输入域和确认取消按钮,两个参数为要显示给用户的提示内容和文本输入域内的默认内容,如果点击确认则返回文本输入域的值,否则返回null。

三者均不涉及HTML、CSS、JavaScript。

还有含有复选框的对话框选择是否阻止后续的对话框的显示。

还可以在JavaScript中通过window.print()window.find()来显示打印和查找对话框。这两者是异步显示的,因此对话框计数器的不会吧它们计算在内。

location对象

提供了与当前窗口中加载的文档有关的信息和一些导航功能。

location对象既是window对象的属性,有事document对象的属性。

location将URL解析为独立的片段。

下面是location对象的所有属性(忽略了每个属性前的location前缀):

属性名 例子 说明
hash "#contents" 返回URL中的hash(#号后跟零或多个字符),如果URL中不包含散列,则返回空字符串
host "blog.zmj97.top:80" 返回服务器名称和端口号(如果有)
hostname "blog.zmj97.top" 返回不带端口号的服务器名称
href "https://blog.zmj97.top" 返回当前加载页面的完整URL。location对象的toString()方法也返回这个值
pathname "/tag/" 返回URL中的目录和/或文件名
port "8080" 返回URL指定的端口号。如果URL中不包含端口号,则返回空字符串
protocol "https:" 返回页面使用的协议,通常是http:或https:
search "?q=javascript" 返回URL的查询字符串。这个字符串以问号开头

查询字符串参数

尽管location.search返回从问号到URL末尾的所有内容,但却没有办法逐个访问每个查询字符串参数,因此可以:

function getQueryStringArgs() {
// 取得查询字符串并去掉开头的问号
var qs = (location.search.length > 0 ? location.search.substring(1) : "");
// 保存数据的对象
var args = {};
// 取得每一项
var items = qs.split("&");
var item = null,
name = null,
value = null;
// 逐个添加到args中
for (var i = 0; i < items.length; i++) {
item = items[i].split("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
args[name] = value;
} return args;
}

位置操作

location.assign("https://blog.zmj97.top"),立即打开新URL并在浏览器的历史记录中生成一条记录。

window.location = "https://blog.zmj97.top"location.href = "https://blog.zmj97.top"与调用assign()的效果一样。

每次修改location对象的属性,页面都会以新URL重新加载(hash除外),并在浏览器的历史记录中生成一条新纪录(包括hash)。

使用location.replace("https://blog.zmj97.top")加载新页面后不会生成历史记录,也不能后退。

location.reload()重新加载,有可能从缓存中加载

location.reload(true)从服务器重新加载

位于reload()调用之后的代码可能会也可能不会执行,取决于网络延迟或系统资源等因素。

因此最好将reload()放在代码的最后一行。

navigator对象

用于识别客户端浏览器,包含有关浏览器的信息。

检测插件

navigator.plugins数组的每一项包含下列属性:

  • name:插件名字
  • description:插件描述
  • filename:插件文件名
  • length:插件所处理的MIME类型数量
// 检查插件(IE中无效)
function hasPlugin(name) {
name = name.toLowerCase();
for (var i = 0; i < navigator.plugins.length; i++) {
if (navigator.plugins[i].toLowerCase().indexOf(name) > -1) {
return true;
}
} return false;
}

每个插件对象本身也是一个MimeType对象的数组,包括四个属性:

  • MIME类型描述description
  • 回指插件对象的enablePlugin
  • MIME类型对应的文件扩展名的字符串suffixes(以逗号分割)
  • 完整MIME类型字符串type

在IE中检查插件只能使用专有的ActiveXObject类型,还要知道插件的COM标识符。

plugins集合有一个refresh()方法用于刷新插件,传入true会加载包含插件的所有页面。否则只更新插件不重新加载页面。

注册处理程序

registerContentHandler()、registerProtocalHandler()

为站点指明处理特定类型的信息

screen对象

所有浏览器都支持的属性:

  • availHeight:可用的屏幕高度(像素高度-系统部件高度),只读
  • availWidth:可用的屏幕宽度(像素宽度-系统部件宽度),只读
  • colorDepth:用于表现颜色的位数,多数系统都是32位,只读
  • height:屏幕的像素高度
  • width:屏幕的像素宽度

history对象

保存用户上网的历史记录

使用go()方法可以在用户的历史记录中任意跳转

history.go(-1); // 后退一页
history.go(2); // 前进两页
history.back(); // 后退一页
history.forward(); // 前进一页

也可以传入一个字符串:浏览器会跳转到历史记录中最近包含该字符串的页面

history.go("wrox.com"); // 跳转到最近的wrox.com页面

客户端检测

不到万不得已,不要使用客户端检测。

先设计最通用的方案,然后再使用特定于浏览器的技术增强该方案。

能力检测

又称特性检测,是最受人们接受的检测方式。

能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。

不用顾及特定的浏览器如何如何,只要它支持特定的能力,就可以给出解决方案。

基本模式:

if (object.propertyInQuestion) {
// 使用object.propertyInQuestion
}
  • 先测试达成目的的最常用的特性
  • 必须测试实际要用到的特性,而不是通过判断另一个特性是否存在来判断是什么浏览器,然后决定是否用这个特性

如果确定自己的应用程序需要使用哪些特定的浏览器特性,最好一次性检测所有相关特性:

// 确定浏览器是否支持Netscape风格的插件
var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);

在实际开发中,应该将能力检测作为确定下一步解决方案的依据,而不是用它来判断用户使用的是什么浏览器。

怪癖检测

怪癖检测的目标是识别浏览器的特殊行为,知道浏览器存在什么缺陷。

例如IE中有一个bug,如果某个实例属性与标记为[[DontEnum]]的某个原型属性同名,则该实例属性不会出现在for-in循环中:

var hasDontEnumQuirk = function() {
var o = {
toString: function() {}
};
for (var prop in o) {
if (prop == toString) {
return false;
}
}
return true;
}();

怪癖通常为某个浏览器独有的,且被归类为bug。

由于检测怪癖涉及运行代码,因此仅检测有直接影响的怪癖,且最好在脚本一开始就执行此类检测,以便尽早解决问题。

JavaScript学习记录四的更多相关文章

  1. JavaScript学习记录二

    title: JavaScript学习记录二 toc: true date: 2018-09-13 10:14:53 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...

  2. leveldb 学习记录(四)Log文件

    前文记录 leveldb 学习记录(一) skiplistleveldb 学习记录(二) Sliceleveldb 学习记录(三) MemTable 与 Immutable Memtablelevel ...

  3. JavaScript学习记录三

    title: JavaScript学习记录三 toc: true date: 2018-09-14 23:51:22 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...

  4. JavaScript学习记录一

    title: JavaScript学习记录一 toc: true date: 2018-09-11 18:26:52 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...

  5. 4.VUE前端框架学习记录四:Vue组件化编码2

    VUE前端框架学习记录四:Vue组件化编码2文字信息没办法描述清楚,主要看编码Demo里面,有附带完整的代码下载地址,有需要的同学到脑图里面自取.脑图地址http://naotu.baidu.com/ ...

  6. javascript学习笔记(四) Number 数字类型

    数字格式化方法toFixed().toExponential().toPrecision(),三个方法都四舍五入 toFixed() 方法指定小数位个数  toExponential() 方法 用科学 ...

  7. Javascript学习笔记四——操作表单

    Javascript学习笔记 大多网页比如腾讯,百度云之类的需要登陆,用户输入账号密码就可以登陆,那么浏览器是如何获取用户的输入的呢?今天就记录一下操作表单. 操作表单与操作DOM是差不多的,表单本身 ...

  8. leveldb 学习记录(四) skiplist补与变长数字

    在leveldb 学习记录(一) skiplist 已经将skiplist的插入 查找等操作流程用图示说明 这里在介绍 下skiplist的代码 里面有几个模块 template<typenam ...

  9. JavaScript学习记录总结(四)——js函数的特殊性

    <script type="text/javascript">  //当局部变量与全局变量 重名的时候   var v="全局变量";//定义全局变 ...

随机推荐

  1. Hadoop 三剑客之 —— 分布式文件存储系统 HDFS

    一.介绍 二.HDFS 设计原理     2.1 HDFS 架构     2.2 文件系统命名空间     2.3 数据复制     2.4 数据复制的实现原理     2.5 副本的选择     2 ...

  2. oracle (9I/10G/11G)数据库日志挖掘(审计误操作)

    文档结构: 资料来自官方网站: https://docs.oracle.com/cd/E11882_01/server.112/e22490/logminer.htm#SUTIL019 来自论坛: h ...

  3. 粘性固定属性 -- position:sticky

    概述 position: sticky,这是一个比较容易忽略的css3 position 新属性,它的作用即为实现粘性布局,它是 relative 与 fixed 的结合. 用法 默认情况下,其表现为 ...

  4. Spark基本运行流程

    不多说,直接上干货! Spark基本运行流程 Application program的组成 Job : 包含多个Task 组成的并行计算,跟Spark action对应. Stage : Job 的调 ...

  5. 路飞学城Python-Day35

    08-初识SQL语句 数据库客户端操作的内容(增查改删): 1.操作数据库 操作数据库 增(本质上就是创建一个本地文件夹) create database db1 charset utf8; 查 查看 ...

  6. Codeforces 675B Restoring Painting

    链接:传送门 题意:给出3 × 3的方块,其中任意2 × 2的方块和左上角2 × 2的和相等,还给出9个格子中的4个--a,b,c,d ,在1~n中选择一些数(可重复)填入剩下5个格子中,问有多少种填 ...

  7. BZOJ 3282 Link Cut Tree (LCT)

    题目大意:维护一个森林,支持边的断,连,修改某个点的权值,求树链所有点点权的异或和 洛谷P3690传送门 搞了一个下午终于明白了LCT的原理 #include <cstdio> #incl ...

  8. 1、使用Python3爬取美女图片-网站中的每日更新一栏

    此代码是根据网络上其他人的代码优化而成的, 环境准备: pip install lxml pip install bs4 pip install urllib #!/usr/bin/env pytho ...

  9. Proxychains安装

    没有管理员权限 1.建立文件夹proxychains,并进入下载 mkdir proxychains cd proxychains wget https://sourceforge.net/proje ...

  10. zoj 3471 Most Powerful(状压dp+Tsp问题+连续性问题)

    上来直接一波敲键盘,直接套Tsp问题的代码 然后WA 发现貌似这道题没有连续性. Tsp问题是一条路径,一个点到另一个点,多了一个限制,所以就需要加多一维 而这道题没有限制,也就是说那一维不需要加,我 ...