창 객체
ECMAScript는 JavaScript의 핵심이지만 웹에서 JavaScript를 사용하려면 BOM(Browser Object Model)이 진짜 핵심입니다. BOM은 웹 페이지 콘텐츠와 독립적인 브라우저 기능에 액세스하기 위한 여러 개체를 제공합니다.
Window 객체: BOM의 핵심 객체는 브라우저의 인스턴스를 나타내는 window입니다. 브라우저에서 window 객체는 자바스크립트를 통해 브라우저 창에 접근하기 위한 인터페이스일 뿐만 아니라 ECMAScript에서 지정한 Global 객체이기도 합니다.
따라서 전역 범위에 선언된 모든 변수와 함수는 창 개체의 속성과 메서드가 됩니다.
<script type="text/javascript"> var age=26;//这里定义的全局变量和全局函数被自动归在了window对象名下 function sayAge(){ console.log(this.age); } console.log(window.age);//26 sayAge();//26 相当于window.sayAge() window.sayAge();//26 //全局变量和在window对象上直接定义属性的唯一区别:全局变量不能够通过delete操作符删除,而直接在window对象上定义的属性可以 window.color='red'; delete window.age; delete window.color; console.log(window.age);//26 console.log(window.color);//undefined </script>
<script type="text/javascript"> /* 还要注意:尝试访问未声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能未经声明的变量是否存在 */ //这会抛出错误,因为oldValue未定义 var newValue=oldValue; //这不会抛出错误,因为是一次属性查询 var newValue=window.oldValue; </script>
창 관계 및 프레임
페이지에 프레임이 포함된 경우 각 프레임은 각각 자체 창 개체가 있으며 프레임 컬렉션에 저장됩니다. 프레임 컬렉션에서 해당 창 개체는 숫자 인덱스(0부터 시작, 왼쪽에서 오른쪽, 위에서 아래로) 또는 프레임 이름으로 액세스할 수 있습니다. 각 창 개체에는 프레임 이름이 포함된 이름 속성이 있습니다.
window.frames[0] 또는 window.frames["topFrame"]을 통해 상위 프레임을 참조할 수 있습니다. 그러나 이러한 프레임을 참조하려면 window 대신 top을 사용하는 것이 좋습니다. 맨 위 개체는 항상 브라우저 창인 가장 높은(가장 바깥쪽) 프레임을 가리키기 때문입니다. 한 프레임에서 다른 프레임으로의 올바른 액세스를 보장하려면 이를 사용하십시오. 프레임워크에 작성된 모든 코드의 경우 창 개체는 최고 수준 프레임워크가 아닌 해당 프레임워크의 특정 인스턴스를 가리키기 때문입니다.
상단 반대편의 또 다른 창 객체는 부모입니다. 상위 개체는 항상 현재 프레임 바로 위의 프레임을 가리킵니다.
프레임과 관련된 마지막 개체는 항상 창을 가리키는 self입니다. self와 window 객체는 서로 바꿔서 사용할 수 있습니다.
프레임을 사용하는 경우 브라우저에 여러 전역 개체가 있습니다. 각 프레임에 정의된 전역 변수는 자동으로 프레임에 있는 창 개체의 속성이 됩니다. 각 창 개체에는 기본 유형 생성자가 포함되어 있으므로 각 프레임워크에는 서로 대응하지만 동일하지 않은 자체 생성자 집합이 있습니다.
위치 객체
위치 객체는 창 객체와 문서 객체 모두의 속성이기 때문에 매우 특별한 객체입니다. window.location과 document.location은 동일한 객체를 참조합니다.
위치 개체의 속성:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>查询字符串参数</title> </head> <body> <script type="text/javascript"> function getQueryStringArgs(){ //取得查询字符串并去掉开头的问号 var qs = (location.search.length > 0 ? location.search.substring(1) : ""), //保存数据对象 args = {}, //取得每一项 items = qs.length ? qs.split("&") : [], item = null, name = null, value = null, //在for循环中使用 i = 0, len = items.length; //逐个将每一项添加到args对象中 for (i=0; i < len; i++){ item = items[i].split("="); //decodeURIComponent用来解码name和value,因为查询字符串应该是被编码过的 name = decodeURIComponent(item[0]); value = decodeURIComponent(item[1]); if (name.length){ args[name] = value; } } return args; } //假设查询字符串是: ?q=javascript&num=10 var args = getQueryStringArgs(); alert(args["q"]); //"javascript" alert(args["num"]); //"10" //这样一来,每个查询字符串参数都成了返回对象的属性,极大地方便了对每个参数的访问 </script> </body> </html>
위치 개체를 사용하면 다양한 방법으로 브라우저의 위치를 변경할 수 있습니다.
가장 일반적인 방법은 다음과 같습니다: 할당() 메소드를 사용하여 URL을 전달합니다
location.ass("http://www.php.cn")
이렇게 하면 새 URL이 즉시 열리고 브라우저 기록에 기록이 생성됩니다.
마찬가지로 location.href 및 window.location을 URL 값으로 설정하면 이 값을 사용하여 할당() 메서드도 호출됩니다.
location.href=”http://www.php.cn”;
window.location=”http://www.php.cn”;
이 두 가지는 이 메소드의 효과는
할당() 메소드를 호출하는 것과 완전히 동일합니다. 또한 위치 객체의 다른 속성을 수정하여 현재 로드된 페이지를 변경할 수도 있습니다.
위치 속성(해시 제외)이 수정될 때마다 페이지가 새 URL로 다시 로드됩니다. 해시 값을 수정하면 브라우저 기록에 새 레코드가 생성됩니다.
URL: http://a.com#helloword의 '#helloworld'는 location.hash입니다. 페이지를 새로 고치므로 해시 값을 데이터 전송에 사용할 수 있습니다. 물론 데이터 용량은 제한됩니다.
위 방법 중 하나로 URL을 수정하면 브라우저 기록에 새 기록이 생성되므로 '뒤로' 버튼을 클릭하면 이전 페이지로 이동합니다.
replace() 메서드를 사용하여 이 동작을 비활성화할 수 있습니다. 이 메서드는 탐색할 URL인 하나의 매개 변수만 허용합니다. 결과로 인해 브라우저 위치가 변경되더라도 기록에 새 레코드가 생성되지는 않습니다. replacement() 메서드를 호출한 후에는 이전 페이지로 돌아갈 수 없습니다.
이 페이지가 브라우저에 로드된 후 1초 후에 브라우저는 www.php.cn으로 리디렉션됩니다. 그러면 '뒤로' 버튼이 비활성화되고 전체 URL을 다시 입력하면 예시 페이지로 돌아갈 수 없습니다.
<script type="text/javascript"> setTimeout(function () { location.replace("http://www.php.cn/"); }, 1000); </script>
reload() 메서드의 기능은 현재 표시된 페이지를 다시 로드하는 것입니다. 매개변수를 전달하지 않고 reload() 메서드를 호출하면 가장 효율적인 방법으로 페이지가 다시 로드됩니다. 즉, 마지막 요청 이후 페이지가 변경되지 않은 경우 페이지는 브라우저 캐시에서 다시 로드됩니다. 서버에서 강제로 다시 로드하려면 이 메소드에 true 매개변수를 전달해야 합니다.
location.reload();//Reload(캐시에서 로드 가능)
location.reload(true);//Reload(서버에서 다시 로드)
시간 초과 호출 및 간헐적인 호출
javascript是单线程语言,但允许通过设置超时值和间歇值来设定代码在特定时刻执行
超时调用:是在指定的时间过后执行代码
间歇调用:每隔指定的时间就执行一次代码
超时调用:需要使用window对象的setTimeout()方法,接收两个参数:要执行的代码和以毫秒表示的时间。
第二个参数是一个表示等待多长时间的毫秒数,但经过该时间后指定的代码不一定执行。因为,javascript是一个单线程的解释器,因此一定时间内只能执行一段代码。第二个参数表示再过多长时间把当前任务添加到队列中。如果队列是空的,则代码会立刻执行,否则就要等待前面的代码执行完了以后再执行。
调用setTimeout()后,该方法会返回一个数值ID,表示超时调用。要取消未执行的超时调用计划,可以调用clearTimeout()方法并将相应的超时调用ID作为参数传递给它即可。
间歇调用:使用setInterval()方法
与超时调用类似,只不过它会按照指定的时间间隔重复执行代码,直到间歇调用被取消或者页面被卸载。它接收的参数与setTimeout()方法一样
Demo1
<script type="text/javascript"> //设置超时调用 var timeoutId = setTimeout(function() { alert("Hello world!"); }, 1000); //取消超时调用 clearTimeout(timeoutId); </script>
Demo2
<script type="text/javascript"> /* 使用间歇调用实现 */ var num = 0; var max = 10; var intervalId = null; function incrementNumber() { num++; if (num == max) { clearInterval(intervalId); alert("Done"); } } intervalId = setInterval(incrementNumber, 500); </script>
Demo3
<script type="text/javascript"> /* 使用超时调用来实现 */ var num = 0; var max = 100; function incrementNumber() { num++; if (num < max) { setTimeout(incrementNumber, 500); } else { alert("Done"); } } setTimeout(incrementNumber, 500); </script>
在使用超时调用时,没有必要跟踪超时调用ID,因为每次执行代码之后,如果不再设置另一次超时调用,调用就会自动停止。一般认为,使用超时调用来模拟间歇调用是一种最佳模式。间歇调用一般较少使用,因为后一个间歇调用可能会在前一个间歇调用结束之前启动。
系统对话框
alert()、confirm()和prompt()
<script type="text/javascript"> alert("Hello world!"); </script> <script type="text/javascript"> /* 判断用户点击了OK还是Cancel,可以检查confirm()方法返回的布尔值:true表示单击了OK,false表示单击了Cancel或单击了右上角的X按钮。 */ if (confirm("Are you sure?")) { alert("I'm so glad you're sure! "); } else { alert("I'm sorry to hear you're not sure. "); } </script> <script type="text/javascript"> /* prompt()方法用来生成一个"提示"框,用于提示用户输入一些文本。提示框除了显示OK和Cancel按钮之外 ,还会显示一个文本输入域,用来输入文本内容。该方法接收两个参数:要显示给用户的文本提示和文本输入域的默认值(可以是一个空字符串) */ var result = prompt("What is your name? ", ""); if (result !== null) { alert("Welcome, " + result); } </script>
history对象
history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。因为history是window对象的属性,因此每个浏览器窗口、每个标签页以及每个框架,都有自己的history对象与特定的window对象关联。处于安全方面的考虑,开发人员是无法知道用户浏览过的URL,不过,借助用户访问过的页面列表,同样可以在不知道实际URL的情况下实现后退和前进。
使用Go()方法可以在用户的历史记录中任意跳转,可以向后也可以向前。该方法接收一个参数:表示向前或者向后跳转的页面数的整数值。负数表示向后跳转(类似单击浏览器的后退按钮),正数表示向前跳转(类似浏览器的前进按钮)。
//后退一页 history.go(-1); //前进一页 history.go(1);
也可以给go()方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置–可能后退也可能前进,具体要看哪个位置最近。如果历史记录中不包含该字符串,那么这个方法什么也不做
//跳转到最近的php.cn history.go("php.cn");
另外,还可以使用back()和forward()来代替go()方法
//后退一页 history.back(); //前进一页 history.forward();
除此之外,history对象还有一个length属性,保存着历史记录的数量。这个数量包括所有的历史记录,即所有的向后和向前的记录。如果history.length==0,则表示这是用户打开窗口后的第一个页面
history对象不常用,但是在创建自定义的后退和前进按钮,以及检测当前页面是不是用户历史记录的第一个页面时,还是必须使用它。
Demo1
history.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>history</title> </head> <body> <form> <input type="text" id="username"> </form> <input type="button" id="btn" value="按钮" onclick="go()"> <script type="text/javascript"> function go(){ var name=document.getElementById("username").value; if(name=="hello"){ history.go(-1); }else{ alert('用户名不正确'); } } </script> </body> </html>
ceshi.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> </head> <body> <a href="history.html" >跳转</a> </body> </html>
这里使用history模仿了一个输入用户名之后。跳转到之前页面的例子。
Demo2
history2.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>history</title> </head> <body> <a href="demo.html">跳转</a> <input type="button" id="btn" value="前进" onclick="go()"> <script type="text/javascript"> function go(){ history.forward(); } </script> </body> </html>
demo.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> </head> <body> <input type="button" name="" value="回退" id="btn" onclick="fn()"> <script type="text/javascript"> function fn(){ history.back(); } </script> </body> </html>
这个小例子模拟了history.back()和history.forward()的基本功能