从编程小白到全栈开发:操控浏览器

一个程序猿和普通电脑用户,当他们浏览到一个效果炫酷的网页的时候,他们的反应是不太相同的:

普通用户会“我靠”一声,随即拿起手中的鼠标,到处点来点去,欣赏网页的精彩内容和炫酷效果;

而程序猿的反应,在“我靠”过后,脑子里即泛出无数的div+css,可能还会有js,并且快速用鼠标右键或键盘快捷键,默默的打开浏览器的开发者工具,边查看网页的代码边点着头“原来如此......”

Chrome的开发者工具

身为程序猿的我们,无时无刻不想着一探那光鲜表面下真实的存在,这是我们的优良美德,查看别人的程序是怎么实现的,是一种快速学习和成长的途径。

JS全栈开发者所进行的前端开发,主要是以浏览器为载体,利用浏览器开放给我们的能力,组合出我们所期望的功能。所以学习如何控制浏览器,是我们的主要目标。

叠纸片

在前面的文章中我们提到过,一个基于浏览器的网页Web应用,构成它骨架的那部分,是HTML,我们在界面上看得到的内容,基本都是由HTML元素所构建成的,一行文字、一个输入框、连一块空白部分,也都来源于HTML元素。

编写一个HTML页面的过程,在我看来,就像是在一张大纸片上按照我们的设想去叠放小纸片的过程。纸片与纸片之间的摆放关系,有上下级的关系、也有兄弟同级的关系,比如用以下这个例子来理解:

示例1

一个HTML文件中的<body>元素,相当于那张铺在桌子上的最大的纸片;然后,我们在这张大纸片上,放了一张叫做container-1的小一点的灰色纸片;接着,又在container-1这张灰色纸片上面,顺序摆放3张分别带有文字的橙色纸片。

从上图右半部分的开发者工具栏中,我们可以清晰的看到这种摆放形态所对应的HTML代码:名为container-1的<div>标签是在<body>标签下一级,3个名为container-2的<div>又是在container-1的下一级,同时这3个container-2互为同级关系。

这种关系,可以用一张图来清晰的把它们的关系展示出来:

HTML DOM树

这看起来像一颗倒置的树,最上面是唯一的树根,往下是分支树杈和树叶。这张图中的每一个方框代表的HTML标签节点,我们叫它DOM节点(Document Object Model,文档对象模型),所以这一整棵树就叫做DOM树了。

再复杂的页面,归根结底,也都只是由这种简单的堆叠关系组成的,只不过是层次更深一些,DOM节点更多一些罢了。所以当你拿到设计师给你的页面平面设计稿的时候,别急着写代码,你首先需要分析一下页面的结构,在脑海中想象一下如何叠出这个页面的纸片模型或DOM树,这样你在写代码的时候就会比较胸有成竹,更有效率。

上帝之手

当一份HTML代码被写好并在浏览器中运行后,它并不是就固定下来,一成不变了。我们有办法随时感知所有这些HTML元素的状态(位置,尺寸,颜色等等)、随时挪动改变它们的层级关系、删除元素、或者创建新的元素。就如一只上帝之手,在触摸和摆弄着这些纸片。

这只上帝之手,就是浏览器开放给我们的JS API,通过JavaScript编程的方式,我们可以很灵活的去访问和操纵这棵DOM树。我们可以通过一些例子来学习和理解JS API的用法,由于起初的这些代码会比较简单,我们也没必要去专门创建js文件,只要借助浏览器自带的开发者工具,就可以很方便的随手运行我们的js代码片段。

window对象

让我们进入开发者工具的console这一栏,我们可以在这里直接输入并运行JS代码,并立即可看到执行结果,这真是我们学习实践的好帮手啊!

来,让我们输入以下内容,并按回车键试试:

window

我们立马就看到了控制台上输出一个类型为Window的对象,让我们展开这个对象,查看详细内容,能看到如下图所示的内容:

window对象

window对象代表了当前的浏览器窗口,它是我们整个前端编程生涯中,最应该记住的一个对象,因为它包含了所有浏览器开放给JS的API,也就是说,所有的API都可以通过window对象来进行使用。

比如alert()这个函数,我们就可以这样来使用:

window.alert('Hello, world');

所有window对象上的属性和方法,都可以省略window.,直接使用,如下所示:

alert('Hello, world');

我们来看一下在开发者工具控制台中输入后的效果:

控制台测试

这样一个alert()函数,就是浏览器开放给我们的API,提供给我们弹出一个自定义消息框的能力。

