window对象
window对象是浏览器的一个实例,有双重角色:既是Javascript访问浏览器窗口的接口,又是ECMAScript的Global对象。
1.window对象的全局作用域
在外部定义的对象,函数,属性都会成为window对象的属性
var age = 20;
console.log(window.age);
function sayAge() {
console.log('打印年龄:'+window.age);
}
window.sayAge();
1.1 与直接添加在window的属性函数等等的区别是,它们不能通过delete删除
console.log(delete(age));//非严格模式下返回false
window.height = 180;
console.log(delete(window.height));//返回true
console.log(window.age);//一样存在
console.log(window.height);//已被删除
> 注意:ie8及以前使用delete删除window的属性的时候,都会抛出错误以示警告
2.窗口关系及框架
这部分日后再补充,可参考Javascript高级程序设计第三版P194
3.窗口位置
var leftPos = (typeof window.screenLeft == "number")?window.screenLeft:window.screenX;
var topPos = (typeof window.screenTop == "number")?window.screenTop:window.screenY;
alert('距离左边:'+leftPos + '距离上边:'+topPos);
有一些小问题,暂且忽略
>注意:window.moveTo和window.moveBy方法一般都会被浏览器屏蔽掉.
4.窗口大小
//获取窗口大小存在各种问题:如chrome获取到的是视口大小,如IE8及更早获取不到等等
console.log('窗口大小:'+ window.outerWidth + '和' + window.outerHeight);
//获取视口大小:
var pageWidth = window.innerWidth,pageHeight = window.innerHeight;
if (typeof pageWidth != "number"){
if (document.compatMode == "CSS1Compat"){
pageWidth = document.documentElement.clientWidth;
pageHeight = document.documentElement.clientHeight;
} else {
pageWidth = document.body.clientWidth;
pageHeight = document.body.clientHeight;
}
}
5.导航和打开窗口
//打开窗口:没有则新建.参数说明:1:要打开的url,
// 2.窗口目标,特殊的窗口名称:_blank,_self,_parent,_top
// 3.一个特性字符串,
// 4.一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值
var otherWindow = window.open('http://piaoshu.org','otherWindow','height=400,width=400,left=100,top=100');
console.log(otherWindow.opener);
console.log(otherWindow.opener === window);//打印true
otherWindow.resizeTo(600,600);
console.log(otherWindow.closed);//打印false
otherWindow.close();
console.log(otherWindow.closed);//打印true
//通常只指定第一个参数,等同于<a href="http://baidu.com" target='_blank'></a>
window.open('http://baidu.com');
//大多数浏览器都内置有弹出窗口屏蔽程序,或者装有相关工具
//所以可以判断窗口是否被屏蔽
var blocked = false;
try {
var wroxWin = window.open("http://www.wrox.com", "_blank");
if (wroxWin == null){
blocked = true;
}
} catch (ex){
blocked = true;
}
if (blocked){
alert('打开新窗口被屏蔽了,请开启');
}
6.超时调用和间歇调用
//超时调用注意:设定时间值到了不一定会立刻执行,因为js是单线程的解析器,所以一定时间内只能执行一段代码
//如果时间到了,js任务队列是空的,就会立刻执行,否则就等待执行.
var timeId = setTimeout(function () {
console.log('超时调用');
},1000);
clearTimeout(timeId);//在执行之前调用就可以取消了
//间歇调用注意:需要在特定条件下取消间歇调用,否则会一直在重复调用,直至页面卸载
var count = 60, interval = null;
var logFun = function () {
console.log('每一秒调用一次我');
console.log(count);
count -= 1;
if(count <= 50){
clearInterval(interval);
}
};
interval = setInterval(logFun,1000);
//所以为了避免管理间歇调用的取消,,而且,后一个间歇调用可能会在前一个间歇调用结束之前启动(根据设定的间隔时间和代码执行时间来定),经常会使用超时调用来替代间歇调用:
var num = 0,max = 10;
var numFun = function () {
console.log(num);
num ++;
//只要符合条件就继续超时调用,相当于间歇调用了
if(num <= max){
setTimeout(numFun,1000);
}
};
setTimeout(numFun,1000);
7.系统对话框
//系统对话框:代码会先停止执行,等对话框消失之后继续执行
//1.alert:消息提醒
alert('这是alert消息');
//2.confirm:确认框,返回值true点击了确定,反之不是
if(confirm('是否确定删除该邮件')){
alert('点击确定');
}else{
alert('没有点击确定');
}
//3.prompt提示用户输入文本
var result = prompt('请输入你的姓名','姓名');
if(result != null){
console.log('这里');
}
Location对象
location特性:既是window对象的属性,也是document对象的属性,window.location和document.location引用的是同一个对象。作用:①保存当前文档的信息;②提供导航功能;③将URL解析为独立的片段。
1.location的属性
//location对象的属性:
//锚
console.log(location.hash);
//服务器名称和端口号
console.log(location.host);
//服务器名称
console.log(location.hostname);
//端口号
console.log(location.port);
//完整的URL
console.log(location.href);
//目录和文件名
console.log(location.pathname);
//页面使用的协议
console.log(location.protocol);
//查询字符串
console.log(location.search);
2.查询字符串参数
//查询字符串参数的函数:
function getQueryStringArgs() {
var qs = location.search.length > 0 ? location.search.substring(1):"";
var args = {},items = qs.length?qs.split("&"):[],item=null,name=null,value=null,
i=0,len=items.length;
for(;i<len;i++){
item = items[i].split("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
if(name.length){
args[name] = value;
}
}
return args;
}
console.log(getQueryStringArgs());
3.location的导航
//location的导航
//改变location的大部分属性都会引起页面的重新加载,包括href,host,hostname,port,search,不包括hash,修改hash不会重新加载页面,但都会产生一条history记录
document.getElementsByClassName('skip-btn')[0].onclick = function () {
//这3句代码的效果是一致的:都会产生一条历史记录,到新页面之后用户可以后退
location.href = 'https://baidu.com';
location.assign('https://baidu.com');
window.location = 'https://baidu.com';
//如果想替换当前URL:
location.replace('https://baidu.com');
//重新刷新当前页面:
//可能会从浏览器缓存中加载页面:
location.reload();
//强制从服务器重新加载页面:
location.reload(true);
}
screen对象
//screen对象:返回一些显示器的信息:
console.log(screen.width);
//减掉系统部件的宽度
console.log(screen.availWidth);
console.log(screen.height);
//减掉系统部件的高度
console.log(screen.availHeight);
history对象
history对象保存着用户的上网记录,使用go()方法可以在上网记录中前进后退:
1.基本操作
history.go(0);//刷新
history.go(1);//前进
history.forward();//同上
history.go(-1);//后退
history.back();//同上
history.go('http://baidu.com');//跳转到最近的http://baidu.com页面,不定是前进还是后退,取最近
2. history.pushState
//检测是否支持history
if(!!(window.history && history.pushState)){
console.log('支持history api');
}else{
console.log('不支持history api');
}
//pushState方法3个参数:①state:状态对象,会传入popstate的回调函数中;②title:标题,目前浏览器都忽略,可忽略,③url:地址栏将显示的地址,不能跨域
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
//总之,pushState方法不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应
3.history.replaceState
//replaceState的参数和pushState一样,区别是它修改浏览历史中当前纪录,而不是添加
history.replaceState({page:1},"page1","page1.html");
4.history.state属性
console.log(history.state);//如果没有,将返回null
5.popstate事件
//每当同一个文档的浏览历史(即history对象)出现变化(只有当前进、后退的时候才会,比如用户点击前进后退按钮,比如js调用go(-1)/back()/forward时,就会触发popstate事件。
window.onpopstate = function (event) {
console.log('location: ' + document.location);
var state = JSON.parse(JSON.stringify(event.state));
};
history.pushState({page:3},"page3","#");
history.back();
6.URLSearchParams API
因为兼容性问题,暂时先不讨论这个,在location当中已经实现过怎样获取查询字符串参数了。
客户端检测
策略:如果能找到更通用的方法,就应该优先采用更通用的方法,就是说先设计最通用的方案,然后再使用特定于浏览器的技术增强该方案。
1.能力检测
//能力检测(特性检测):为了识别浏览器的能力
function getElement(id){
if(document.getElementById){
return document.getElementById(id);
}else if(document.all){
return document.all[id];
}else{
throw new Error("No way to retrieve element!");
}
}
//检测是否有某个特性更可靠的做法:
function isHostMethod(object, property) {
var t = typeof object[property];
return t=='function' ||
(!!(t=='object' && object[property])) ||
t=='unknown';
}
var xhr = new ActiveXObject("Microsoft.XMLHttp"),result = null;
result = isHostMethod(xhr, "open");//true
result = isHostMethod(xhr, "foo");//false
2.怪癖检测
//怪癖检测:识别浏览器的特殊行为,即确定bug
//如:IE8 及更早版本中存在一个 bug,即如果某个实例属性与[[Enumerable]]标记为 false 的某个原型属性同名,那么该实例属性将不会出现在 fon-in 循环当中
var hasDontEnumQuirk = function(){
var o = { toString : function(){} };
for (var prop in o){
if (prop == "toString"){
return false;
} }
return true;
}();
3.用户代理检测
//用户代理检测:包括检测呈现引擎、平台、Windows 操作系统、移动设备和游戏系统
var client = function () {
//呈现引擎
var engine = {
ie: 0,
gecko: 0,
webkit: 0,
khtml: 0,
opera: 0,
//完整的版本号
ver: null
};
//浏览器
var browser = {
ie: 0,
firefox: 0,
safari: 0,
konq: 0,
opera: 0,
chrome: 0,
//具体的版本号
ver: null
};
//平台、设备和操作系统
var system = {
win: false,
mac: false,
x11: false,
//移动设备
iphone: false,
ipod: false,
ipad: false,
ios: false,
android: false,
nokiaN: false,
winMobile: false,
//游戏系统
wii: false, ps: false
};
//检测呈现引擎和浏览器
var ua = navigator.userAgent;
if (window.opera) {
engine.ver = browser.ver = window.opera.version();
engine.opera = browser.opera = parseFloat(engine.ver);
} else if (/AppleWebKit\/(\S+)/.test(ua)) {
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
//确定是 Chrome 还是 Safari
if (/Chrome\/(\S+)/.test(ua)) {
browser.ver = RegExp["$1"];
browser.chrome = parseFloat(browser.ver);
} else if (/Version\/(\S+)/.test(ua)) {
browser.ver = RegExp["$1"];
browser.safari = parseFloat(browser.ver);
} else {
//近似地确定版本号
var safariVersion = 1;
if (engine.webkit < 100) {
safariVersion = 1;
} else if (engine.webkit < 312) {
safariVersion = 1.2;
} else if (engine.webkit < 412) {
safariVersion = 1.3;
} else {
safariVersion = 2;
}
browser.safari = browser.ver = safariVersion;
}
} else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)) {
engine.ver = browser.ver = RegExp["$1"];
engine.khtml = browser.konq = parseFloat(engine.ver);
} else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) {
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver);
//确定是不是 Firefox
if (/Firefox\/(\S+)/.test(ua)) {
browser.ver = RegExp["$1"];
browser.firefox = parseFloat(browser.ver);
}
} else if (/MSIE ([^;]+)/.test(ua)) {
engine.ver = browser.ver = RegExp["$1"];
engine.ie = browser.ie = parseFloat(engine.ver);
}
//检测浏览器
browser.ie = engine.ie;
browser.opera = engine.opera;
//检测平台
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
//检测 Windows 操作系统 if (system.win){
if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)) {
if (RegExp["$1"] == "NT") {
switch (RegExp["$2"]) {
case "5.0":
system.win = "2000";
break;
case "5.1":
system.win = "XP";
break;
case "6.0":
system.win = "Vista";
break;
case "6.1":
system.win = "7";
break;
default:
system.win = "NT";
break;
}
} else if (RegExp["$1"] == "9x") {
system.win = "ME";
} else {
system.win = RegExp["$1"];
}
}
//移动设备
system.iphone = ua.indexOf("iPhone") > -1;
system.ipod = ua.indexOf("iPod") > -1;
system.ipad = ua.indexOf("iPad") > -1;
system.nokiaN = ua.indexOf("NokiaN") > -1;
//windows mobile
if (system.win == "CE") {
system.winMobile = system.win;
} else if (system.win == "Ph") {
if (/Windows Phone OS (\d+.\d+)/.test(ua)) {
;
system.win = "Phone";
system.winMobile = parseFloat(RegExp["$1"]);
}
}
//检测 Android 版本
if (/Android (\d+\.\d+)/.test(ua)) {
system.android = parseFloat(RegExp.$1);
}
//游戏系统
system.wii = ua.indexOf("Wii") > -1;
system.ps = /playstation/i.test(ua);
//返回这些对象
return {
engine: engine,
browser: browser,
system: system
};
}();
网友评论