解釋 css 各類定位,absolute 相對於誰定位;
-> position: relative/absolute/fixed/static/inherit/initial/unset/sticky
-> 相對於最近一層position非static的父元素
-> relative不會脫離文檔流javascript
iframe 中的 fixed 定位和什麼有關,怎麼固定瀏覽器窗口
-> iframe窗口非瀏覽器窗口,經過postmessage通訊將top頁面的scrolltop傳遞給iframe,iframe內部經過監聽通信事件動態設置元素的定css
transfrom 的主要用法
-> transform用來向元素應用各類2D和3D轉換,該屬性容許咱們對元素進行旋轉、縮放、移動或傾斜等操做,有translate, scale, rotate, skew,html
flex 盒子佈局
flex 佈局詳解前端
// 1. padding 補償 .parent { width: 100%; overflow: hidden; } .left, right { float: left; padding-bottom:9999px; margin-bottom:-9999px; } // 2. flex 佈局 .parent{ display: flex; }
css 盒模型;
-> 標準盒子模型:寬度=內容的寬度(content)+ border + padding + margin -> box-sizing:content-box;
-> 低版本IE盒子模型:寬度=內容寬度(content+border+padding)+ margin -> box-sizing:border-box;;vue
重繪和迴流的區別
-> 重繪(repaint):當render tree中的一些元素須要更新屬性,單這些屬性只會影響元素的外觀,風格,而不會影響到元素的佈局,此類的頁面渲染叫做頁面重繪。
-> 迴流(reflow):當render tree中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而引發的頁面從新渲染。
-> 迴流必將引發重繪,而重繪不必定會引發迴流java
如何解決外邊距重合問題;
-> 外邊距重疊是指兩個或多個盒子(可能相鄰也可能嵌套)的相鄰邊界(其間沒有任何非空內容、補白、邊框)重合在一塊兒而造成一個單一邊界
外層元素添加padding;
外層元素 overflow:hidden;
外層元素透明邊框 border:1px solid transparent;
內層元素絕對定位 postion:absolute;
內層元素 加float:left;或display:inline-block;node
清除浮動
一、父級div定義 overflow: auto;
;
二、.clearfixreact
// 1. float+margin(一側定寬,一側自動) // 2. position+margin(一側定寬,一側自動) // 3. float+負margin(一側定寬,一側自動) .right { float:left; width: 100%; } .right .cont { margin-left:200px; } .left { float: left; width: 200px; margin-left: -100%; }
// 1. float+margin(兩側定寬,中間自適應) // 2. position+margin(兩側定寬,中間自適應) // 3. float+負margin(兩側定寬,中間自適應) .m-box { float:left; width: 100%; } .m-box .center { margin:0 200px; } .left,.right { float: left; width: 200px; margin-left: -100%; } .right { margin-left: -200px; }
// 一、絕對定位+margin:auto .box { margin: auto; position: absolute; left: 0; right: 0; top: 0; bottom: 0; } // 二、絕對定位+transform反向偏移 .box { margin: auto; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } // 三、display: flex-box .box { display: flex; align-items: center; justify-content: center; }
.box { width: 100%; height: 0; padding-top: 75%; }
.ig{ -webkit-animation:circle 1.5s infinite linear; } @-webkit-keyframes circle{ 0%{ transform:rotate(0deg); } 100%{ transform:rotate(360deg); } }
.triangle{ width: 0; height:0; border: 10px solid transparent; border-top-color: red; }
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no">
(1) 在js腳本中把對應的方法名,參數等寫成一個符合協議的uri,而且經過window.prompt方法發送給java層。jquery
(2) 在java層的onJsPrompt方法中接受到對應的message以後,經過JsCallJava類進行具體的解析。webpack
(3) 在JsCallJava類中,咱們解析獲得對應的方法名,參數等信息,而且在map中查找出對應的類的方法。
// 時間複雜度(nlogn), 空間複雜度O(n) var quickSort = function(arr) { if(arr.length<=1) return arr; var left = [], right = [], point = Math.floor(arr.length/2); var middle = arr.splice(point, 1)[0]; for(var i = 0; i < arr.length; i++){ arr[i] < middle ? left.push(arr[i]) : right.push(arr[i]) ; } return quickSort(left).concat([middle], quickSort(right)); }
a.forEach(function(value, index){ b.indexOf(value) === -1 && b.push(value); }) a.map(function(value, index){ b.indexOf(value) === -1 && b.push(value); }) var c; c = a.filter(function(value, index, array){ return index === array.indexOf(value); }) function unique(arr) { var ret = []; var tmp = {}; for(var i = 0, len = arr.length; i < len; i++){ if(!tmp[typeof arr[i] + arr[i]]) { tmp[typeof arr[i] + arr[i]] = true; ret.push(arr[i]); } } return ret; }
一、 var myNewArray = [].concat.apply([], myArray); 二、 var myNewArray4 = [].concat(...myArray); 三、 var myNewArray = myArray.reduce(function(prev, curr) { return prev.concat(curr); });
// 參照 vue 源碼實現 var EventEmiter = function (){ this._events = {}; }; EventEmiter.prototype.on = function (event, cb){ if (Array.isArray(event)){ for (let i = 0, l = event.length; i < l; i++){ this.on(event[i], cb); } } else { (this._events[event] || (this._events[event] = [])).push(cb); } return this; }; EventEmiter.prototype.once = function (event, cb){ function on () { this.off(event, cb); cb.apply(this, arguments); } on.fn = cb; this.on(event, on); return this; }; EventEmiter.prototype.off = function (event, cb){ if (!arguments.length){ this._events = Object.create(null); return this; } if (Array.isArray(event)){ for (let i = 0, l = event.length; i < l; i++){ this.off(event[i],cb); } return this; } if (!cb){ this._events[event] = null; return this; } if (cb){ let cbs = this._events[event]; let i = cbs.length; while(i--){ if (cb === cbs[i] || cb === cbs[i].fn){ cbs.splice(i, 1); break; } } return this; } }; EventEmiter.prototype.emit = function (event){ let cbs = this._events[event]; let args = Array.prototype.slice.call(arguments, 1); if (cbs){ for (let i = 0, l = cbs.length; i < l; i++){ cbs[i].apply(this,args); } } };
function parseUrl(url){ var result = []; var query = url.split("?")[1]; var queryArr = query.split("&"); queryArr.forEach(function(item){ var obj = {}; var value = item.split("=")[1]; var key = item.split("=")[0]; obj[key] = value; result.push(obj); }); return result; }
// 使用的是選擇排序 const versionSort = version => { const temp = version.map(v => v.split('.')); for (let i = 0; i < temp.length; i++) { let minIndex = i; for (let j = i; j < temp.length; j++) { for (let k = 0; k < temp[j].length; k++) { const current = +temp[j][k], min = +temp[minIndex][k]; if (current < min) { minIndex = j; } // 只要不等,就馬上結束最內層遍歷! if (current !== min) { break } } } [temp[i], temp[minIndex]] = [temp[minIndex], temp[i]]; } return temp.map(v = > v.join('.')) };
隨意給定一個無序的、不重複的數組arr,任意抽取n個數,相加和爲sum,也可能無解,請寫出該函數。
function debounce(fn, interval, immediate) { let timer; return function() { const context = this; const args = arguments; timer && clearTimeout(timer); if(immediate) { var callNow = !timer; timer = setTimeout(function() { timer = null; }, interval); callNow && fn.apply(context, args); } else { timer = setTimeout(function() { fn.apply(context, args); }, interval); } } }
Function.prototype.bind = function(ctx) { var self = this; var args = Array.prototype.slice.call(arguments, 1); var F = function() {}; var fBind = function() { var argsBind = Array.prototype.slice.call(arguments); return self.apply(this instanceof F ? this : ctx, args.concat(argsBind)); } F.prototype = this.prototype; fBind.prototype = new F(); return fBind; }
promise封裝;
簡單的 Promise
function parseInt(s, radix = 10) { if (typeof s !== 'string') { return NaN; } if (typeof radix !== 'number' || radix < 2 || radix > 36) { return NaN; } let result = 0; for (let i = 0; i < s.length; i += 1) { let c = s.charCodeAt(i); // 小寫大寫字母轉換爲數字 if (c >= 97) { c -= 87; // - 'a' + 10 } else if (c >= 65) { c -= 55; // - 'A' + 10 } else { c -= 48; // - '0' } // 若是字母轉化後的值大於進制數,則跳出循環返回以前的結果 if (c >= radix) { if (i === 0) { return NaN; } break; } // 結果累加,和進制相關 result = (result * radix) + c; } return result; }
function comma(num) { var source = String(num).split("."); source[0] = source[0].replace(new RegExp('(\\d)(?=(\\d{3})+$)','ig'),"$1,"); return source.join("."); }
請使用數組的reduce方法實現數組的map方法;
function sumStrings(a,b) { while(a.length < b.length){ a = "0" + a; } while(b.length < a.length){ b = "0" + b; } var addOne = 0; var result = []; for(var i=a.length-1;i>=0;i--){ var c1 = a.charAt(i) - 0; var c2 = b.charAt(i) - 0; var sum = c1 + c2 + addOne; if(sum > 9){ result.unshift(sum - 10); addOne = 1; } else{ result.unshift(sum); addOne = 0; } } if(addOne){ result.unshift(addOne); } if(!result[0]){ result.splice(0,1); } return result.join(""); }
a instanceof Array; a.constructor === Array; a.__proto__ === Array.prototype; Array.prototype.isPrototypeOf(a); // isProtoTypeOf() Object.getPrototypeOf(a) === Array.prototype; // Object.getPrototypeOf() Object.prototype.toString.call(a) === '[object Array]'; // 首推 -> 前幾種繼承會擾亂, iframe 下 instance 失效 Array.isArray() // polyfill 就是調用字符串判斷法 var argsArray = Array.prototype.slice.call(arguments);
xss和csrf攻擊;
-> xss 跨站腳本攻擊,主要是前端層面的,用戶在輸入層面插入攻擊腳本,改變頁面的顯示,或則竊取網站 cookie,預防方法:不相信用戶的全部操做,對用戶輸入進行一個轉義,不容許 js 對 cookie 的讀寫
-> csrf 跨站請求僞造,以你的名義,發送惡意請求,經過 cookie 加參數等形式過濾
咱們無法完全杜絕攻擊,只能提升攻擊門檻
cookie的有哪些安全的設置;