网页开发入门|14 脚本(上)
在网页上实现交互,需要使用脚本语言Script language来编写脚本。

上节课,我们了解了网页的交互能力,我们说到交互的三要素是事件、监听和脚本。
整个的交互过程特别像是在钓鱼:

网页元素开启的「监听」,仿佛是用来捕获「事件」的「钩子Hook」,静静地等待着咬钩。一旦「事件」上钩,就会立刻通知浏览器启动接下来的收网动作。
收网动作通常会由很多的步骤组成,起杆、收线、起鱼等等,而这些步骤就是我们所预设的「脚本」。
在网页上实现交互,需要使用脚本语言Script language来编写脚本。
脚本语言有很多,比如高度流行的Python、优雅的Ruby、在游戏开发中常用的Lua等等。
专为浏览器而生的Javascript,简称JS,被W3C
选入Web标准,成为今天在网页中几乎唯一能用的脚本语言。

我们本节课就来初步了解一下JS。
重写页面
在上节课,我们写了一个非常简单的脚本alert()
,用来在浏览器窗口中弹出一个提示框。
脚本还可以让页面根据用户的操作发生一些变化,比如说当用户点击了一个按钮,就让页面显示出新的内容。
使用document.write()
脚本,可以让我们向页面添加内容。
创建一个新的文件script.html
来体验一下这个脚本。
在页面中放置一个按钮,并为它添加鼠标点击的监听以及响应事件的脚本。
<button onclick="document.write()">click here</button>

在浏览器中点击按钮,发现页面变成了一片空白,页面被脚本重写了。
请注意,这里网页的URL没有发生变化,说明我们的页面确实是被JS重写了,而不是通过超链接打开了新页面。
和alert()
类似,我们可以通过添加额外的参数来告诉浏览器,要向页面中写入什么内容。
修改按钮监听中的脚本:
<button onclick="document.write('hello world')">click here</button>

可以看到,当我们点击下按钮,页面上的内容就被重写为了hello world
。
除了写入简单的字符,还可以向页面中写入带标签的内容。
<button onclick="document.write('hello <b>world</b>')">click here</button>

可想而知,如果我们把另外一个网页的全部HTML
代码都作为参数放到到这个脚本中,点击这个按钮就可以为用户重写一个全新的页面。
选取元素
通常,我们并不需要把整个页面全部重写,而只是需要修改页面中的局部内容,也就是修改某个元素,这就要求我们必须准确的指明要修改的元素是哪个。
还记得我们在CSS
中也有类似的需求么?我们在CSS
使用选择器,就可以告诉浏览器将对应样式应用在选择器选中的元素上。

遗憾的是,JS
没有提供通过CSS
选择器来选中元素的功能,但是元素标签中的id
属性,仍然可以帮助JS
获取元素。
一些JS的扩展库,如jQuery提供了使用CSS选择器选中元素的功能。
我们先为元素添加上id
属性。
<p id="greeting">hello, world!</p>
这时,便可以使用document.getElementById()
,来获取我们需要的元素了。
<button onclick="document.getElementById('greeting')">click here</button>
参数'greeting'
帮助我们获取到了id
为greeting
的这个p
元素。
但是如果这时按下按钮,什么都不会发生。因为我们仅仅是得到了一个元素,并没有告诉浏览器要对这个元素做些什么。

在对元素做进一步的操作之前,我们可以先用alert()
来确认一下,是否成功选中了p
元素。
请注意,使用alert()
弹出内容,需要将内容作为参数放进括号里,所以我们需要把document.getElementById('greeting')
这整句话放进括号里,像这样:
<button onclick="alert(document.getElementById('greeting'))">click here</button>

