1、css實(shí)現(xiàn)圖片自適應(yīng)寬高
主要使用padding-bottom,該屬性是基于父元素寬度百分比的;
<div style="width:100px;height:100px;">
<img src="" style="width:100%;padding:100%" />
</div>
2、什么是BFC?
BFC 全稱為 塊級格式化上下文 (Block Formatting Context)
BFC 特性(功能)
- 使 BFC 內(nèi)部浮動元素不會到處亂跑;
- 和浮動元素產(chǎn)生邊界。
一個塊格式化上下文由以下之一創(chuàng)建:
- 根元素或其它包含它的元素
- 浮動元素 (元素的 float 不是 none)
- 絕對定位元素 (元素具有 position 為 absolute 或 fixed)
- 內(nèi)聯(lián)塊 (元素具有 display: inline-block)
- 表格單元格 (元素具有 display: table-cell,HTML表格單元格默認(rèn)屬性)
- 表格標(biāo)題 (元素具有 display: table-caption, HTML表格標(biāo)題默認(rèn)屬性)
- 具有overflow 且值不是 visible 的塊元素,
- display: flow-root
- column-span: all 應(yīng)當(dāng)總是會創(chuàng)建一個新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一個多列容器中。
- 一個塊格式化上下文包括創(chuàng)建它的元素內(nèi)部所有內(nèi)容,除了被包含于創(chuàng)建新的塊級格式化上下文的后代元素內(nèi)的元素。
http://www.itdecent.cn/p/0d713b32cd0d
3、項(xiàng)目里面的前端鑒權(quán)是怎么實(shí)現(xiàn)的?
1、session-cookie
將登錄的用戶名和密碼發(fā)送給后端,后端生成session,然后保存session生成唯一標(biāo)識字符串,在響應(yīng)頭種下這個唯一標(biāo)識字符串,返回給前端,前端將唯一標(biāo)識字符串保存到cookie中,下次再發(fā)送http請求時帶上該域名下的cookie信息,服務(wù)端解析請求頭cookie中的唯一標(biāo)識,然后根據(jù)唯一標(biāo)識查找保存該客戶端的session,并判斷是否合法。
2、token
客戶端使用用戶名和密碼登錄,服務(wù)端接受請求,驗(yàn)證用戶名和密碼,驗(yàn)證成功后,簽發(fā)一個token,發(fā)送給客戶端,客戶端收到token后保存起來,以后每次請求都帶上簽發(fā)的token
3、OAuth(開放授權(quán))
支付寶、微信、QQ登錄
4、vue里面的虛擬dom是怎么回事?
因?yàn)閖avascript的dom操作是很影響性能的,所以要盡量減少js和dom的交互,虛擬dom就是為了解決這種交互而設(shè)計(jì)的,虛擬dom通過樹的形式保存dom信息,當(dāng)檢測到數(shù)據(jù)更新,需要更新dom,先將js中需要修改的節(jié)點(diǎn)全部修改完成,最終將生成的虛擬dom更新到視圖中去。代價是需要在內(nèi)存中保存一份可供維護(hù)的數(shù)據(jù)信息。
5、vue雙向綁定講一講
vue實(shí)現(xiàn)雙向數(shù)據(jù)綁定主要采用數(shù)據(jù)劫持和發(fā)布訂閱結(jié)合的方式。
數(shù)據(jù)劫持就是利用Object.defineProperty()這個方法重新定義了對象獲取屬性值(get)和設(shè)置屬性值(set)的操作實(shí)現(xiàn)的。
發(fā)布訂閱需要Observer監(jiān)聽器(用來監(jiān)聽屬性的變化通知訂閱者)、Watcher訂閱者(收到屬性變化,然后更新視圖)、Compile解析器(解析指令、初始化模板、綁定訂閱者)
代碼演示:
var obj = {}
var name;
//第一個參數(shù):定義屬性的對象。//第二個參數(shù):要定義或修改的屬性的名稱。//第三個參數(shù):將被定義或修改的屬性描述符。
Object.defineProperty(obj, "data", {
//獲取值
get: function () {
return name;
},
//設(shè)置值
set: function (val) {
name = val;
console.log(val)
}
})
6、手寫函數(shù)防抖和函數(shù)節(jié)流
函數(shù)防抖的應(yīng)用場景
連續(xù)的事件,只需觸發(fā)一次回調(diào)的場景有:
- 搜索框搜索輸入。只需用戶最后一次輸入完,再發(fā)送請求
- 手機(jī)號、郵箱驗(yàn)證輸入檢測
- 窗口大小Resize。只需窗口調(diào)整完成后,計(jì)算窗口大小。防止重復(fù)渲染
函數(shù)節(jié)流的應(yīng)用場景
間隔一段時間執(zhí)行一次回調(diào)的場景有:
- 滾動加載,加載更多或滾到底部監(jiān)聽
- 谷歌搜索框,搜索聯(lián)想功能
- 高頻點(diǎn)擊提交,表單重復(fù)提交
// 函數(shù)防抖
const _.debouce = (func, wait) => {
let timer;
return () => {
cleatTimeout(timer)
timer = setTimeout(func,wait)
}
}
?
// 函數(shù)節(jié)流
const _.throttle = (func, wait) => {
let timer;
return () => {
if(timer){
return;
}
timer = setTimeout(() => {
func();
timer = null;
},wait)
}
}
7、圖片懶加載實(shí)現(xiàn)原理
1、設(shè)置圖片src為同一張默認(rèn)托地圖,同時自定義一個data-src屬性來存儲圖片的真實(shí)地址
2、頁面初始化顯示的時候或者瀏覽器發(fā)生滾動的時候判斷圖片是否在視野中
3、當(dāng)圖片在視野中,通過js自動改變該區(qū)域圖片的src屬性為真實(shí)圖片地址
8、跨域有哪些處理方式
1、通過jsonp跨域
2、跨域資源共享(CORS)
3、nodejs中間件代理跨域
4、ngnix反向代理中設(shè)置proxy_cookie_domain
9、說說對閉包的認(rèn)識
一句話解釋:能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。函數(shù)作為參數(shù)傳遞和函數(shù)作為返回值而已形成閉包。
在js中變量的作用域?qū)儆诤瘮?shù)作用域,在函數(shù)執(zhí)行完成后。作用域就會被清理,內(nèi)存也會隨之被回收,但是由于閉包函數(shù)是建立在函數(shù)內(nèi)部的子函數(shù),由于其可以訪問上級作用域,即使上級函數(shù)執(zhí)行完,作用域也不會隨之銷毀,這時的子函數(shù)便擁有了訪問上級函數(shù)作用域變量的權(quán)限,即使上級函數(shù)執(zhí)行完后作用域內(nèi)的值也不會被銷毀。
10、數(shù)組常用方法有哪些
改變數(shù)組方法
1、splice() 添加/刪除數(shù)組元素
let a = [1, 2, 3, 4, 5, 6, 7];
let item = a.splice(0, 3); // [1,2,3]
console.log(a); // [4,5,6,7]
// 從數(shù)組下標(biāo)0開始,刪除3個元素
let item1 = a.splice(0,3,'添加'); // [4,5,6]
console.log(a); // ['添加',7]
// 從數(shù)組下標(biāo)0開始,刪除3個元素,并添加元素'添加'
2、sort() 數(shù)組排序
var array = [10, 1, 3, 4,20,4,25,8]
// 升序 a-b < 0 a將排到b的前面,按照a的大小來排序
array,sort(function(a, b){
return a-b
})
console.log(array) // [1,3,4,4,8,10,20,25];
// 降序
array.sort(function(a,b){
return b-a
})
console.log(array) // [25,20,10,8,4,4,3,1];
3、pop() 刪除數(shù)組中最后一個元素
4、push() 向數(shù)組的末尾添加一個元素
5、shift() 刪除數(shù)組的第一個元素
6、unshift() 向數(shù)組開頭添加元素
7、reverse() 翻轉(zhuǎn)數(shù)組
8、ES6: copyWithin() 指定位置的成員復(fù)制到其他位置
9、ES6
// 數(shù)組求和
let sum = [0, 1, 2, 3].reduce(
function (a, b) {
return a + b;
}, 0);
// 6
// 將二維數(shù)組轉(zhuǎn)化為一維 將數(shù)組元素展開
let flattened = [[0, 1], [2, 3], [4, 5]].reduce( (a, b) => a.concat(b), [] );
// [0, 1, 2, 3, 4, 5]
10、fill() 填充數(shù)組
不改變數(shù)組的方法
1、join() 數(shù)組轉(zhuǎn)字符串
2、concat() 合并兩個或多個數(shù)組
3、ES6擴(kuò)展運(yùn)算符…合并數(shù)組
4、indexOf() 查找數(shù)組是否存在某個元素,返回下標(biāo)
5、ES7 includes() 查找數(shù)組是否包含某個元素 返回布爾
6、slice() 淺拷貝數(shù)組
let a = [{name: 'zhangsan'}, {name: 'lisi'}]
let b = a.slice(0,1);
console.log(b, a);
// [{name: 'zhangsan'}] [{name: 'zhangsan'}, {name: 'lisi'}]
a[0].name = '改變數(shù)組';
console.log(b, a)
// [{"name":"改變原數(shù)組"}] [{"name":"改變原數(shù)組"}, {name: 'lisi'}]
遍歷方法
1、forEach
2、every 檢測數(shù)組所有元素是否符合判斷條件,如果有一個元素不滿足在,則整個表達(dá)式返回false,且元素不會再進(jìn)行檢測
3、some 檢測數(shù)組中是否有滿足條件的判斷,如有有一個元素滿足條件,則表達(dá)式返回true,剩余元素不會再執(zhí)行檢測
4、filter 過濾原始數(shù)組,返回新數(shù)組
5、reduce 為數(shù)組提供累加器,合并為一個值
// 數(shù)組求和
let sum = [0, 1, 2, 3].reduce(function (a, b) { return a + b; }, 0); // 6
// 將二維數(shù)組轉(zhuǎn)化為一維 將數(shù)組元素展開
let flattened = [[0, 1], [2, 3], [4, 5]].reduce( (a, b) => a.concat(b), [] );
// [0, 1, 2, 3, 4, 5]
6、ES6 find() & findIndex() 根據(jù)條件找到數(shù)組成員 這兩鐘方法都可以識別NaN,彌補(bǔ)了indexOf的不足
[1, 4, -5, 10,NaN].find((n) => Object.is(NaN, n));
// 返回元素NaN
[1, 4, -5, 10].findIndex((n) => n < 0);
// 返回索引2
7、ES6 keys() & values() & entries() 遍歷鍵名、遍歷鍵值、遍歷鍵名+鍵值
for (let index of ['a', 'b'].keys()) { console.log(index); } // 0
// 1
for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a"
// 1 "b"
11、怎么判斷一個Object是數(shù)組
- 使用Object.prototype.toString 來判斷是否是數(shù)組
- 使用原型鏈來完成判斷
function isArray(obj){
return obj.proto === Array.prototype;
} - ES6 Array.isArray()
12、繼承有哪些方式
- ES6得class繼承
- 原型繼承
- 構(gòu)造繼承
- 寄生組合式繼承
- 實(shí)例繼承
13、call、apply、bind之間的關(guān)系
apply和call
- 二者都是Function對象上的方法,每個函數(shù)都能調(diào)用
- 二者的第一個參數(shù)都是你要指定執(zhí)行的上下文
- 最終都會轉(zhuǎn)換成一個一個參數(shù)的執(zhí)行,故call比apply運(yùn)行效率高
- 區(qū)別是:call方法接受的是若干個參數(shù)列表,而apply接受的是一個包含多個參數(shù)的數(shù)組
var a = {
name: 'cherry',
fn: function (a, b) {
console.log(a + b)
}
}
var b = a.fn
b.apply(a, [1, 2]) // 3
b.call(a, 4, 5, 6) // 15
b.bind(a, 1, 2)() // 3
bind 與apply、call區(qū)別
bind()是強(qiáng)綁定,只要傳進(jìn)去了context,則bind中return出來的的函數(shù)this便一直指向context,除非context是個變量;因?yàn)閎ind會return一個新函數(shù),故此需要二次執(zhí)行。
apply、call是顯示綁定,立即執(zhí)行
14、Promise
所謂promise,簡單說就是一個容器,里面保存著某個未來才會結(jié)束的事件的結(jié)果。從語法上說,promise是一個對象,從它可以獲取異步操作的消息。Promise提供統(tǒng)一的Api,各種異步操作都可以用同樣的方法處理,讓開發(fā)者不用再關(guān)注時序和底層的結(jié)果。Promise的狀態(tài)具有不受外界影響和不可逆兩個特點(diǎn)。
promise解決了什么問題?
Promise解決了回調(diào)地獄的問題,提高代碼可讀性以及解決信任度問題
promise在事件循環(huán)中的執(zhí)行過程是怎樣的
var promise = new Promise((resolve, reject) => {
console.log('我是promise任務(wù)')
resolve('resolved')
})
promise.then(res => {
console.log(res)
})
console.log('我是同步任務(wù)')
setTimeout(() => {
console.log('我是延時任務(wù)')
})
// 上面代碼的執(zhí)行順序是: 我是promise任務(wù)、我是同步任務(wù)、resolved、我是延時任務(wù)。
Promise新建后立即執(zhí)行,立即resolve的Promise對象,是在本輪”事件循環(huán)”(event loop)的結(jié)束時,而不是在下一輪”事件循環(huán)”的開始時;setTimeout在下一輪”事件循環(huán)”開始時執(zhí)行。
15、Vue-router的原理
vue-router是通過hash和History interface兩種方式實(shí)現(xiàn)前端路由,更新視圖但不重新請求頁面,在vue-router中,mode參數(shù)決定采用哪一種方式來實(shí)現(xiàn)路由跳轉(zhuǎn)。
mode參數(shù):
- 默認(rèn)hash
- history(注:如果瀏覽器不支持history新特性,則采用hash方式)
- 如果不在瀏覽器環(huán)境中則使用abstract(node環(huán)境下)
當(dāng)你選擇了mode類型之后,程序會根據(jù)你選擇的mode類型創(chuàng)建不同的history對象(HashHistory或HTML5History或AbstractHistory)
HashHistory替換路由有兩種方式:HashHistory.push() 和 HashHistory.replace()
HashHistory.push() 將新路由添加到瀏覽器訪問歷史的棧項(xiàng)
- $router.push() // 調(diào)用方法
- HashHistory.push() // 根據(jù)Hash模式調(diào)用,設(shè)置hash并添加到瀏覽器歷史記錄(添加到棧項(xiàng))(window.location.hash = xxx)
- History.transitonTo() // 監(jiān)測更新,更新則調(diào)用History.updateRoute()
- History.updateRoute() // 更新路由
- {app._route = route} // 替換當(dāng)前app路由
- vm.render() // 更新視圖
HashHistory.replace
replace() 方法與push()方法不同之處在于,它并不是將新路由添加到瀏覽器訪問歷史的棧項(xiàng),而是替換當(dāng)前路由
HTML5History替換路由兩種方式:pushState()和replaceState()
window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)
異同:
- pushState設(shè)置新的URL可以是與當(dāng)前URL同源的任意URL;而hash只能修改#后面的部分,故只可以設(shè)置與當(dāng)前同文檔的URL
- pushState通過stateObject可以添加任意類型的數(shù)據(jù)到記錄中,而hash只可添加短字符串
- pushState可以額外設(shè)置title屬性供后續(xù)使用
- history模式會將url修改的和正常請求后端的url一樣,如果后端沒有配置對應(yīng)的(/user/id)路由處理,則會返回404錯誤
16、左邊定寬,右邊自適應(yīng)方案:float + margin , float + calc
// 方案一
.left{
width: 120px;
float: left;
}
.right{
margin-left: 120px;
}
// 方案二
.left{
width: 120px;
float: left;
}
.right{
width: calc(100% - 120px);
float: left;
}
17、左右兩邊定寬,中間自適應(yīng):float,float + calc,flex,圣杯布局(設(shè)置BFC,margin負(fù)值法)
.wrap{
width: 100%;
height:200px;
}
.wrap > div{
height: 100%;
}
// 方案1
.left{
width: 120px;
float: left;
}
.right{
width: 120px;
float: right;
}
.center{
margin: 0 120px;
}
// 方案2
.left{
width: 120px;
float: left;
}
.right{
float: right;
width: 120px;
}
.center{
width: calc(100% -240px);
margin-left: 120px;
}
// 方案3
.wrap{
display: flex;
}
.left{
width: 120px;
}
.right{
width: 120px;
}
.center{
flex: 1;
}
18、Vue和React的區(qū)別
- 相同點(diǎn):都支持ssr,都有Vdom,組件化開發(fā),實(shí)現(xiàn)webComponents規(guī)范,數(shù)據(jù)驅(qū)動等
- 不同點(diǎn):Vue是雙向數(shù)據(jù)流,react是單項(xiàng)數(shù)據(jù)流。vue的vdom是追蹤每個組件的依賴關(guān)系,不會渲染整個組件樹,react每當(dāng)狀態(tài)改變時,全部子組件都會重新render
19、XSS和CSRF
- XSS:跨站腳本攻擊,代碼注入的一種,常見方式是將惡意代碼注入合法代碼里隱藏起來,再誘發(fā)惡意代碼。防范:所有的用戶輸入做過濾和轉(zhuǎn)譯
- CSRF:跨站請求偽造,是在用戶已登錄的web應(yīng)用程序上執(zhí)行非本意的操作攻擊。防范:驗(yàn)證碼,額外驗(yàn)證機(jī)制(token)
20、computed和methods的區(qū)別
- computed是屬性調(diào)用,methods是函數(shù)調(diào)用
- computed帶有緩存功能,methods沒有
21、$nextTick
定義:在下次DOM更新結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新之后的DOM
應(yīng)用場景:需要在視圖更新之后,基于新的視圖進(jìn)行操作。(點(diǎn)擊按鈕使輸入框展示出來,同時獲取焦點(diǎn))
22、如何實(shí)現(xiàn)左邊兩欄一定比例,左欄高度隨右欄高度自適應(yīng)?
關(guān)鍵點(diǎn):margin-bottom: -10000px; padding-bottom: 10000px;
.container {
overflow: hidden;
width: 400px;
}
.container .left,
.container .right {
float: left;
margin-bottom: -10000px;
padding-bottom: 10000px;
}
.container .left {
width: 20%;
background: pink;
}
.container .right {
width: 80%;
background: deeppink;
}
23、什么是深拷貝和淺拷貝
對于基本數(shù)據(jù)類型來說,直接創(chuàng)建一個變量的副本,即為深拷貝
對引用類型來說,淺拷貝指向某個對象的指針,而不復(fù)制對象,新舊對象共用一塊內(nèi)存;
深拷貝是復(fù)制一個一模一樣的對象,不共享內(nèi)存,修改新對象,舊對象保持不變;
深拷貝實(shí)現(xiàn)方式:
- JSON.Stringify和JSON.parse
- 遞歸實(shí)現(xiàn)
- Jquery的extend()
深拷貝的兩種實(shí)現(xiàn)方式:
// 方式一
let o1 = {
a:{
b: 1
}
}
let o2 = JSON.parse(JSON.stringfy(o1))
?
// 方式二
function deepCopy(s){
const d = Array.isArray(s) ? [] : {}
for(let key in s){
if(typeof s[key] == 'Object'){
d[key] = deepCopy(s[key])
}else{
d[key] = s[key]
}
}
return d
}
24、js中數(shù)據(jù)類型的判斷
1、typeof
數(shù)字 Number、布爾值Boolean、字符串String、函數(shù)Function、對象Object、Undefined可以被解釋,但數(shù)組和null判斷的不準(zhǔn)確
2、instanceof
引用數(shù)據(jù)類型Array、Function、Object可以被準(zhǔn)確判斷,Number、Boolean、String不能準(zhǔn)確判斷
3、constructor
本可以判斷,然而一旦將函數(shù)的prototype重新賦值,則會輕易更改constructor
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true
4、Object.prototype.toString.call()
25、數(shù)組去重
- ES5方式
function unique(arr){
const temp = []
arr.forEach(e => {
if(temp.indexOf(e) == -1){
temp.push(e)
}
})
return temp
}
- ES6方式
function unique(arr){
return Array.from(new Set(arr))
}
26、獲取地址欄參數(shù)信息
function getQueryString(name){
let reg = new RegExp('(^|&)' + name + ='([^&]*)(&|$)','i')
let r = window.location.search.substr(1).macth(reg)
if(r !== null){
return unescape(r[2])
}
return ''
}
27、不同情況調(diào)用,this分別指向如何
- 由new調(diào)用則綁定到新創(chuàng)建的對象
- 由call、apply或bind調(diào)用,綁定到指定的對象
- 由上下文調(diào)用,綁定到上下文對象
- 不符合上述規(guī)則,指向全局對象,瀏覽器環(huán)境下是window,嚴(yán)格模式下是undefiend
- 如果是ES6的箭頭函數(shù),this指向它被創(chuàng)建的上下文
28、http1.1跟http1.0比新特性
1.1版本最大的變化就是引入了持久化連接,即TCP連接默認(rèn)不關(guān)閉,可以被多個請求復(fù)用,不用聲明Connection:keep-alive,
1.1版本還引入了管道機(jī)制,即在同一個TCP連接里面,客戶端可以同時發(fā)送多個請求。
還增加了許多動詞方法:put、pacth、options、delete
另外還增加了host字段,用來指定服務(wù)器域名
29、http狀態(tài)碼
1、2xx 成功
204:請求發(fā)送成功,但無任何響應(yīng)內(nèi)容
2、3xx 重定向
301:永久性重定向 所請求的資源/網(wǎng)頁已經(jīng)被分配了新的URL,搜索引擎在抓取新內(nèi)容的同時也將舊網(wǎng)址交換為重定向后的新網(wǎng)址
302:臨時重定向 臨時從舊地址A跳轉(zhuǎn)到B,搜索引擎會抓取新的內(nèi)容而保存舊的地址
3、4xx 客戶端錯誤
400:請求報(bào)文中存在語法錯誤
401:未授權(quán),需要進(jìn)行身份驗(yàn)證,如果是需要登錄的網(wǎng)頁,服務(wù)端可能返回此響應(yīng)
403:服務(wù)器拒絕請求
404:服務(wù)器上無法找到該資源
4、5xx 服務(wù)端錯誤
500:服務(wù)器內(nèi)部錯誤
501:服務(wù)器無法識別請求方法
502:網(wǎng)關(guān)錯誤
503:服務(wù)不可用(超載或停機(jī)維護(hù))
504:網(wǎng)關(guān)超時
30、瀏覽器進(jìn)程下5大線程
GUI渲染線程
js引擎線程
事件觸發(fā)線程
定時器觸發(fā)線程
異步http請求線程
31、捕獲js運(yùn)行時報(bào)錯和跨域資源加載報(bào)錯
js運(yùn)行時報(bào)錯
1、try catch 捕獲錯誤
2、window.onerror
資源加載報(bào)錯
1、Object.onerror
var img = document.getElementById('img')
img.onerror = function(){
// 捕獲錯誤
}
2、window.performance.getEntries()
瀏覽器獲取網(wǎng)頁時,會對網(wǎng)頁中每一個對象(腳本文件、樣式表、圖片文件等)發(fā)出一個Http請求,而通過window.performance.getEntries方法,則可以以數(shù)組形式,返回這些請求的時間統(tǒng)計(jì)信息。
function () {
// 瀏覽器不支持,就算了!
if (!window.performance && !window.performance.getEntries) {
return false;
}
var result = []; // 獲取當(dāng)前頁面所有請求對應(yīng)的PerformanceResourceTiming對象進(jìn)行分析 window.performance.getEntries().forEach((item) => {
result.push({
'url': item.name,
'entryType': item.entryType,
'type': item.initiatorType,
'duration(ms)': item.duration
});
});
// 控制臺輸出統(tǒng)計(jì)結(jié)果
console.table(result);
})();
3、捕獲Error事件
window.addEventListener("error",function(ev){
console.log('捕獲',ev)// 捕獲錯誤
},true);
跨域資源加載報(bào)錯
跨域js文件獲取是有限制的,如果想獲取其他域下的js錯誤需要在script標(biāo)簽里添加crossorigin屬性,然后服務(wù)器端要設(shè)置header(‘Access-Control-Allow-Origin: *’),或者 指定域名。
<script type="text/javascript" src="http://localhost:3000/test/script.js" crossorigin="anonymous"></script>>
32、target和currentTarget區(qū)別
e.target指向觸發(fā)事件監(jiān)聽的對象
e.currentTarget指向添加監(jiān)聽事件的對象
33、flex: 1 集成的是哪三個屬性
flex-grow:定義了元素放大比例,默認(rèn)值0
flex-shrink:定義了元素縮放比例,默認(rèn)值1
flex-basis:在分配多余空間之前,項(xiàng)目占據(jù)主軸的空間。瀏覽器根據(jù)這個屬性,計(jì)算主軸是否有多余空間,默認(rèn)值是auto
34、js獲取dom元素的八種方法
getElementById
getElementByName
getElementByTagName
getElementByClassName
獲取html的方法 document.documentElement
獲取body的方法 document.body
通過選擇器獲取一個元素 querySelector
通過選擇器獲取一組元素 querySelectorAll