JavaScript Learning
[TOC]
了解
基本知识
脚本语言 scripting language
面向对象 object-oriented
放在 <script>
标签内,或者通过外部引用,多用于浏览器交互
能做什么?
翻转器(rollover):鼠标指针、突出显示按钮
处理表单
设置cookie
客户端 ……
不能做什么?
服务器
干涉其他脚本打开的窗口
……
JQuery
JS库,代码复用
Ajax
Asynchronous JavaScript and XML(异步 Javascript 和 XML),实质上是 Javascript 的一小部分,但是使用频繁以至于有了独立的词汇描述。
一种创建交互式 Web 应用程序的方式,由以下技术组成:
HTML
CSS(Cascading Style Sheet)
使用 Javascript 访问的 DOM(Document Object Model)
XML or JSON
XMLHttpRequest
事件处理
event handler
用户操作触发事件,事件有其处理程序。
代码分离
将网站分为:
HTML:页面内容和结构
CSS:页面外观和表现
Javascript:页面交互行为
HTML内容的语义性(semantic)划分:
<div>
:block-level元素,与前后元素之间有物理换行
<span>
:inline元素
HTML内容的标识(标识一些需要修改的内容,以便 JS 和 CSS 访问):
id
:唯一元素,CSS 中使用#
访问
class
:多次使用的元素,CSS 中使用 .
访问
Startup
脚本位置
<head></head>
<body></body>
外部引用 :<script src=""></script>
Example
1 2 3 4 5 6 7 8 9 10 11 window .onload = WriteMessage;alert("Welcome to my JacaScript page!" ) function WriteMessage ( ) { document .getElementById('test' ).innerHTML = "Hello World!" ; }
不支持JS?
1 <noscript > This page requests JavaScript.</noscript >
条件选择框?
1 2 3 4 5 6 7 8 if (confirm("Are you sure you want to do that?" )) { alert("You choose YES." ); } else { alert("You choose NO." ); } confirm("Are you sure you want to do that?" ) ? alert("You choose YES." ) : alert("You choose NO." );
获取用户回答?
1 2 prompt("Questions" , "default answer" )
1 2 3 4 5 6 7 var ans = prompt("Are you sure you want to do that?" , "Your answer." );if (ans){ alert("Your answer is " + ans); } else { alert("You refuse to answer." ); }
链接重定向
在HTML上可以直接使用:
1 <a href ="target-page.html" > <a >
但是JS脚本能够覆盖掉HTML标签的重定向,甚至不会让用户知道 。
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Redirection Test</title > <script src ="redirection.js" > </script > </head > <body > <h1 > Source Page</h1 > <h2 > <a href ="target-page-1.html" id ="redirect" > Welcome to my site!</a > </h2 > </body > </html > <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Target Page</title > </head > <body > <h1 > Target Page 1</h1 > </body > </html > <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Target page 2</title > </head > <body > <h1 > Target Page 2</h1 > </body > </html >
没有JS的情况下,点集链接会重定向到 target-page-1.html
使用JS重定向到 target-page-2.html
:
1 2 3 4 5 6 7 8 9 10 11 12 13 window .onload = initAll;function initAll ( ) { document .getElementById("redirect" ).onclick = initRedirect; } function initRedirect ( ) { window .location = "target-page-1.html" ; return false ; }
优化体验
加入重定向提醒:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 window .onload = initAll;function initAll ( ) { document .getElementById("redirect" ).onclick = initRedirect; } function initRedirect ( ) { alert("We are not responsible for the content of pages outside out site." ); window .location = this ; return false ; }
this
:关键字,根据上下文 传递value。这里 this 在一个由标签的事件触发的函数中使用,因此 this 是一个链接对象。
无干扰编程 unobstusive scripting,一种使用JS编写网页的方式,旨在分离JS代码和HTML代码
渐进增强,不支持JS的访问者也能够访问全部功能,只是体验较差。
多级条件
多个判断分支:
错误处理
1 2 3 4 5 try { throw } catch (){}
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 var ans = prompt("Enter a number:" , "" );try { if (!ans || ans < 0 || isNaN (ans)){ throw new Error ("Not a valid number!" ); } alert("The square root of " + ans + "is " + Math .sqrt(ans)); } catch (errMsg){ alert(errMsg.message); }
Web 应用程序
Bingo Card
美国的Bingo 卡片是5×5 的方形,5 个列上标着B-I-N-G-O,格子中包含1~75 的数字。正中间通常是一个空的格子,常常印着单词free。 每列可以包含的数字的范围如下:
B 列包含数字1~15;
I 列包含数字16~30;
N 列包含数字31~45;
G 列包含数字46~60;
O 列包含数字61~75。
HTML & CSS
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 window .onload = initALL;var usedNums = new Array (76 );function initALL ( ) { if (document .getElementById){ document .getElementById("reload" ).onclick = anotherCard; newCard(); } else { alert("Your browser doesn't support this script." ) } } function newCard ( ) { for (let i = 0 ; i < 24 ; i++) { setSquare(i); } } function setSquare (squareNum ) { var currSquare = "square" + squareNum; var colPlace = new Array (0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,4 ,4 ,4 ,4 ,4 ); var colBasis = colPlace[squareNum] * 15 ; do { var newNum = colBasis + getNewNum(); } while (usedNums[newNum]); usedNums[newNum] = true ; document .getElementById(currSquare).innerHTML = newNum; document .getElementById(currSquare).className = "" ; document .getElementById(currSquare).onmousedown = toggleColor; } function getNewNum ( ) { return Math .floor(Math .random() * 15 ) + 1 ; } function anotherCard ( ) { for (let i = 1 ; i < usedNums.length; i++) { usedNums[i] = false ; } newCard(); return false ; } function toggleColor (evt ) { if (evt) { var squareNum = evt.target; } else { var square = window .event.srcElement; } if (squareNum.className == "" ) { squareNum.className = "pickedBG" ; } else { squareNum.className = "" ; } checkWin(); } function checkWin ( ) { var winningOption = -1 ; var setSquare = 0 ; var winners = new Array (31 ,992 ,15360 ,507904 ,541729 ,557328 ,1083458 ,2162820 ,4329736 ,8519745 ,8659472 ,16252928 ); for (let i = 0 ; i < 24 ; i++) { var currSquare = "square" + i; if (document .getElementById(currSquare).className != "" ) { document .getElementById(currSquare).className = "pickedBG" ; setSquare = setSquare | Math .pow(2 , i); } } for (let i = 0 ; i < winners.length; i++) { if ((winners[i] & setSquare) == winners[i]) { winningOption = i; } } if (winningOption > -1 ) { for (let i = 0 ; i < 24 ; i++) { if (winners[winningOption] & Math .pow(2 , i)) { currSquare = "square" + i; document .getElementById(currSquare).className = "winningBG" ; } } } }
探测对象
object detection:探测浏览器是否有能力理解使用的对象
1 2 3 4 5 if (document .getElementByID){} else { alert("Your browser doesn't support this script." ) }
对象探测在生产环境中很重要,但是不必总是检查,对于没有100%支持的对象总是需要先检查。
Math
Math.random()
:生成0-1的随机浮点数
Math.floor
:向下取整
Array
生成包含指定元素的数组:
1 var newArray = new Array (1 ,2 ,3 )
生成有指定个数元素的数组:
1 var newArray = new Array (20 )
多种方式调用脚本
点击 Click here 时,不是重新加载页面,而是重新执行脚本:
1 2 3 4 5 6 7 8 9 10 document .getElementById("reload" ).onclick = anotherCard;function anotherCard ( ) { for (let i = 1 ; i < usedNums.length; i++) { usedNums[i] = false ; } newCard(); return false ; }
JS 操纵 CSS
通过更改对象的 class
属性,从而匹配CSS中的不同样式。
也可以更改 style
属性,就不必使用CSS文件,但是使用CSS文件能够将页面的表现和交互行为分离。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function toggleColor (evt ) { if (evt) { var squareNum = evt.target; } else { var square = window .event.srcElement; } if (squareNum.className == "" ) { squareNum.className = "pickedBG" ; } else { squareNum.className = "" ; } }
状态压缩技术
使用二进制位表示某位元素是否在集合内。
1 00 00 00 00 00 00 00 00 00 00 00 00
存在24个格子,编号为 0~23。将上述二进制数从低到高位编号为 0~23,第 i 位若为0则表示第 i 个格子不在集合内,若为1则表示第 i 个格子在集合内。
单元素集合
\[
\begin{equation}
\{i\}:\underbrace{00...0\overbrace{1}^{\text{第 i 个}}0...00}_{\text{N个}}=2^i
\end{equation}
\]
集合合并
按位取或 \[
\{i,j\}=a|b\;\;\;\;(a=\{i\},b=\{j\})
\]
判断元素是否在集合内
按位取与 \[
m\in A:m\&A
\]
判断集合是否相等
按位取与,与目标集合比较 \[
A==B:(A\&B)==B
\]
图像处理
翻转器
效果:鼠标移动到图像上时,改变网页上的图像。
实现:翻转器 rollover
思路:original img + replacement img
标签中实现
通过加入 onmouseover
和 onmouseout
事件,使用 document.images["attr"].src="link.png"
更换图片来达到动画效果。
缺点:图片下载缓慢产生的效果延迟。
onmouseover:鼠标指针放在目标上方
onmouseout:鼠标指针离开目标
document.images[“id”].src=“link”:将目标id的 img
标签图像链接替换为对应的图像链接。
1 2 3 <a href ="next.html" onmouseover ="document.images['2b'].src='replacement.jpg'" onmouseout ="document.images['2b'].src='original.jpg'" > <img src ="original.jpg" id ="2b" alt ="2b" > </a >
alt
为非图形化浏览器提供图片的描述。
JS实现
为确保替换图像立刻出现,使用JS预先加载图片到浏览器缓存,并保存在脚本变量中。
HTML & CSS
tagName
总是返回大写的值
这里的翻转器定义在 img
上,不支持老式浏览器(IE3)
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 26 27 window .onload = rolloverInit;function rolloverInit ( ) { for (let i = 0 ; i < document .images.length; i++) { if (document .images[i].parentNode.tagName == "A" ) { setupRollover(document .images[i]); } } } function setupRollover (theImage ) { theImage.outImage = new Image(); theImage.outImage.src = theImage.src; theImage.onmouseout = function ( ) { this .src = this .outImage.src; } theImage.overImage = new Image(); theImage.overImage.src = "replacement_" + theImage.id + ".png" ; theImage.onmouseover = function ( ) { this .src = this .overImage.src; } }
三状态翻转器(点击)
1 2 3 4 5 theImage.clickImage = new Image(); theImage.clickImage.src = "click_" + theImage.id + ".png" ; theImage.onclick = function ( ) { this .src = this .clickImage.src; }
通过链接触发翻转器
JS通过 id
class
操纵文档,因此通过这两个属性定位链接和对应的图像。
对链接的 onmouseover
onmouseout
onclick
事件定义处理函数,这就需要用到对应的图像对象,因此使用一个新的属性 imgToChange
来储存图像对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function setupRollover (theLink, theImage ) { theLink.imgToChange = theImage; theLink.onmouseover = function ( ) { this .imgToChange.src = this .overImage.src; } theLink.onmouseout = function ( ) { this .imgToChange.src = this .outImage.src; } theLink.outImage = new Image(); theLink.outImage.src = theImage.src; theLink.overImage = new Image(); theLink.overImage.src = "replacement_" + theImage.id + ".png" ; }
程序附录
Web App
返回
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Make Your Own Bingo Card</title > <link rel ="stylesheet" href ="bingo-card.css" > <script src ="bingo-card.js" > </script > </head > <body > <h1 > Create A Bingo Card</h1 > <table > <tr > <th > B</th > <th > I</th > <th > N</th > <th > G</th > <th > O</th > </tr > <tr > <td id ="square0" > </td > <td id ="square5" > </td > <td id ="square10" > </td > <td id ="square14" > </td > <td id ="square19" > </td > </tr > <tr > <td id ="square1" > </td > <td id ="square6" > </td > <td id ="square11" > </td > <td id ="square15" > </td > <td id ="square20" > </td > </tr > <tr > <td id ="square2" > </td > <td id ="square7" > </td > <td id ="free" > Free</td > <td id ="square16" > </td > <td id ="square21" > </td > </tr > <tr > <td id ="square3" > </td > <td id ="square8" > </td > <td id ="square12" > </td > <td id ="square17" > </td > <td id ="square22" > </td > </tr > <tr > <td id ="square4" > </td > <td id ="square9" > </td > <td id ="square13" > </td > <td id ="square18" > </td > <td id ="square23" > </td > </tr > </table > <p > <a href ="bingo-card.html" id ="reload" > Click here </a > to create a new card.</p > </body > </html >
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 26 27 28 29 30 31 32 33 body { background-color : white; color : black; font-size : 20px ; font-family : "Lucida Grande" , Verdana, Arial, Helvetica, sans-serif, Tahoma, sans-serif; } h1 , th { font-family : Georgia, 'Times New Roman' , Times, serif; } h1 { font-size : 28px ; } table { border-collapse : collapse; } th , td { padding : 10px ; border : 2px #666 solid; text-align : center; width : 20% ; } #free , .pickedBG { background-color : #f66 ; } .winningBG { background-image : url ("winningBG.png" ); }
Rollover
返回
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Rollover Test</title > <script src ="rollover.js" > </script > <link rel ="stylesheet" href ="rollever.css" > </head > <body > <a href ="next.html" > <img src ="original_arrow.png" id ="arrow" alt ="arrow" > </a > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 body { background-color : #ffffff ; } img { border-width : 0 ; } img #arrow , img #arrowImg { width : 147px ; height : 82px ; } #button1 , #button2 { width : 113px ; height : 33px ; } .centered { text-align : center; }