window.onload 和 document.onDOMContentLoaded 有什么区别?
两者的区别主要是触发的时机不同,DOMContentLoaded
是在DOM树构建完成触发,而window.onload
是在DOM树构建完成、外部的js、css、图片等资源都加载完成后再触发。即:
-
windo.onload
:当页面完全加载后(包括所有图像,JavaScript文件,CSS文件等外部资源),就会触发window上面的load事件。 -
document.onDOMContentLoaded
:当初始HTML文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架完成加载。
两事件的作用都是:
- 当我们给一些元素绑定函数时,会出现绑定处理函数运行完了,但是元素还没有加载的情况。而
window.onload
事件和document.onDOMContentLoaded
事件就是为了避免这种情况。 - 保证在元素加载完成之后再处理绑定函数。但
document.onDOMContentLoaded
加载机制更加合理。因为大多数客户可以允许图片,flash等的加载。
如何获取图片真实的宽高?
document.querySelector('img').onload = function(){
console.log(this.width)
console.log(this.height)
}
//输出的是渲染后的图片宽高
getComputedStyle(img).width
getComputedStyle(img).height
// getComputedStyle方法可用来获取元素中所有可用的css属性
//IE678 中则用 currentStyle 代替
//由于获得的是CSS属性,相当于是渲染后的图片宽高
var img_url ='http://js.jirengu.com/images/dave.min.svg' // 创建对象
var img = new Image() // 改变图片的src
img.src = img_url // 加载完成执行
img.onload = function(){
console.log('图片真实width: '+img.width+', 图片真实height: '+img.height)
} //输出
//输出的是图片原始宽高
如何获取元素的真实宽高?
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.box {
width: 500px;
height: 600px;
border: 2px solid black;
}
</style>
</head>
<body>
<div class="box">NinthG</div>
<script>
function $(selector) {
return document.querySelector(selector)
}
console.log(window.getComputedStyle($('.box')).width);
console.log(window.getComputedStyle($('.box')).height);
//不包含border
</script>
</body>
使用clientWidth
和clientHeight
可以获取元素内容区域的宽高,对应于box-sizing: content-box
使用offsetWidth
和offsetHeight
可以获取元素边框内部区域的宽高,对应于box-sizing: border-box*
URL 如何编码解码?为什么要编码?
如何编码解码
JavaScript提供四个URL的编码/解码方法。
- decodeURI()
- decodeURIComponent()
- encodeURI()
- encodeURIComponent()
区别
encodeURI方法不会对下列字符编码
1\. ASCII字母
2\. 数字
3\. ~!@#$&*()=:/,;?+'
encodeURIComponent方法不会对下列字符编码
1\. ASCII字母
2\. 数字
3\. ~!*()'
所以encodeURIComponent比encodeURI编码的范围更大。
实际例子来说,encodeURIComponent会把 http://
编码成 http%3A%2F%2F
而encodeURI却不会。
如果你需要编码整个URL,然后需要使用这个URL,那么用encodeURI。 encodeURI("http://blog.jirengu.com/?cat=11&a=饥人谷"); //"http://blog.jirengu.com/?cat=11&a=%25E9%25A5%25A5%25E4%25BA%25BA%25E8%25B0%25B7";
其中,汉字被编码。但是如果你用了encodeURIComponent,那么结果变为
"http%3A%2F%2Fblog.jirengu.com%2F%3Fcat%3D11%26a%3D%25E9%25A5%25A5%25E4%25BA%25BA%25E8%25B0%25B7"
为什么要编码
通常如果一样东西需要编码,说明这样东西并不适合传输。原因多种多样,如Size过大,包含隐私数据,对于Url来说,之所以要进行编码,是因为Url中有些字符会引起歧义。
- 例如,Url参数字符串中使用key=value键值对这样的形式来传参,键值对之间以&符号分隔,如/s?q=abc&ie=utf-8。如果你的value字符串中包含了=或者&,那么势必会造成接收Url的服务器解析错误,因此必须将引起歧义的&和=符号进行转义,也就是对其进行编码。
- 又如,Url的编码格式采用的是ASCII码,而不是Unicode,这也就是说你不能在Url中包含任何非ASCII字符,例如中文。否则如果客户端浏览器和服务端浏览器支持的字符集不同的情况下,中文可能会造成问题。
Url编码的原则:就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。
为什么要进行URL编码
escape,encodeURI,encodeURIComponent有什么区别?
补全如下函数,判断用户的浏览器类型。
function isAndroid() {
return /Android/.test(window.navigator.userAgent);
}
function isiPhone() {
return /iphone/i.test(window.navigator.userAgent);
}
function isiPad() {
return /ipad/i.test(window.navigator.userAgent);
}
function isIOS() {
return /(ipad)|(iphone)/.test(widow.navigator.userAgent);
}
//通过userAgent属性识别浏览器,不是一个好办法。
//因为必须考虑所有的情况(不同的浏览器,不同的版本),非常麻烦,而且无法保证未来的适用性,更何况各种上网设备层出不穷,难以穷尽。
//所以,现在一般不再识别浏览器了,而是使用“功能识别”方法,即逐一测试当前浏览器是否支
cookie & session &localStorage 分别是什么?
cookie
- cookie是存储在浏览器上的一小段数据,用来记录某些当页面关闭或者刷新后仍然需要记录的信息。在控制台用 「document.cookie」查看你当前正在浏览的网站的cookie。
- cookie可以使用 js 在浏览器直接设置(用于记录不敏感信息,如用户名), 也可以在服务端通使用 HTTP 协议规定的 set-cookie 来让浏览器种下cookie,这是最常见的做法。(打开一个网站,清除全部cookie,然后刷新页面,在network的Response headers试试找一找set-cookie吧)
- 每次网络请求 Request headers 中都会带上cookie。所以如果 cookie 太多太大对传输效率会有影响。
- 一般浏览器存储cookie 最大容量为4k,所以大量数据不要存到cookie。
session
当一个用户打开淘宝登录后,刷新浏览器仍然展示登录状态。服务器如何分辨这次发起请求的用户是刚才登录过的用户呢?这里就使用了session保存状态。用户在输入用户名密码提交给服务端,服务端验证通过后会创建一个session用于记录用户的相关信息,这个 session 可保存在服务器内存中,也可保存在数据库中。
- 创建session后,会把关联的session_id 通过setCookie 添加到http响应头部中。
- 浏览器在加载页面时发现响应头部有 set-cookie字段,就把这个cookie 种到浏览器指定域名下。
- 当下次刷新页面时,发送的请求会带上这条cookie, 服务端在接收到后根据这个session_id来识别用户。
cookie 是存储在浏览器里的一小段「数据」,而session是一种让服务器能识别某个用户的「机制」,session 在实现的过程中需要使用cookie。 二者不是同一维度的东西。
localStorage
- localStorage HTML5本地存储web storage特性的API之一,用于将大量数据(最大5M)保存在浏览器中,保存后数据永远存在不会失效过期,除非用 js手动清除。
- 不参与网络传输。
- 一般用于性能优化,可以保存图片、js、css、html 模板、大量数据。
使用 localStorage封装一个 Storage 对象,达到如下效果:
Storage.set('name', '饥人谷')
Storage.set('age', 2, 30) ; //设置 name 字段存储的值为'饥人谷'
Storage.set('teachers', ['ruoyu', 'fangfang', 'tom'], 60)
Storage.get('name') // ‘饥人谷’
Storage.get('age') // 如果不超过30秒,返回数字类型的2;如果超过30秒,返回 undefined,并且 localStorage 里清除 age 字段
Storage.get('teachers') //如果不超过60秒,返回数组; 如果超过60秒,返回undefined
var Storage = (function(){
return {
set: function(key, value, expireSeconds){
localStorage[key] = JSON.stringify({
value: value,
expired: expireSeconds===undefined?undefined:Date.now() + 1000*expireSeconds
})
},
get: function(key){
if(localStorage[key] === undefined){
return
}
var o = JSON.parse(localStorage[key])
if(o.expired === undefined || Date.now() < o.expired){
return o.value
}else{
delete localStorage[key]
}
}
}
})()
网友评论