在简单学习了 HTML 和 CSS 之后,接下来是 JavaScript
的学习,学习的重点不是 JavaScript 作为一个脚本语言的语法内容,而是
JavaScript 对于网页的控制,参考教程:https://developer.mozilla.org 。
HTML 定义了网页的内容
CSS 描述了网页的布局
JavaScript 控制了网页的行为
1. 在 HTML 中使用 JS
在 HTML 和 CSS 一起组装成一个网页之后,浏览器的 JavaScript 引擎将执行
JavaScript 代码,这保证了当 JavaScript
开始运行之前,网页的结构和样式已经就位,然后 JS
可以更新这个网页的具体内容等。
对于浏览器,它的每一个标签页使用了一个独立的运行环境,不同标签页之间没有任何联系,JS
代码也相互独立运行,一定程度上保证了信息安全。
script 标签
在 HTML 的 head 或者 body 部分都可以使用,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <title > demo title</title > </head > <body > <script > console .log ("使用JavaScript" ); document .write ("<h1>这是一个标题</h1>" ); </script > </body > </html >
建议在 body
部分的最后使用(也就是</body>
之前),否则加载时可能遇到
HTML 元素还没出现等错误,通常 JS 需要等待 HTML/CSS
加载完成后进行执行,对网页进行进一步的处理。
链接 JS 文件
导入外部的 js 文件,在 HTML 的 head 或者 body
部分都可以使用,例如:
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <title > demo title</title > </head > <body > <script src ="abc.js" > </script > </body > </html >
加载逻辑
对于外部脚本的加载执行,默认情况下,浏览器处理 HTML/CSS
生成页面时,遇到<script>
元素时会中断页面的加载,立刻加载脚本并执行,然后加载页面的剩余部分。
可以使用 async
进行异步化加载,它告知浏览器:在遇到<script>
元素时不要中断后续页面的加载,异步地进行脚本加载,等到
JS 脚本下载完成时中断页面的处理,执行脚本,执行完成后继续加载页面。使用
async 引入的脚本建议不要修改页面内容,并且不能依赖其他脚本,因为对于多个
async,加载的进度不可控,因此执行的顺序也不可控。
1 <script async src ="abc.js" > </script >
可以使用 defer
进行,它明确告知浏览器:遇到<script>
元素时异步进行脚本加载,等到整个页面加载结束,才会执行脚本,脚本会在
DOMContentLoaded
事件触发之前执行完,并且对于多个脚本按照出现的顺序依次执行,例如
1 2 3 4 5 <script defer src ="js/script1.js" > </script > <script defer src ="js/script2.js" > </script > <script defer src ="js/script3.js" > </script >
2. JS 基础语法
作为脚本语言,JS 和 Python 非常类似,首先过一遍语法。
JS 的语句使用大括号划分语句块的结构层次等。
JS 对于大小写敏感!
JS
语句可以不使用结束符,但是建议使用分号作为语句的结束,没有分号的语句出现在行末总是默认语句结束了。
JS 支持注释,包括/**/
和//
都可以。
基本字面量
数字 Number 包括整数和小数;(整数和小数根本不分开,特别注意)
字符串 String 例如a="John"
,支持索引访问(从 0
开始),可以直接获取长度a.length
;
布尔类型 Boolean 例如 true 和 false;
数组 Array 例如[1,2,3]
;
对象 Object 例如{name:"abc",length:20}
;(JSON
语法就是由此衍生的,最后一个不要加逗号)
函数 Function 例如function fa(a,b){ return a*b; }
数字字符串可以与数字互相转换类型:
1 2 3 4 (123 ).toString (); String (123 ); Number ("3.14" );
变量
和 Python 一样,JS 变量是没有固定类型的,变量可以赋任何类型的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 var a, b; a = 1 ; var length = 16 ; var length; length = undefined ; var name = "John" ;document .getElementById ("demo" ).innerHTML = name;
可以使用 typeof 获取当前变量的类型,例如
不声明直接使用变量也是可以的,这时会自动视为 window
的一个属性,例如
对于var a
等变量声明语句,JS
解析时采用了声明提升的规则,也就是会自动把变量声明语句(不含初值)移动到语句块的最前方。
函数
见下例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function myfunc_1 ( ) { return 1 ; } function myfunc_2 (a, b ) { var x = a + b; return x; } function myfunc_3 (a, b ) { if (a > b) { return ; } return a; }
对象
对象的定义以及属性的获取见下例,格式就是 JSON 那样:
1 2 3 4 5 6 7 var a = { name : "abc" , length : 12 , }; a.length ; a["length" ];
对象除了属性,还可以定义方法,也就是对象可调用的函数,例如
1 2 3 4 5 6 7 8 9 var a={ name : "abc" f : function ( ){ return this .name ; } } a.f () a.f
流程控制
条件语句,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 if (a > 0 ) { } if (a != 0 ) { } else if (a > 0 ) { } else { } switch (n) { case 1 : break ; case 2 : break ; default : }
循环语句,基本上也和 c 风格一样,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 for (var i = 0 ; i < s.length ; i++) { a += i; } for (x in person) { a = a + person[x]; } while (i < 5 ) { } do { } while (a > 0 );
也支持 break 和 continue 跳出循环。
严格模式
JS
的语法较为宽松,但是可以在脚本或函数的开头使用下面一行代码开启严格模式,
严格模式会用更严格的标准来检查语法:
不允许使用未声明的变量;
不允许使用delete a;
删除变量或对象或函数;
不允许函数重名等。
...
3. JS 脚本如何执行
JS 脚本在网页中何时会被执行?主要有两类:
网页加载时,或者网页加载完成时;
特定的事件触发,例如点击按钮,在文本框输入内容,关闭页面等,主要是通过调用函数来执行。
加载时执行
例一,加载页面时 demo 元素会被 JS 修改内容,变成"段落已修改。"
1 2 3 4 5 <p id ="demo" > 我的第一个段落</p > <script > document .getElementById ("demo" ).innerHTML = "段落已修改。" ; </script >
效果为:
我的第一个段落
例二,加载页面时直接在页面中添加内容,注意不要在文档加载完成之后使用document.write()
,这会覆盖该文档。
1 2 3 <script > document .write (Date ()); </script >
效果为:
例三,加载页面时会自动触发弹窗,还会向浏览器控制台写入信息(未使用)
1 2 3 4 <script > window .alert ("hello,world" ); console .log ("hello" ); </script >
由事件触发
例一,点击按钮会把<p>
元素的内容设置为当前时间,因为把按钮的
onclick 绑定到了 JS 的 myFunction 函数,会触发执行 myFunction 函数。
1 2 3 4 5 6 7 8 9 10 <p > 当前时间:<span id ="nowdate" > </span > <button onclick ="myFunction()" > 刷新时间</button > </p > <script > function myFunction ( ) { document .getElementById ("nowdate" ).innerHTML = Date (); } myFunction (); </script >
效果为:
当前时间:
刷新时间
除了在 HTML 元素中绑定,也可以在 JS
脚本中对元素的特定事件绑定相应函数。例如下面通过 JS
脚本对文本绑定了很多函数,对应行为会分别触发相应函数。
源代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <p id ="d0" > 与这段文字交互</p > <script > function whenclick ( ) { document .getElementById ("d0" ).innerHTML = "你点击了这段文字" ; } function whenclickright ( ) { document .getElementById ("d0" ).innerHTML = "你右键点击了这段文字" ; } function whenmouseover ( ) { document .getElementById ("d0" ).style .color = "green" ; } function whenmouseout ( ) { document .getElementById ("d0" ).style .color = "blue" ; document .getElementById ("d0" ).innerHTML = "与这段文字交互" ; } document .getElementById ("d0" ).onclick = whenclick; document .getElementById ("d0" ).oncontextmenu = whenclickright; document .getElementById ("d0" ).onmouseover = whenmouseover; document .getElementById ("d0" ).onmouseout = whenmouseout; </script >
效果为:
与这段文字交互
常见的事件为:
当前 HTML 元素被改变 onchange
;
当前 HTML 元素被单击(似乎左右键都行) onclick
;
当前 HTML 元素被右键点击 oncontextmenu
;
鼠标移动到 HTML 元素上 onmouseover
;
鼠标从 HTML 元素上移开 onmouseout
;
4. JS 如何修改页面
接下来考虑:JS 脚本如何修改网页的内容,包括 HTML
元素的内容,属性和样式等。
接入 HTML 输入流
使用 document.write
在页面当前位置中添加内容,注意不要在文档加载完成之后使用
document.write()
,这会覆盖该文档。
源代码如下(未使用)
1 2 3 <script > document .write (Date ()); </script >
改变元素内容
使用document.getElementById
等方法可以获取元素,对元素的
innerHTML 属性赋值,就是直接修改元素的内容。
源代码如下
1 2 3 4 5 6 7 8 9 10 11 <ul > <li > <span id ="p1" > Hello World!</span > </li > <li > <span name ="p2" > Hello World!</span > </li > <li > <span class ="p3" > Hello World!</span > </li > </ul > <script > document .getElementById ("p1" ).innerHTML = "新文本1 !" ; document .getElementsByName ("p2" )[0 ].innerHTML = "新文本2 !" ; document .getElementsByClassName ("p3" )[0 ].innerHTML = "新文本3 !" ; </script >
效果如下:
Hello World!
Hello World!
Hello World!
改变元素属性/样式
使用document.getElementById
等方法可以获取元素,对元素的
style 属性的子属性赋值,就是直接修改元素的样式。
源代码如下:
1 2 3 4 5 6 7 8 9 10 <ul > <li > <span id ="q1" > Hello World! 改蓝色</span > </li > <li > <span id ="q2" > Hello World! 改字体</span > </li > <li > <span id ="q3" > Hello World! 改字号</span > </li > </ul > <script > document .getElementById ("q1" ).style .color = "blue" ; document .getElementById ("q2" ).style .fontFamily = "Arial" ; document .getElementById ("q3" ).style .fontSize = "larger" ; </script >
效果如下:
Hello World! 改蓝色
Hello World! 改字体
Hello World! 改字号
直接弹窗
浏览器支持三种弹窗:警告框、确认框、提示框。
警告框向用户弹出警告,用户只能关闭,警告框
确认框需要用户选择确认或取消,返回一个布尔值,确认框
提示框需要用户输入一个值(可以给默认值),然后点击确认或直接取消,如果取消返回值为
null,提示框
可以分别点击按钮试一下,源代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <script > function f1 ( ) { alert ("你好,我是一个警告框!" ); } function f2 ( ) { var x; var r = confirm ("按下按钮!" ); if (r == true ) { x = '你按下了"确定"按钮!' ; } else { x = '你按下了"取消"按钮!' ; } document .getElementById ("append1" ).innerHTML = x; } function f3 ( ) { var x; var person = prompt ("请输入你的名字" , "Harry Potter" ); if (person != null && person != "" ) { x = "你好 " + person + "! 今天感觉如何?" ; document .getElementById ("append2" ).innerHTML = x; } } </script >
计时事件
可以实现每秒获取时间,写入元素中:
也就是每秒钟运行一次代码,点击时间则可以停止这个计时事件。
源代码如下,似乎函数使用可以放在定义之前?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script > var myVar = setInterval (function ( ) { myTimer (); }, 1000 ); function myTimer ( ) { var d = new Date (); var t = d.toLocaleTimeString (); document .getElementById ("time1" ).innerHTML = t; } function myStopFunction ( ) { clearInterval (myVar); } </script >
5. JS 表单
静态网页暂时用不到,以后有空再补吧。
6. Node.js 运行本地服务器
参考代码及注释如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var http = require ("http" );var server = http.createServer (function (req, res ) { res.setHeader ("Content-Type" , "text/html; charset=utf-8" ); res.writeHead (200 , "ok" ); res.write ("Hello Node!!" ); res.end (); }); server.listen (8080 ); console .log ("服务器已打开,可以运行 http://localhost:8080" );
web 笔记完。