为了巩固加深一下映像,让我们再来一个。随便打开一个网站,然后打开开发者工具,在控制台中输入window.locationlocation,我们就能得到这样一个Location对象,这就是通过调用浏览器API,来查看浏览器当前打开的网页的地址信息的例子。

location

更进一步,我们还能通过这个得到的Location对象,对当前页面进行刷新、跳转到别的网页等操作。你们可以自己来试试如下的代码吧:

window.location.reload();
window.location.replace('http://www.qq.com');
document对象

从上文我们已经了解了浏览器JS API的结构,所以,document对象它也是附属于window对象的一个对象,我们可以通过window.documentdocument来直接访问到它。它代表的,正是由我们的HTML代码所建立的DOM树,所有需要对我们的网页HTML元素(也称作DOM节点)进行访问或操作的行为,都会直接或间接的通过document对象来实现。

document

说到要操作这棵DOM树,首先不得不谈的就是如何去定位DOM节点,在这棵节点众多的树上,如何精准的找到我们想访问或操作的DOM节点,是头等重要的事情,就像打靶的话首先得找到正确的靶子才行啊!

我们知道,去寻找和识别一件事物,需要观察它们具有的特征,发现和目标事物有所匹配的线索。而对于DOM节点来说,它们也会有一些独特的特征,最简单和明显的特征,就是DOM标签的名字:

<div></div>
<h1></h1>
<p></p>
<input type="text" />

功能不同的DOM标签拥有不同的标签名,如div, h1, p, input等等,分辨它们就如分辨大象,老虎,老鼠,河马一样容易。

那如果DOM标签都是同一个,那怎么办?就如我们现在要去观察一大堆喵,它们可都是喵啊,你怎么去区别它们?没事,我们可以根据它们的大小,颜色,品种,产地等信息,来做详细的区分。

<div class="cat big red"></div>
<div class="cat big blue"></div>
<div class="cat medium red"></div>
<div class="cat medium white"></div>
<div class="cat small orange"></div>

由上面的代码我们可以看出,在我们创建这些div的时候,给他们加了些天赋属性点,虽然它们都是div,但它们已经是不同的div了,我们一眼就能看出它们之间的区别来。

心思缜密的同学看到这里就会有疑问了,如果以标签名字,或者分类信息这些特征来定位区分,也难保有同名同姓,或者长得一模一样的人或事物啊。没错,肯定会有这种情况发生!但是这个问题肯定是难不倒我们的,身份证这种东西,不就是为了避免这样的情况发生的么?DOM标签,我们也可以给它们设置一个唯一的身份证号(ID):

<div id="cat001" class="cat">...</div>
<div id="cat002" class="cat">...</div>
<div id="cat003" class="cat">...</div>

就这样,只要报出身份证号,比如cat002,三只喵里面肯定会站出那只符合身份证号码的喵来。

这套用于查找定位DOM的机制,我们称作选择器(Selector)。

好,我们现在大致了解了这样一种定位机制的原理,那下面来看一下,如何在实际编码中使用这种选择器查找定位我们需要的DOM节点。

在很久之前,浏览器开放的JS API,对这套选择器机制的支持还是不太完善的,没有形成一个统一的API接口,我们通常有一些零散的API来完成这些事情:

//通过标签名来获取所有是该标签名的DOM节点
document.getElementsByTagName('div');

//通过ID来获取一个DOM节点
document.getElementById('cat001');

有些API还是缺失的,比如通过标签的属性名和属性值,通过标签的class等方式来获取DOM节点,需要自己去手动处理。直到像Prototype,jQuery,Mootools之类的前端JS工具库的兴起,它们都自带了一套比较完整的用于执行选择器的API,由于它们太好用了,倒逼了浏览器标准,使得类似的选择器API出现在了现代的浏览器中。我们可以来看一下它们的用法:

// 1)jQuery的选择器API
$('input');   // 查找所有标签名为input的元素
$('#cat001');  // 查找id为cat001的元素,id前加#号
$('.red');   // 查找class属性中包含有red的元素,class名字前加.号

// 2)现代浏览器提供的和jQuery功能相对等价的选择器API
document.querySelectorAll('input');
document.querySelectorAll('#cat001');
document.querySelectorAll('.red');

是不是看起来比老的API清晰也更统一了?而且我相信大多数人会更喜欢jQuery的写法,清新爽洁不紧绷啊!不过浏览器提供的API毕竟是自带的原生的API,是行业标准,不需要引入第三方库也能直接使用(在你的网页不需要兼容老的浏览器的情况下),有它自身的一些优势,所以学习和熟悉它们也是很有必要的。

