js位置、web存储、页面加载事件、给类添加方法、promise封装ajax、重绘和重排、XMLHTTPRequest和JSONP

一、js放在head和body标签中的区别

head 部分中的脚本: 需调用才执行的脚本或事件触发执行的脚本放在HTML的head部分中。当你把脚本放在head部分中时,可以保证脚本在任何调用之前被加载。
body 部分中的脚本: 当页面被加载时执行的脚本放在HTML的body部分。放在body部分的脚本通常被用来生成页面的内容。

二、html5的web存储

以前我们在本地存储数据都是用document.cookie来存储的,但是由于其的存储大小只有4K左右,解析也很复杂,给开发带来了诸多的不便.不过现在html5出了web的存储,弥补了cookie的不足,而且开放起来也是相当的方便。

web存储分两类

sessionStorage

容量大小约为5M左右,该方式的生命周期为关闭浏览器窗口为止

localStorage

容量大小约为20M左右, 存储的数据不会随着用户浏览时会话过期而过期,但会应用户的请求而删除。浏览器也因为存储空间的限制或安全原因删除它们.而且类型存储的数据可以同一个浏览器的多个窗口共享

注意点:只能存储字符串,如果是json对象的话,可以将对象JSON.stringify() 编码后存储

方法详解:

setItem(key, value) 设置存储内容

getItem(key) 读取存储内容

removeItem(key) 删除键值为key的存储内容

clear() 清空所有存储内容

写法:

 //更新
function update() {
    window.sessionStorage.setItem(key, value);
}
//获取
function get() {
    window.sessionStorage.getItem(key);
}
//删除
function remove() {
    window.sessionStorage.removeItem(key);
}
//清空所有数据
function clear() {
    window.sessionStorage.clear();
}

三、页面加载顺序及触发的事件

页面加载大致的几个步骤

1.开始解析HTML文档结构。

2.加载外部样式表及JavaScript脚本。

3.解析执行JavaScript脚本。

4.DOM树渲染完成。

5.加载未完成的资源(如图片)。

6.页面加载成功。

页面加载触发的事件

1.document的readystatechange事件

document.onreadystatechange = function() { // 文档加载状态改变事件处理
    if (document.readyState === "loading") { // document加载中
        console.log(document.readyState);
    }
    if (document.readyState === "interactive") { // 互动文档加载完成,文档解析完成,但是如图像,样式表和框架等子资源仍在加载中
        console.log(document.readyState);
    }
    if (document.readyState === "complete") { // 文档和所有子资源加载完成,load事件即将被触发
        console.log(document.readyState);
    }
}

readyState属性描述了文档的加载状态,整个加载过程中document.readyState会不断变化,每次变化都触发readystatechange事件。

也可以用事件监听器去绑定:

document.addEventListener("readystatechange", function() {
    console.log(document.readyState);
});

2.document的DOMContentLoaded事件

DOM树渲染完成时候触发DOMContentLoaded事件,此时可能外部资源还在加载。jQuery中的ready事件就是实现的这个事件。

3.window的load事件

当所有的资源全部加载完成后就会触发window的load事件。
load()和onload 效果是一样的 都是在页面所有内容加载完才执行;但是onload只能有一个,load可以有多个; ready()是DOM结构树绘制完毕后执行。

四、JS中,使用什么属性可以对Dog类添加方法eat( )

prototype

Dog.prototype.eat = function(   ){}

五、用Promise封装Ajax

Promise的出现主要是解决地狱回调的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有Promise 我们就无需嵌套。Promise的本质就是分离了异步数据获取和业务逻辑。
ajax

$.ajax({
        method:"post",
        url:"/xxx",
        data:"username=mtt&password=1",
        dataType:'json',
        success:()=>{}//成功后的回调函数
        error:()=>{}//失败后的回调函数
    }
    )

用promise封装ajax

let myButton = document.getElementById('myButton');

function success(responseText){
    console.log("成功")
    console.log(responseText);//responseTex
}
function fail(request){
    console.log("失败")
    console.log(request);
}
myButton.addEventListener("click",(e)=>{
    //使用ajax
    $.ajax({
        method:"post",
        url:"/xxx",
        data:"username=mtt&password=1",
        dataType:'json'//预期服务器返回的数据类型,如果不写,就是响应里设置的
    }
    ).then(success,fail)//$.ajax()返回一个promise
})

用promise封装函数的通用模板

function xxx(){
    return new Promise((f1, f2) => {
        doSomething()
        setTimeout(()=>{
            // 成功就调用 f1,失败就调用 f2
        },3000)
    })
}

xxx().then(success, fail)

// 链式操作
xxx().then(success, fail).then(success, fail)

六、浏览器渲染页面的过程,以及重绘和重排

回流
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。

重绘
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

注意
回流必将引起重绘,而重绘不一定会引起回流。执行顺序:先回流后重绘。

回流何时发生:

当页面布局和几何属性改变时就需要回流。下述情况会发生浏览器回流:

1、添加或者删除可见的DOM元素;

2、元素位置改变;

3、元素尺寸改变——边距、填充、边框、宽度和高度

4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;

5、页面渲染初始化;

6、浏览器窗口尺寸改变——resize事件发生时;

减少回流、重绘

(1) 避免操作DOM,创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。也可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。
(2) 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于render tree中。如读取offsetLeft等属性。
(3) 尽可能在DOM树的末端改变class ,尽可能在DOM树的里面改变class,可以限制回流的范围,使其影响尽可能少的节点。
(4) 避免设置多层内联样式,因为每一个都会造成回流,样式合并在一个外部类,这样当该元素的class属性被操作时,只会产生一个reflow。
(5) 将需要多次回流的元素position属性设为absolute或fixed,这样该元素就会脱离文档流,它的变化不会影响其他元素变化。比如动画效果应用到position属性为absolute或fixed的元素上。
(6) 牺牲平滑度换取速度,动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动
(7) 避免使用table布局,在布局完全建立之前,table需要很多关口,table是可以影响之前已经进入的DOM元素的显示的元素。即使一些小的变化和会导致table中所有其他节点回流。
(8) 避免使用css的JavaScript表达式,该规则较过时,但是个好主意。因为每次都需要重新计算文档,或部分文档、回流。

七、XMLHTTPRequest和JSONP的应用场景,以及其分别如何检测请求错误的

XMLHttpRequest
用于浏览器端与服务器端异步请求数据,实现对页面的无刷新修改,支持GET/POST请求,一般用于非跨域的场景。如果需要使用XMLHttpRequest跨域请求数据,需要通过CORS头支持。

JSONP
用于跨域请求数据的场景,只支持GET请求。jsonp的核心原理就是目标页面回调本地页面的方法,并带入参数。JSONP 全称是 JSON with Padding,JSONP可能会引起CSRF(Cross-site request forgery 跨站请求伪造)攻击或XSS (Cross Site Scripting 跨站脚本攻击)漏洞。输出 JSON 时,没有严格定义好 Content-Type(Content-Type: application/json)直接导致了一个典型的 XSS 漏洞。对于支持JSONP的接口,写接口时数据可能会被篡改,读接口时数据可能会被劫持。

主要解决方案:
a.Referer 严谨过滤
b.严格定义输出的 Content-Type: application/json,浏览器不解析恶意插入的 XSS 代码(直接访问提示文件下载)
c.部署一次性 Token
d.限制callback函数名长度,严格过滤callback函数名
e.过滤JSON里数据的输出

异常判断

XMLHttpRequest:一般通过该对象的readystate和http状态码status来判断。
JSONP:一般是onerror事件和超时timer来判断。

Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值