1.window.onload 和 document.onDOMContentLoaded 有什么区别
这两者之间的区别首先要了解浏览器页面的展现,在浏览器解析html的时候是先构建DOM树
document.onDOMContentLoaded
是在浏览器DOM的结构渲染完成就触发
window.onload
则是在整个页面所有资源全都加载完成才触发
window.nonload
的完成时间要远远晚于document.onDOMContentLoaded
,因为在DOM构建完成之后还可能要需要加载其他资源,比如图片、flash。
在jquery中可以使用$(document).ready
就是就是利用了DOMContentLoaded来实现的
2.如何获取图片真实的宽高
//现在有有一个class为image的图片
//或者可以用 .getComputedStyle 来获取元素计算后的样式
3.如何获取元素的真实宽高
用.getComputedStyle
来获取元素计算后的样式
console.log(getComputedStyle(document.querySelector('element')).height)
console.log(getComputedStyle(document.querySelector('element')).width)
4.URL 如何编码解码?为什么要编码?
-
数据是怎么传递的
数据在HTTP中传输的时候会采用“key=value”键值对这种方法来传递数据,而键值对又是以&
来分割参数,用=
来分割参数值,比如name=tom&age=10
就分割成name=tom
和age=10
。
服务器在读取数据的时候会把所有的字符转换成ASCII码(最广泛的方式),比如&
对应的是26
,=
对应的是3D
,当服务器处理数据的时候读到了3D
就知道前面读取的是一个key,当读到26
的时候,就知道前面读取到的是一个key的value。这样可以把客户端传过来的参数解析
-
为什么要编码
如果在传递参数的时候,参数值里面包含了一些特殊的字符,比如&和=。假如我想传递一个键值对name=t$om=1
,要传递的参数是name
参数的值是t&om=1
,但是服务器解析的时候就会认为是传递了两个参数,分别是name=t
和om=1
。本意是想要传递一个键值对,现在结果解析出来是两个,这显然不是我们想要的。这个时候我们就需要通过编码来转义有异议的字符,让服务器得到我们想要传递的数据。
-
URL 如何编码解码
URL编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符
编码:首先需要把该字符的 ASCII 的值表示为两个16进制的数字,然后在其前面放置转义字符("%"),置入 URL 中的相应位置。(对于非 ASCII 字符, 需要转换为 UTF-8 字节序, 然后每个字节按照上述方式表示.)
如"中文"使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,经过Url编码之后得到"%E4%B8%AD%E6%96%87"
解码:将ACSII码转义回去
-
JavaScript提供四个URL的编码/解码方法
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
-
区别
encodeURI()
方法不会对下列字符编码
ASCII字母
数字
~!@#$&*()=:/,;?+'
encodeURIComponent()
方法不会对下列字符编码
ASCII字母
数字
~!*()'
所以encodeURIComponent()
比encodeURI()
编码的范围更大。encodeURIComponent()
会把 http://
编码成 http%3A%2F%2F
而encodeURI()
却不会
5.补全如下函数,判断用户的浏览器类型
function isAndroid(){
}
function isIphone(){
}
function isIpad(){
}
function isIOS(){
}
function isAndroid(){
return /android/i.test(navigator.userAgent);
}
funcnction isIphone(){
return /iphone/i.test(navigator.userAgent);
}
function isIpad(){
return /ipad/i.test(navigator.userAgent);
}
function isIOS(){
return /(ipad)|(iphone)/i.test(navigator.userAgent);
}
通过userAgent属性识别浏览器,不是一个好办法。因为必须考虑所有的情况(不同的浏览器,不同的版本),非常麻烦,而且无法保证未来的适用性,更何况各种上网设备层出不穷,难以穷尽。所以,现在一般不再识别浏览器了,而是使用“功能识别”方法,即逐一测试当前浏览器是否支持要用到的JavaScript功能。
5.cookie & session &localStorage 分别是什么?
-
cookie
- Cookie是什么
1.Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据
2.浏览器需要保存这段数据,不得轻易删除。
3.此后每次浏览器访问该服务器,都必须带上这段数据。 - 为什么要用cookie
因为HTTP协议是无状态的,服务器无法判断两条请求是否是同一个浏览器所发出的,但是一直保持"会话"需要占用到额外的资源。cookie的设置就能使用户在第一次访问某个服务器的时候,通过服务器的指令在本地建立一个可以进行认证的文件,每次发送请求的时候把cookie文件随着一同发送,来进行认证。 - cookie的一些特点
1.cookie本身是一段文本,明文保存,只能保存字符串,本身的大小不能超过4KB,因为每次请求都会跟随一起发送到服务器。
2.cookie的设置可以是服务器通过set-cookie让浏览器种下cookie,用户也可以通过js的操作去修改cookie的内容,比如设置好默认的用户名和密码,下一次就不用再自己填写。(cookie参数httpOnly为true
可以让浏览器不允许脚本操作 document.cookie 去更改 cookie)
3.cookie是有过期时间的,如果不设置过期时间,cookie会保存在内存中,在浏览器关闭的时候,cookie会比一并删除。如果设置了过期时间,那么cookie会保存在硬盘中可以继续使用。
4.浏览器限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie。不同浏览器能保存的总cookie也是有限制的
-
session
- session是什么
session也是服务器的一种机制,会使用另一种方法来追踪会话。用户在向服务器发送请求的时候,服务器会检索请求中有没有session_id,如果有,就跟自己本身所保存的session_id一一检索来确认用户,如果没有,就给用户创建一个新的session_id,一般会保存在cookie中。 - 为什么要用session
不同于cookie的明文保存,session_id是一个1024比特长度的随机字符串,里面只包含了用户唯一的身份识别信息。除了身份识别,其他所有信息都是在服务端,保证了数据的安全性。而且即使用户禁用了cookie,也有其他方法能传输session_id - session的特点
1.session的过期时间是立即,也就是浏览器关闭会立马删除session_id
2.Session中能够存取任何类型的数据,包括而不限于String、Integer、List、Map等
3.即使cookie可以进行加密放到服务器后再解密,相对来说session就省事多了。但是如果某个网站并发大,太多的session会影响服务器性能,这时候反而不如cookie这类放在本地浏览器数据节约资源。
-
localStorage
localStorage是什么
1.localStorage HTML5本地存储web storage特性的API之一,用于将大量数据(最大5M)保存在浏览器中,保存后数据永远存在不会失效过期,除非用 js手动清除。
2.不参与网络传输。
3.一般用于性能优化,可以保存图片、js、css、html 模板、大量数据。
4.localstorage在隐私模式下不可读取
5.localstorage本质是在读写文件,数据多的话会比较卡
6.localstorage不能被爬虫爬取,不要用它完全取代URL传参localstorage的使用
基础知识
localstorage存储对象分为两种:
1.sessionStrage: session即会话的意思,在这里的session是指用户浏览某个网站时,从进入网站到关闭网站这个时间段,session对象的有效期就只有这么长。
2.localStorage: 将数据保存在客户端硬件设备上,不管它是什么,意思就是下次打开计算机时候数据还在。
两者区别就是一个作为临时保存,一个长期保存。
6.使用 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,并且 localStorage 里清除 teachers 字段
不会用.set/.get的写法和思路
localStorage.clear(); //清除所有的localStorage 方便调试
var storageset = function(key, value, time){ //三个参数
//localStorage存放的是string字符串类型的,所以需要用JSON.stringify把对象转换为字符串
localStorage[key] = JSON.stringify({ //localStorage[key]表示localStorage(key)的内容
value : value, //第一个value是键名,随便取。第二个value是键值,function传递的参数
times : time===undefined?undefined:Date.now() + time*1000, //同上,定义时间待会作比较
}); //注意大括号
};
var storageget = function(key){
if(localStorage[key] === undefined){
return; ////如果没有值,就返回字符串。如果不设置就返回undefined
}
var v = JSON.parse(localStorage[key]); //把字符串转换为对象
if(v.times > Date.now() || v === undefined){ //看是否设置了时间,时间多久了
return v.value; //倒计时没到或者没设置时间 直接返回
}else{
localStorage.removeItem(key); //如果时间到了,删除key的值
//delate localStorage[key]
return;
}
};
storageset('a', 10 ,5); //设置一个参数用来调试
storageget('a') //10
localStorage //Storage {a: "{"value":10,"times":1585434173171}", length: 1}
//5秒后
storageget('a') //undefined
localStorage //Storage {length: 0}
完美封装
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]
}
}
}
})()