另外,选择器的语法也不止上面提及的这3种,还有一些如级联、伪类等,这些都留给你们自己去进一步学习了解了。

下面我们来几个例子,看一下怎么选择器API的实际运用。仍然拿我们最前面的HTML页面入手,我们要给三个橙色的div,加上一个白色的边框。在开发者工具栏中,直接输入以下代码:

// 通过选择器API,利用class都为container-2的特征,获取到三个橙色的div
var list = document.querySelectorAll('.container-2');

// 循环,为其中的每一个div设置边框样式
for (var i = 0; i < list.length; i++) {
  var el = list[i];
  el.style.border = '2px solid #FFFFFF';
}

添加边框

我们可以看到,选择器精确的获取到了三个class名为container-2的DOM节点,并为其设置了边框样式。

接着,再试试这段代码,目标是要删除第二个橙色的div:

var list = document.querySelectorAll('.container-2');
list[1].remove();

我们可以立即观察到,那个内容为"Section B"的橙色div已经从DOM树中消失了。

删除第二个橙色div后

通过上面这一系列小小的例子,你是不是已经对怎么来操作DOM有了一个大概的了解了?基本的原则,归结起来其实很简单:

  • 第一步:先找到目标DOM
  • 第二步:通过调用DOM提供的函数或设置DOM的属性

复杂的事情,其实都是由一些最简单的步骤组合堆砌起来的。

其他

浏览器提供的丰富的API中,有可以用来和服务器端进行通信和数据交互的,有用来处理视频音频的播放的,有用来进行绘图的,也有用来取得地理位置经纬度信息的......通过调用API,我们就能达到操控浏览器,完成我们希望它为我们完成的工作。

用最通俗的语言,讲述最技术的故事。 欢迎关注一斤代码的系列课程《从编程小白到全栈开发》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏web前端教室

周末浅谈-WEB前端组件

image.png 随着前端业务复杂化的不断加深,前端交互流程也愈加复杂,所以angularJs,vueJs,avalonJs等许多前端框架都出现了,它们不像J...

1965
来自专栏河湾欢儿的专栏

html5标签

什么是html5? 仅仅是狭义的概念。h5草案前身叫做web application 由WHATWG组织编写,在2007年提交到了w3c,w3c起名叫做HTM...

3421
来自专栏angularejs学习篇

angularjs学习第五天笔记(第二篇:表单验证升级篇)

您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指...

1061
来自专栏张善友的专栏

強大的jQuery Chart组件-Highcharts

Highcharts是一个制作图表的纯Javascript类库,主要特性如下: 兼容性:兼容当今所有的浏览器,包括iPhone、IE和火狐等等; 对个人用户完全...

3175
来自专栏阿凯的Excel

在Excel内实现跳跃!

今天和大家分享Excel中跳跃的神器。 想提跳跃,你会想到什么? 嗯 思路对了,我们实现的就是在Excel内实现跳棋。直接说需求吧! 我有好几千行的数据 ...

4023
来自专栏angularejs学习篇

angularjs学习第五天笔记(第二篇:表单验证升级篇)

您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指...

903
来自专栏liuchengxu

如何使用 Vim 的 help

实际上,无论是 Vim 的基础知识还是进阶知识,大都可以从 help 中找到指引。但是我想很多人并没有意识到这一点,或者并没有重视这一点。RTFM (read ...

742
来自专栏葡萄城控件技术团队

Angular和Vue.js 深度对比

Vue.js 是开源的 JavaScript 框架,能够帮助开发者构建出美观的 Web 界面。当和其它网络工具配合使用时,Vue.js 的优秀功能会得到大大加强...

6863
来自专栏前端杂货铺

关于首屏时间采集自动化的解决方案

关于首屏 首屏时间是指从转向该页面到屏幕中该页面所有内容都可见时的时间。已经有太多的关于首屏时间的计算,在本文中并不重复阐述这些已经被提出或者实现的方案,而旨...

5797
来自专栏RESTART POiNTER

Web动态图片合成与分享——html2canvas方案实践

在web侧运营活动中,分享传播是重要的一环。普通的h5链接/结构化消息分享已经不能满足产品越来越大的脑洞。在很多场景下,我们需要将个性化内容(如帐号信息,头像,...

2.2K2

扫码关注云+社区

领取腾讯云代金券