一、Js/Jquery获取网页屏幕可见区域高度
1.1、获取浏览器窗口的可视区域高度和宽度,滚动条高度有需要的朋友可参考一下。
document.body.clientWidth ==> BODY对象宽度
document.body.clientHeight ==> BODY对象高度
document.documentElement.clientWidth ==> 可见区域宽度
document.documentElement.clientHeight ==> 可见区域高度
document.body.clientWidth ==> 网页可见区域宽
document.body.clientHeight ==> 网页可见区域高
document.body.offsetWidth ==> 网页可见区域宽(包括边线的宽)
document.body.offsetHeight ==> 网页可见区域高(包括边线的高)
document.body.scrollWidth ==> 网页正文全文宽
document.body.scrollHeight ==> 网页正文全文高
document.body.scrollTop ==> 网页被卷去的高
document.body.scrollLeft ==> 网页被卷去的左
window.screenTop ==> 网页正文部分上
window.screenLeft ==> 网页正文部分左
window.screen.height ==> 屏幕分辨率的高
window.screen.width ==> 屏幕可用工作区高度
window.screen.availHeight ==> 屏幕可用工作区高度
window.screen.availWidth ==> 屏幕可用工作区宽度
window.innerHeight ==> 获取浏览器显示区域高度
window.innerWidth ==> 获取浏览器显示区域宽度
1.2、部分jquery函数获取方法
// 部分jQuery函数
$(window).height() //浏览器时下窗口可视区域高度
$(document).height() //浏览器时下窗口文档的高度
$(document.body).height() //浏览器时下窗口文档body的高度
$(document.body).outerHeight(true) //浏览器时下窗口文档body的总高度 包括border padding margin
$(window).width() //浏览器时下窗口可视区域宽度
$(document).width() //浏览器时下窗口文档对于象宽度
$(document.body).width() //浏览器时下窗口文档body的高度
$(document.body).outerWidth(true) //浏览器时下窗口文档body的总宽度 包括border padding
HTML精确定位: scrollLeft,scrollWidth,clientWidth,offsetWidth
scrollHeight: 获取对象的滚动高度。
scrollLeft: 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop: 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
scrollWidth: 获取对象的滚动宽度
offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft: 获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop: 获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
event.clientX 相对文档的水平座标
event.clientY 相对文档的垂直座标
event.offsetX 相对容器的水平坐标
event.offsetY 相对容器的垂直坐标
document.documentElement.scrollTop 垂直方向滚动的值
event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的量
alert($(document).scrollTop()); //获取滚动条到顶部的垂直高度
alert($(document).scrollLeft()); //获取滚动条到左边的垂直宽度
二、浏览器兼容的一些代码写法
一:网页可见区域宽高,不包括工具栏和滚动条(浏览器窗口可视区域大小)
1.对于IE9+、chrome、firefox、Opera、Safari:
window.innerHeight浏览器窗口的内部高度;
window.innerWidth浏览器窗口的内部宽度;
2.对于IE8.7.6.5:
document.documentElement.clientHeight:表示HTML文档所在窗口的当前高度;
document.documentElement.clientWidth:表示HTML文档所在窗口的当前宽度;
或者,因为document对象的body属性对应HTML文档的<body>标签,所以也可表示为:
document.body.clientHeight:表示HTML文档所在窗口的当前高度;
document.body.clientWidth:表示HTML文档所在窗口的当前宽度;
结论:
document.body.clientWidth/Height:的宽高偏小,高甚至默认200;
document.documentElement.clientWidth/Height 和 window.innerWidth/Height 的宽高始终相等。
所以在不同浏览器都实用的的Javascripit方案:
var w = document.documentElement.clientWidth || document.body.clientWidth;
var h = document.documentElement.clientHeight || document.body.clientHeight;
二:网页正文全文宽高
scrollWidth和scrollHeight获取网页内容高度和宽度
1.针对IE.Opera:scrollHeight是网页内容实际高度,可以小于clientHeight;
2.针对NS.firefox:scrollHeight是网页内容高度,不过最小值是clientHeight;也就是说网页内容实际高度小于clientHeight的时候,scrollHeight返回clientHeight;
3.浏览器兼容代码:
var w = document.documentElement.scrollWidth || document.body.scrollWidth;
var h = document.documentElement.scrollHeight || document.body.scrollHeight;
二:网页可见区域宽高,包括滚动条等边线(会随窗口的显示大小改变)
1.值:offsetWidth = scrollWidth + 左右滚动条 +左右边框;
offsetHeight = scrollHeight + 上下滚动条 + 上下边框;
2.浏览器兼容代码:
var w = document.documentElement.offsetWidth || document.body.offsetWidth ;
var h = document.documentElement.offsetHeight || document.body.offsetHeight ;
三:网页卷去的距离与偏移量
1.scrollLeft:设置或获取位于给定对象左边界与窗口中目前可见内容的最左端之间的距离;
2.scrollTop:设置或获取位于给定对象最顶端与窗口中目前可见内容的最左端之间的距离;
3.offsetLeft:设置或获取位于给定对象相对于版面或由offsetParent属性指定的父坐标的计算左侧位置;
4.offsetTop:设置或获取位于给定对象相对于版面或由offsetParent属性指定的父坐标的计算顶端位置;
二、浏览器 window.navigator 对象
浏览器信息:
window.navigator : 代表正在使用的浏览器的对象。
window.navigator.appCodeName: 返回浏览器的代码名。"Mozilla" 本来是 Netscape Navigator 的开发代码(语源是怪兽哥斯拉),考虑到为 Mozilla 制作的网页的兼容性,Internet Explorer 的返回值也是 "Mozilla"。
window.navigator.appName:返回代表浏览器名的字符串。
IE:Microsoft Internet Explorer
Chrome:Netscape
window.navigator.appVersion : 返回代表浏览器版本号的字符串。Internet Explorer 为“<对应的Mozilla版本> (compatibpe; MSIE <IE的版本>; <操作系统名称>)”的形式。
window.navigator.appMinorVersion: 返回浏览器的次版本号。该属性是一个只读的字符串。仅IE有效。
window.navigator.userAgent: userAgent 返回代表浏览器名和版本号的字符串。
window.navigator.platform:返回浏览器平台的字符串("Win32", "Win16", "WinCE", "Mac68k", "MacPPC", "HP-UX", "SunOS" 等)。
window.navigator.cpuClass:返回CPU的信息("x86", "68K", "Alpha", "PPC" 等)。仅IE有效。
window.navigator.browserLanguage、window.navigator.systemLanguage、window.navigator.userLanguage
以上三个语言仅IE有效。
language、browserLanguage 返回浏览器的语言种类,systemLanguage 返回系统的语言种类,userLanguage 返回用户环境的语言种类。
浏览器状态:
window.navigator.cookieEnabled:返回 cookie 是否可用的真伪值。
window.navigator.onLine:返回是否能连上网络的真伪值。
window.navigator.javaEnabled():返回 Java 是否可用的真伪值。
window.navigator.userProfile:
2.1、获取浏览器URL
获取到当前浏览的url地址方法:
window.location.href
window.document.URL
获取URL中的内容信息:
url = 'http://www.baidu.com?id=123456&word=abcd#123'
window.location.hostname // 获取到域名 www.baidu.com
window.location.hash // 获取哈希值 “#” 号后面的值 ?id=123456&word=abcd
window.location.search // 获取 “?” 号后面的值 #123
三、LocalStorage和sessionStorage的用法以及使用区别
3.1、localstorage
localStorage的生命周期是永久性的。即使关闭浏览器,数据也不会销毁,存储大小一般为5M,需要主动去销毁,使用方法如下:
var storage = null;
if(window.localStorage){ //判断浏览器是否支持localStorage
storage = window.localStorage;
storage.setItem("name", "Rick"); //存储/修改
alert(storage.getItem("name")); //获取
storage.removeItem("name"); //删除
storage.clear();//清除所有数据
storage.length();//查看多少条记录
}
3.2、sessionStorage
sessionStorage 的生命周期是在浏览器关闭前。在整个浏览器未关闭前,其数据一直都是存在的。
var storage = window.sessionStorage;
storage.setItem('name', name); // 设置/修改
storage.getItem("name"); // 获取
storage.removeItem("name"); //删除
storage.clear();//清除所有数据
storage.length();//查看多少条记录
四、js获取HTTP request response信息
ajax发起请求的时候才能获取到相关的信息
getResponseHeader 从响应信息中获取指定的http头语法
strValue =oXMLHttpRequest.getResponseHeader(bstrHeader);
getAllResponseHeaders 获取响应的所有http头语法
strValue =oXMLHttpRequest.getAllResponseHeaders();
获取http协议请求行:
getMethod();获取http协议的请求方法;
getRequestURI();获取URI
getRequestURL();获取URL
getQueryString();获取http请求URL后面的查询字符串
getProtocol();获取http后面的协议号版本号
getContextPath();获取URI上下文的路径
getServletPath();获取servlet的映射路径;
获取http协议请求头:
getheader(“”);获取指定的请求头的值
getHeaders(); 返回一个枚举包含请求头中的所有值
getHeaderNames();所有请求头的 名称
getIntHeader();获取特定请求的值,并将其转化为int类型。
getDateHeader();获取特定请求头的值
请求转发:
getRequestDispatcher()方法返回给定路径的RequestDispatcher对象,同时提供了两种方法来包含不同的资源,以及将请求转发到不同资源:
forward()派发请求和响应对象到RequestDispatcher对象所确定的新资源。该资源利用请求和响应对像来处理http请求,将控制权完全移交;
include()包含服务器端的资源暂时把控制权交给别人;
例如:
request.getRequestDispatcher("/login.html").forward(request,response);
注意:
响应重定向会执行两次请求,而请求转发只执行一次。
响应头:
Location:这个头配合302状态码使用,用于告诉客户找谁
Server:服务器通过这个头,告诉浏览器服务器的类型
Content-Encoding:服务器通过这个头,数据的压缩格式
Content-Length:服务器通过这个头,告诉浏览器回送数据的长度
Content-Type:服务器通过这个头,告诉浏览器回送数据的类型
Last-Modified:服务器通过这个头,告诉浏览器当前资源缓存时间
Refresh:服务器通过这个头,告诉浏览器隔多长时间刷新一次
Content-Disposition:服务器通过这个头,告诉浏览器以下载方式打开数据
Transfer-Encoding:服务器通过这个头,告诉浏览器数据的传送格式
ETag:…
Expires:服务器通过这个头,告诉浏览器把回送的资源缓存多长时间,-1或0,则是不缓存
Cache-Control:no-cache
Pragma:no-cache
服务器通过以上两个头,也是控制浏览器不要缓存数据
备注:服务器返回值
当服务器响应时,其状态行的信息为HTTP的版本号,状态码,及解释状态码的简单说明。现将5类状态码详细列出:
① 客户方错误
100 继续
101 交换协议
② 成功
200 OK
201 已创建
202 接收
203 非认证信息
204 无内容
205 重置内容
206 部分内容
③ 重定向
300 多路选择
301 永久转移
302 暂时转移
303 参见其它
304 未修改(Not Modified)
305 使用代理
④ 客户方错误
400 错误请求(Bad Request)
401 未认证
402 需要付费
403 禁止(Forbidden)
404 未找到(Not Found)
405 方法不允许
406 不接受
407 需要代理认证
408 请求超时
409 冲突
410 失败
411 需要长度
412 条件失败
413 请求实体太大
414 请求URI太长
415 不支持媒体类型
⑤ 服务器错误
500 服务器内部错误
501 未实现(Not Implemented)
502 网关失败
504 网关超时
505 HTTP版本不支持
五、document.referrer 的使用
1. a.html文件内容如下:
<a href="b.html">浏览b.html </a>
2. b.html文件中的内容如下:
<body>
<script type="text/javascript">
document.write(document.referrer);
</script>
</body>
3. 则在通过a.html中的超链接访问b.html的时候,显示的结果是:
http://127.0.0.1/a.html
4. URI的编解码
decodeURIComponent() 函数可对 encodeURIComponent() 函数编码的 URI 进行解码。
encodeURIComponent('编码')
decodeURIComponent('解码')
5.1、获取搜索关键词
function goTo(url) {
var ua = navigator.userAgent;
if (ua.indexOf('MSIE') >= 0) {
var rl = document.createElement('a');
rl.href = url;
document.body.appendChild(rl);
rl.click();
} else {
location.href = url;
}
}
function getReferer() {
if (document.referrer) {
return document.referrer;
} else {
return false;
}
}
function getKeyWord(url) {
var refer = url;
var sousuo = refer.split(".")[1];
var grep = null;
var str = null;
var keyword = null;
switch (sousuo) {
case "baidu":
grep = /wd\=.*\&/i;
str = refer.match(grep)
keyword = str == null ? '' : str.toString().split("=")[1].split("&")[0];
fkeyword = keyword.length > 0 ? keyword : '';
if (fkeyword.length > 0) {
setCookie("keyword", getCookie("keyword").length > 0 ? getCookie("keyword") + "," + fkeyword : fkeyword, 7);
setCookie("from", getCookie("from").length > 0 ? getCookie("from") + "," + "baidu" : "baidu", 7);
setCookie("url", getCookie("url").length > 0 ? getCookie("url") + "," + encodeURIComponent(url) : encodeURIComponent(url), 7);
}
break;
case "google":
grep = /&q\=.*/i;
str = refer.match(grep)
keyword = str == null ? '' : str.toString().split("&")[1].split("=")[1];
fkeyword = keyword.length > 0 ? keyword : '';
if (fkeyword.length > 0) {
setCookie("keyword", getCookie("keyword").length > 0 ? getCookie("keyword") + "," + fkeyword : fkeyword, 7);
setCookie("from", getCookie("from").length > 0 ? getCookie("from") + "," + "google" : "google", 7);
setCookie("url", getCookie("url").length > 0 ? getCookie("url") + "," + encodeURIComponent(url) : encodeURIComponent(url), 7);
}
break;
case "so":
grep = /&q\=.*/i;
str = refer.match(grep)
keyword = str == null ? '' : str.toString().split("&")[1].split("=")[1];
fkeyword = keyword.length > 0 ? keyword : '';
if (fkeyword.length > 0) {
setCookie("keyword", getCookie("keyword").length > 0 ? getCookie("keyword") + "," + fkeyword : fkeyword, 7);
setCookie("from", getCookie("from").length > 0 ? getCookie("from") + "," + "360soso" : "360soso", 7);
setCookie("url", getCookie("url").length > 0 ? getCookie("url") + "," + encodeURIComponent(url) : encodeURIComponent(url), 7);
}
break;
}
}
if (!getReferer()) {
goTo('?x=3&r=' + Math.random());
} else {
getKeyWord(getReferer());
}
6、事件
a.窗口事件,只在body和frameset元素中才有效
onload 页面或图片加载完成时
onunload 用户离开页面时
b.表单元素事件,在表单元素中才有效
onchange 框内容改变时
onsubmit 点击提交按钮时
onreset 重新点击鼠标按键时
onselect 文本被选择时
onblur 元素失去焦点时
onfocus 当元素获取焦点时
c.键盘事件,在base,bdo,br,frame,frameset,head,html,iframe,meta,param,script,style,title元素里都无效
onkeydown 按下键盘按键时
onkeypress 按下或按住键盘按键时
onkeyup 放开键盘按键时
d.在base,bdo,br,frame,frameset,head,html,iframe,meta,param,script,style,title元素里都无效
onclick 鼠标点击一个对象时
ondblclick 鼠标双击一个对象时
onmousedown 鼠标被按下时
onmousemove 鼠标被移动时
onmouseout 鼠标离开元素时
onmouseover 鼠标经过元素时
onmouseup 释放鼠标按键时
e.html事件
resize:窗口尺寸变化
scroll:滚动条移动
f.移动事件四种touch事件
touchstart: //手指放到屏幕上时触发
touchmove: //手指在屏幕上滑动式触发
touchend: //手指离开屏幕时触发
touchcancel: //系统取消touch事件的时候触发,这个好像比较少用
每个触摸事件被触发后,会生成一个event对象,event对象里额外包括以下三个触摸列表
touches: //当前屏幕上所有手指的列表
targetTouches: //当前dom元素上手指的列表,尽量使用这个代替touches
changedTouches: //涉及当前事件的手指的列表,尽量使用这个代替touches
这些列表里的每次触摸由touch对象组成,touch对象里包含着触摸信息,主要属性如下:
clientX / clientY: //触摸点相对浏览器窗口的位置
pageX / pageY: //触摸点相对于页面的位置
screenX / screenY: //触摸点相对于屏幕的位置
identifier: //touch对象的ID
target: //当前的DOM元素
其他
onresize 当窗口或框架被重新定义尺寸时
onabort 图片下载被打断时
onerror 当加载文档或图片时发生错误时
自定义对象:有初始化对象和定义构造函数的对象两种方法
a:初始化对象
例如: 对象={属性1:值1;属性2:值2;......属性n:值n} 注意:每个属性/值对之间用分号隔开;
b: 定义构造函数的对象
例如:
function 函数名(属性1, 属性2,......属性N){
this.属性1=属性值1;
this.属性2=属性值2;
this.属性n=属性值n;
this.方法名1=函数名1;
this.方法名2=函数名2;
}
6.1、特殊事件
6.1.1、浏览器控制历史记录 popstate
a、popstate用来做什么的?
简而言之就是HTML5新增的用来控制浏览器历史记录的api。
b、过去如何操纵浏览器历史记录?
window.history对象,该对象上包含有length和state的两个值,在它的__proto__上继承有back、forward、go等几个功能函数
在popstate之前,我们可以利用back、forward、go对history进行后退和前进操作。
例如:
history.back(); (后退一步,使用history.go(-1)也可实现后退效果)
弊端:只能操作前进后退,但是无法控制前进后要去哪,history.length都只会维持原来的状态
c、popstate的怎么用?
HTML5的新API扩展了window.history,使历史记录点更加开放了。可以存储当前历史记录点pushState、替换当前历史记录点replaceState、监听历史记录点popstate。
pushState、replaceState两者用法差不多。
使用方法:
history.pushState(data,title,url); //其中第一个参数data是给state的值;第二个参数title为页面的标题,但当前所有浏览器都忽略这个参数,传个空字符串就好;第三个参数url是你想要去的链接; replaceState用法类似,例如:history.replaceState("首页","",location.href+ "#news");
两者区别:pushState会改变history.length,而replaceState不改变history.length
window.addEventListener("popstate", function(e) {
worrying.style.display = "block";
}, false);
function pushHistory() {
var state = {
title: "title",
url: ""
};
window.history.pushState(state, "title", "");
}
7、cookie 的操作
cookie.set("uesr","sss",24);//设置为24天过期
alert(cookie.get("uesr"));//获取cookie
document.cookie = 'k1=v1;k2=v2;' 设置cookie
var cookie = document.cookie; 获取所有的cookie字符串
给cookie设置终止日期
例如:如果要将cookie设置为10天后过期,可以这样实现:
//获取当前时间
var date=new Date();
var expiresDays=10;
//将date设置为10天以后的时间
date.setTime(date.getTime()+expiresDays*24*3600*1000);
//将userId和userName两个cookie设置为10天后过期
document.cookie="userId=828; userName=hulk; expires="+date.toGMTString();
其中GMT_String是以GMT格式表示的时间字符串,这条语句就是将userId这个cookie设置为GMT_String表示的过期时间,
超过这个时间,cookie将消失,不可访问。
删除cookie
为了删除一个cookie,可以将其过期时间设定为一个过去的时间,例如:
//获取当前时间
var date=new Date();
//将date设置为过去的时间
date.setTime(date.getTime()-10000);
//将userId这个cookie删除
document.cookie="userId=828; expires="+date.toGMTString();
8、js编码与解码
8.1、charCodeAt()
js unicode是以十六进制代码外加开头\u表示的字符串。即\unnnn
'好'.charCodeAt(0).toString(16)
"597d"
这段代码的意思是,把字符'好'转化成Unicode编码,toString()就是把字符转化成16进制了;charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。等于就是'charCodeAt()'里面的这个参数是指定位置的单个字符,
'好哦'.charCodeAt(0).toString(16)
"597d"
'好哦'.charCodeAt(1).toString(16)
"54e6"
上面这段代码就可以看出,一个字符串你想要知道单个字符的编码,就是靠里面的这个参数,也就是索引。
8.2、编解码url
Javascript语言用于编码的函数,一共有三个,最古老的一个就是escape()。虽然这个函数现在已经不提倡使用了,但是由于历史原因,很多地方还在使用它,所以有必要先从它讲起。
8.2.1、escape 和 unescape
实际上,escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如"春节"的返回结果是%u6625%u8282,也就是说在Unicode字符集中,"春"是第6625个(十六进制)字符,"节"是第8282个(十六进制)字符。
它的具体规则是,除了ASCII字母、数字、标点符号"@ * _ + - . /"以外,对其他所有字符进行编码。在u0000到u00ff之间的符号被转成%xx的形式,其余符号被转成%uxxxx的形式。对应的解码函数是unescape()。
PS:
首先,无论网页的原始编码是什么,一旦被Javascript编码,就都变为unicode字符。也就是说,Javascipt函数的输入和输出,默认都是Unicode字符。这一点对下面两个函数也适用。
其次,escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心。
例如:
编码:
1 2 3 4 5 |
|
解码:
1 2 3 4 5 |
|
8.2.2、encodeURI 和 decodeURI
encodeURI()是Javascript中真正用来对URL编码的函数;它着眼于对URL中的中文字符,因此除了常用的英文字符以外,对其他一些在网址中有特殊含义的符号"; / ? : @ & = + $ , #",也不进行编码;编码中文字符后,它输出符号的utf-8形式,并且在每个字节前加上%。
它对应的解码函数是decodeURI()。
注:需要注意的是,它不对单引号'编码。
例如:
编码:
1 2 |
|
解码:
1 2 |
|
8.2.3、
encodeURIComponent 和 decodeURIComponent
最后一个Javascript编码函数是encodeURIComponent()对URL中的符号以及中文字符进行编码;因此"; / ? : @ & = + $ , #"这些在encodeURI()中不被编码的符号,在encodeURIComponent()中会被编码;至于具体的编码方法,两者是一样。
它对应的解码函数是decodeURIComponent()。
例如:
编码:
1 2 |
|
解码:
1 2 |
结果:http://www.baidu.com?name=zhang@xiao@jie&order=1 |
9、javascript JSON
1、JS中生成JSON对象和字符串的方法:
var json = [];
var row1 = {};
row1.id= "1";
row1.name = "jyy";
// 或者
var row2 = {id:'2',name:'abc'}
json.push(row1);
json.push(row2);
// 或者
// JSON字符串:
var str1 = '{ "name": "haorooms", "sex": "man" }';
// JSON对象:
var str2 = { "name": "haorooms", "sex": "man" };
2、JS中将JSON对象解析为字符串的方法:
var jsonStr = JSON.stringify(json);
3、JS解析JSON对象或者字符串的方法:
var objs = eval(json);
// 或者
var objs = eval(jsonStr);
for(var j = 0;j<objs.length;j++){
alert(objs[j].id);
alert(objs[j].name);
}
4、页面中Json对象与Json字符串互转(4种转换方式):
4.1、jQuery插件支持的转换方式:
$.parseJSON( jsonstr ); // jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象
4.2、浏览器支持的转换方式(Firefox,chrome,opera,safari,ie9,ie8)等浏览器:
JSON.parse(jsonstr); // 可以将json字符串转换成json对象
var obj = str.parseJSON(); // 由JSON字符串转换为JSON对象
JSON.stringify(jsonobj); // 可以将json对象转换成json对符串
var last=obj.toJSONString(); // 将JSON对象转化为JSON字符
注:ie8(兼容模式),ie7和ie6没有JSON对象,推荐采用JSON官方的方式,引入json.js。
4.3、Javascript支持的转换方式:
eval('(' + jsonstr + ')'); // 可以将json字符串转换成json对象,注意需要在json字符外包裹一对小括号 。
注:ie8(兼容模式)、ie7和ie6也可以使用eval()将字符串转为JSON对象,但不推荐这些方式,这种方式不安全eval会执行json串中的表达式。
4.4、JSON官方的转换方式:
http://www.json.org/提供了一个json.js,这样ie8(兼容模式)、ie7和ie6就可以支持JSON对象以及其stringify()和parse()方法;
可以在https://github.com/douglascrockford/JSON-js上获取到这个js,一般现在用json2.js。
10、DOM操作
Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法。常见的Node有 element,text,attribute,comment,document 等(所以要注意 节点 和 元素 的区别,元素属于节点的一种)。
Node有一个属性 nodeType 表示Node的类型,它是一个整数,其数值分别表示相应的Node类型,具体如下:
{
ELEMENT_NODE: 1, // 元素节点
ATTRIBUTE_NODE: 2, // 属性节点
TEXT_NODE: 3, // 文本节点
DATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8, // 注释节点
DOCUMENT_NODE: 9, // 文档
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11, // 文档碎片
NOTATION_NODE: 12,
DOCUMENT_POSITION_DISCONNECTED: 1,
DOCUMENT_POSITION_PRECEDING: 2,
DOCUMENT_POSITION_FOLLOWING: 4,
DOCUMENT_POSITION_CONTAINS: 8,
DOCUMENT_POSITION_CONTAINED_BY: 16,
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32
}
NodeList 对象是一个节点的集合,一般由 Node.childNodes 、 document.getElementsByName 和 document.querySelectorAll 返回的;不过需要注意, Node.childNodes 、 document.getElementsByName 返回的 NodeList 结果是实时的(此时跟HTMLCollection比较类似),而 document.querySelectorAll 返回的结果是固定的,这一点比较特殊。
举例如下:
var childNodes = document.body.childNodes;
console.log(childNodes.length); // 如果假设结果是“2”
document.body.appendChild(document.createElement('div'));
console.log(childNodes.length); // 此时的输出是“3”
1、HTMLCollection
HTMLCollection是一个特殊的NodeList,表示包含了若干元素(元素顺序为文档流中的顺序)的通用集合,它是实时更新的,当其所包含的元素发生改变时,它会自动更新。另外,它是一个伪数组,如果想像数组一样操作它们需要像 Array.prototype.slice.call(nodeList, 2) 这样调用。
2、节点查找API
document.getElementById :根据ID查找元素,大小写敏感,如果有多个结果,只返回第一个;
document.getElementsByClassName :根据类名查找元素,多个类名用空格分隔,返回一个 HTMLCollection 。注意兼容性为IE9+(含)。另外,不仅仅是document,其它元素也支持 getElementsByClassName 方法;
document.getElementsByTagName :根据标签查找元素, * 表示查询所有标签,返回一个 HTMLCollection 。
document.getElementsByName :根据元素的name属性查找,返回一个 NodeList 。
document.querySelector :返回单个Node,IE8+(含),如果匹配到多个结果,只返回第一个。
document.querySelectorAll :返回一个 NodeList ,IE8+(含)。
document.forms :获取当前页面所有form,返回一个 HTMLCollection ;
3、创建节点API
节点创建API主要包括 createElement 、 createTextNode 、 cloneNode 和 createDocumentFragment 四个方法。
3.1、创建元素:createElement
var elem = document.createElement("div");
elem.id = 'test';
elem.style = 'color: red';
elem.innerHTML = '我是新创建的节点';
document.body.appendChild(elem);
通过 createElement 创建的元素并不属于 document 对象,它只是创建出来,并未添加到html文档中,要调用 appendChild 或 insertBefore 等方法将其添加到HTML文档中。
3.2、创建文本节点 createTextNode:
var node = document.createTextNode("我是文本节点");
document.body.appendChild(node);
3.3、克隆一个节点 cloneNode:
node.cloneNode(true/false) ,它接收一个bool参数,用来表示是否复制子元素。
var from = document.getElementById("test");
var clone = from.cloneNode(true);
clone.id = "test2";
document.body.appendChild(clone);
克隆节点并不会克隆事件,除非事件是用 <div οnclick="test()"></div> 这种方式绑定的,用 addEventListener 和 node.οnclick=xxx; 方式绑定的都不会复制。
3.4、createDocumentFragment
本方法用来创建一个 DocumentFragment ,也就是文档碎片,它表示一种轻量级的文档,主要是用来存储临时节点,大量操作DOM时用它可以大大提升性能。
假设现有一题目,要求给ul添加10000个li,我们先用最简单的拼接字符串的方式来实现:
<ul id="ul"></ul>
<script>
(function()
{
var start = Date.now();
var str = '';
for(var i=0; i<10000; i++)
{
str += '<li>第'+i+'个子节点</li>';
}
document.getElementById('ul').innerHTML = str;
console.log('耗时:'+(Date.now()-start)+'毫秒'); // 44毫秒
})();
</script>
再换逐个append的方式,不用说,这种方式效率肯定低:
<ul id="ul"></ul>
<script>
(function()
{
var start = Date.now();
var str = '', li;
var ul = document.getElementById('ul');
for(var i=0; i<10000; i++)
{
li = document.createElement('li');
li.textContent = '第'+i+'个子节点';
ul.appendChild(li);
}
console.log('耗时:'+(Date.now()-start)+'毫秒'); // 82毫秒
})();
</script>
最后再试试文档碎片的方法,可以预见的是,这种方式肯定比第二种好很多,但是应该没有第一种快:
<ul id="ul"></ul>
<script>
(function()
{
var start = Date.now();
var str = '', li;
var ul = document.getElementById('ul');
var fragment = document.createDocumentFragment();
for(var i=0; i<10000; i++)
{
li = document.createElement('li');
li.textContent = '第'+i+'个子节点';
fragment.appendChild(li);
}
ul.appendChild(fragment);
console.log('耗时:'+(Date.now()-start)+'毫秒'); // 63毫秒
})();
</script>
4、节点修改API
节点修改API都具有下面这几个特点:
不管是新增还是替换节点,如果其原本就在页面上,那么原来位置的节点将被移除;
修改之后节点本身绑定的事件不会消失;
4.1、appendChild(child)
在某个节点后追加插入另一个节点,语法就是:
parent.appendChild(child);
它会将child追加到parent的子节点的最后面。另外,如果被添加的节点是一个页面中存在的节点,则执行后这个节点将会添加到新的位置,其原本所在的位置将移除该节点,也就是说不会同时存在两个该节点在页面上,且其事件会保留。
4.2、insertBefore(newNode, refNode)
将某个节点插入到另外一个节点的前面,语法:
parentNode.insertBefore(newNode, refNode);
这个API个人觉得设置的非常不合理,因为插入节点只需要知道newNode和refNode就可以了,parentNode是多余的,所以jQuery封装的API就比较好:
newNode.insertBefore(refNode); // 如 $("p").insertBefore("#foo");
切记不要把这个原生API 和 jQuery API使用方法搞混,这里写一个简单的例子:
<div id="parent">
我是父节点
<div id="child">
我是旧的子节点
</div>
</div>
<input type="button" id="insertNode" value="插入节点" />
<script>
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").addEventListener('click', function()
{
var newNode = document.createElement("div");
newNode.textContent = "我是新节点";
parent.insertBefore(newNode, child);
}, false);
</script>
关于第二个参数:
refNode是必传的,如果不传该参数会报错;
如果refNode是undefined或null,则insertBefore会将节点添加到末尾;
4.3、removeChild(node)
removeChild用于删除指定的子节点并返回子节点,语法:
var deletedChild = parent.removeChild(node);
deletedChild指向被删除节点的引用,它仍然存在于内存中,可以对其进行下一步操作。另外,如果被删除的节点不是其子节点,则将会报错。一般删除节点都是这么删的:
function removeNode(node)
{
if(!node) return;
if(node.parentNode) node.parentNode.removeChild(node);
}
4.4、replaceChild(newChild, oldChild)
replaceChild用于将一个节点替换另一个节点,语法:
parent.replaceChild(newChild, oldChild);
5、节点关系API
DOM中的节点相互之间存在着各种各样的关系,如父子关系,兄弟关系等。
5.1、父关系API
parentNode :每个节点都有一个parentNode属性,它表示元素的父节点。Element的父节点可能是Element,Document或DocumentFragment;
parentElement :返回元素的父元素节点,与parentNode的区别在于,其父节点必须是一个Element元素,如果不是,则返回null;
5.2、子关系API
children :返回一个实时的 HTMLCollection ,子节点都是Element,IE9以下浏览器不支持;
childNodes :返回一个实时的 NodeList ,表示元素的子节点列表,注意子节点可能包含文本节点、注释节点等;
firstChild :返回第一个子节点,不存在返回null,与之相对应的还有一个 firstElementChild ;
lastChild :返回最后一个子节点,不存在返回null,与之相对应的还有一个 lastElementChild ;
5.3、兄弟关系型API
previousSibling :节点的前一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点或注释节点,与预期的不符,要进行处理一下。
nextSibling :节点的后一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点,与预期的不符,要进行处理一下。
previousElementSibling :返回前一个元素节点,前一个节点必须是Element,注意IE9以下浏览器不支持。
nextElementSibling :返回后一个元素节点,后一个节点必须是Element,注意IE9以下浏览器不支持。
6、元素属性型API
6.1、setAttribute(name, value)
给元素设置属性:
element.setAttribute(name, value);
其中name是特性名,value是特性值。如果元素不包含该特性,则会创建该特性并赋值。
6.2、getAttribute("id")
getAttribute返回指定的特性名相应的特性值,如果不存在,则返回null:
var value = element.getAttribute("id");
7、样式相关API
7.1、直接修改元素的样式
elem.style.color = 'red';
elem.style.setProperty('font-size', '16px');
elem.style.removeProperty('color');
7.2、动态添加样式规则
var style = document.createElement('style');
style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}';
document.head.appendChild(style);
7.3、window.getComputedStyle(element[, pseudoElt])
通过 element.sytle.xxx 只能获取到内联样式,借助 window.getComputedStyle 可以获取应用到元素上的所有样式,IE8或更低版本不支持此方法。
var style = window.getComputedStyle(element[, pseudoElt]);
7.4、getBoundingClientRect()
getBoundingClientRect 用来返回元素的大小以及相对于浏览器可视窗口的位置,用法如下:
var clientRect = element.getBoundingClientRect();
clientRect是一个 DOMRect 对象,包含width、height、left、top、right、bottom,它是相对于窗口顶部而不是文档顶部,滚动页面时它们的值是会发生变化的。