点击按钮看一下,它显示的不是hello world
,而是[object HTMLParagraphElement]
。
object
指明了我们获取到是一个对象Object。对象可以理解为虚拟的物体,类似于我们现实中的桌子、汽车、鼠标等等,会有一些属性,还有一些功能。
比如汽车,就有尺寸、品牌、油耗等属性,还有行驶、刹车等功能。
在JS中,元素被看作是一种对象,而且是一种DOM(文档对象模型Document Object Model)对象,HTMLParagraphElement
便是DOM中的一种,也就是p元素。
DOM对象的属性和功能都是由W3C制定好的,方便我们在脚本中使用。
代码document.getElementById()
中的document
也是一种是DOM对象,它拥有一个名为getElementById
的功能。使用.
便可以从对象中获取属性或功能。
我们会在下节课展开讲解DOM,并利用它们对页面内容进行修改。
常量
在下节课,我们将多次使用这个p
元素,并对它进行操作和修改。
如果每次都用document.getElementById('greeting')
来获取它,实在是太长太不方便了。所以先别着急,让我们先为它起一个临时的代号。
比如,我们可以用字母p
来作为代号,代码如下:
const p = document.getElementById('greeting')
我们来看一下这里的新语法。
等号=
的右边是原本获取元素的脚本document.getElementById('greeting')
,通过=
,将它所得到的元素传递到左边的p
中。
等号=
的左边,p
前面还有一个const
,是常量constant的缩写,意为永远不变,不许修改的意思。
什么意思呢?
我们知道,在代数中经常使用字母x
来表示变量,x
的值是可以发生变化的,可以x=1
也可以x=-0.5
,有时候也可以用x ∈ [-1,1]
表示x
的取值范围。
相对的,const
所指的常量,类似于我们给圆周率起名叫π
,只要说到π
就等于3.1415......
,永远不会改变。
在我们的脚本中,使用const
来约定了字母p
作为一个常量指代p
元素,这个过程也称作常量的定义defined。
如果尝试在脚本中使用一个没有被定义的常量,将会获得undefined。
当然,在命名常量时可以不止使用一个字母,我们也鼓励使用单词或词组来对常量命名,增强代码的可读性。
const paragraph = document.getElementById('greeting')
const paragraphElement = document.getElementById('greeting')
当使用词组时,可以使用驼峰法(Camel-Case)命名,即除了第一个单词以外,后面的单词首字母都使用大写。用这样的方法命名,一会高一会低,很像骆驼的驼峰,因此得名。
联合alert()
,代码可以变成这样:
const paragraph = document.getElementById('greeting');
alert(paragraph)
让我们放进整体脚本中,看一下效果:
<button onclick="const paragraph = document.getElementById('greeting'); alert(paragraph)">click here</button>
提醒你,多个语句之间要使用;
分割哦!

问题又来了,paragraph
是常量的代号,那如果我们想要paragraph
这个单词本身,也称作字面量literal,该怎么办呢?
给它加上单引号!
<button onclick="const paragraph = document.getElementById('greeting'); alert('paragraph')">click here</button>

这就是我们上节课中给参数加上'
单引号的原因,用于区分常量和字面量。
延伸阅读:JS的诞生
JS名字里有个Java,却和那个著名的Java语言没有亲戚关系,甚至JS之父Brendan Eich还挺看不上Java的。

上世纪90年代,网景公司(Netscape)发布了历史上一个有商业意义的浏览器Navigator,但当时的网页就像咱们之前的网页一样,没有交互能力,只能用来浏览。
这个时候Java语言正是大红大紫,网景的高层就决定:未来的网页脚本语言必须"看上去与Java足够相似",但是比Java简单,并起名叫Javascript。
网景员工Brendan Eich接到这一「简化Java」的重任。但是,他是一个函数式编程语言的忠实粉丝,对采用了对象式编程的Java并不喜欢。
为了应付公司安排的任务,他只用10天时间就把Javascript设计出来了。
它借鉴C语言的基本语法;借鉴Java语言的数据类型和内存管理;借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位;借鉴Self语言,使用基于原型(prototype)的继承机制。
"与其说我爱Javascript,不如说我恨它。它是C语言和Self语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:'它的优秀之处并非原创,它的原创之处并不优秀。'(the part that is good is not original, and the part that is original is not good.)"
参考资料:
阮一峰的网络日志 《Javascript诞生记》
我将本课程所有的代码托管在gitee
上了,你可以点击这个链接,或到gitee.com
上搜索弦五 网页开发入门,查看和获取本课程的全部代码。