在移動端web開發中,UI設計稿中設置邊框爲1像素,前端在開發過程當中若是出現border:1px,測試會發如今某些機型上,1px會比較粗,便是較經典的移動端1px像素問題。javascript
設備像素比dpr = 設備像素 / CSS像素(某一方向上) 能夠經過window.devicePixelRatio獲取設備的dpr值。通常來講,在桌面的瀏覽器中,設備像素比(dpr)等於1,一個css像素就是表明的一個物理像素。而在移動端,大多數機型都不是爲1,其中iphone的dpr廣泛是2和3,那麼一個css像素再也不是對應一個物理像素,而是2個和3個物理像素。即咱們一般在css中設置的width:1px,對應的即是物理像素中的2px。手機機型不一樣,dpr可能不一樣。php
以iphone5爲例,iphone5的CSS像素爲320px568px,DPR是2,因此其設備像素爲640px1136pxcss
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- initial-scale=1.0 縮放比 當爲1的時候沒用進行任何縮放 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>1px物理像素實現(方案一)</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#box {
width: 0.5rem;
height: 0.5rem;
border-bottom: 1px solid #000;
}
</style>
<!-- 像素比 = 物理像素 / css像素 -->
</head>
<body>
<div id="box"></div>
</body>
<script type="text/javascript">
window.onload = function () {
//像素比是什麼?針對不一樣屏幕 dpr不同
var dpr = window.devicePixelRatio;
console.log(dpr);
//縮放比例
var scale = 1 / dpr;
//可視區域的寬度
var width = document.documentElement.clientWidth;
//獲取mate標籤
var metaNode = document.querySelector('meta[name="viewport"]');
metaNode.setAttribute('content',"width=device-width, initial-scale='+scale+'");
//頁面中元素的寬度,高度,比例得反向乘回來
var htmlNode = document.querySelector('html');
htmlNode.style.fontSize = width * dpr + 'px';
}
</script>
</html>
複製代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- initial-scale=1.0 縮放比 當爲1的時候沒用進行任何縮放 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>1px物理像素實現(方案二)</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#box {
width: 200px;
height: 200px;
position: relative;
}
#box:before {
content:'';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background: #000;
}
@media screen and (-webkit-min-device-pixel-ratio:2) {
#box:before {
transform: scaleY(0.5);
}
}
@media screen and (-webkit-min-device-pixel-ratio:3) {
#box:before {
transform: scaleY(0.333333);
}
}
</style>
</head>
<body>
<div id="box"></div>
</body>
<script type="text/javascript">
window.onload = function () {
}
</script>
</html>
複製代碼
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#wrap {
width: 100px;
height: 100px;
background:grey;
position: relative;
}
#wrap .box {
width: 50px;
height: 50px;
background:pink;
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
複製代碼
<style type="text/css">
#wrap {
width: 100px;
height: 100px;
background:grey;
position: relative;
}
#wrap .box {
width: 50px;
height: 50px;
background:pink;
position: absolute;
top:50%;
left: 50%;
margin-left:-25px;
margin-top:-25px;
}
</style>
複製代碼
<style type="text/css">
#wrap {
width: 100px;
height: 100px;
background:grey;
position: relative;
}
#wrap .box {
width: 50px;
height: 50px;
background:pink;
position: absolute;
top:50%;
left: 50%;
transform: translate(-50% , -50%);
}
</style>
複製代碼
<style type="text/css">
#wrap {
width: 100px;
height: 100px;
background:grey;
display: flex;
justify-content: center;
align-items: center;
}
#wrap .box {
width: 50px;
height: 50px;
background:pink;
}
</style>
複製代碼
<style type="text/css">
#wrap {
width: 100px;
height: 100px;
background:grey;
display: -webkit-box;
-webkit-box-pack:center;
-webkit-box-align: center;
}
#wrap .box {
width: 50px;
height: 50px;
background:pink;
}
</style>
複製代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>rem適配</title>
<style type="text/css">
#wrap {
width: 0.5rem;
height: 0.5rem;
background:grey;
}
/* html 根元素字體大小設置屏幕區域的寬度 */
</style>
</head>
<body>
<div id="wrap">
<div class="box"></div>
</div>
</body>
<script type="text/javascript">
window.onload = function () {
//獲取屏幕區域的寬度
var width = document.documentElement.clientWidth;
//獲取html
var htmlNode = document.querySelector('html');
//設置字體大小
htmlNode.style.fontSize = width + 'px';
}
</script>
</html>
複製代碼
www.cnblogs.com/wangzhenyu6…html
跨域,指的是瀏覽器不能執行其餘網站的腳本。它是由瀏覽器的同源策略形成的,是瀏覽器施加的安全限制。前端
- ——是瀏覽器安全策略
- ——協議名、域名、端口號必須徹底一致
- 舉例:
複製代碼
http://www.123.com/index.html 調用 http://www.123.com/server.php (非跨域)
http://www.123.com/index.html 調用 http://www.456.com/server.php (主域名不一樣:123/456,跨域)
http://abc.123.com/index.html 調用 http://def.123.com/server.php (子域名不一樣:abc/def,跨域)
http://www.123.com:8080/index.html 調用 http://www.123.com:8081/server.php (端口不一樣:8080/8081,跨域)
http://www.123.com/index.html 調用 https://www.123.com/server.php (協議不一樣:http/https,跨域)
請注意:localhost和127.0.0.1雖然都指向本機,但也屬於跨域。
瀏覽器執行javascript腳本時,會檢查這個腳本屬於哪一個頁面,若是不是同源頁面,就不會被執行
複製代碼
- 違背同源策略就會產生跨域
複製代碼
- jsonp cors websocket Node中間件代理(兩次跨域) ngix反向代理...
複製代碼
因此JSONP的原理其實就是利用引入script不限制源的特色,把處理函數名做爲參數傳入,而後返回執行語句,仔細閱讀如下代碼就能夠明白裏面的意思了。vue
補充:1) JSONP和AJAX對比java
JSONP和AJAX相同,都是客戶端向服務器端發送請求,從服務器端獲取數據的方式。但AJAX屬於同源策略,JSONP屬於非同源策略(跨域請求)
複製代碼
2)JSONP優缺點node
SONP優勢是簡單兼容性好,可用於解決主流瀏覽器的跨域數據訪問的問題。缺點是僅支持get方法具備侷限性,不安全可能會遭受XSS攻擊。
複製代碼
<script>
//建立 script 標籤
var script = document.createElement('script');
//設置回調函數
function getData(data) {
//數據請求回來被觸發的函數
console.log(data);
}
//設置script的src屬性,設置請求地址
script.src = 'http://localhost:3000?callback = getData';
//讓script生效
document.body.appendChild(script);
</script>
複製代碼
CORS 須要瀏覽器和後端同時支持。IE 8 和 9 須要經過 XDomainRequest 來實現。 瀏覽器會自動進行 CORS 通訊,實現 CORS 通訊的關鍵是後端。只要後端實現了 CORS,就實現了跨域。 服務端設置 Access-Control-Allow-Origin 就能夠開啓 CORS。 該屬性表示哪些域名能夠訪問資源,若是設置通配符則表示全部網站均可以訪問資源。 雖然設置 CORS 和前端沒什麼關係,可是經過這種方式解決跨域問題的話,會在發送請求時出現兩種狀況,分別爲簡單請求和複雜請求。react
只要同時知足如下兩大條件,就屬於簡單請求jquery
條件1:使用下列方法之一:
條件2:Content-Type 的值僅限於下列三者之一:
請求中的任意 XMLHttpRequestUpload 對象均沒有註冊任何事件監聽器; XMLHttpRequestUpload 對象可使用 XMLHttpRequest.upload 屬性訪問。
Websocket是HTML5的一個持久化的協議,它實現了瀏覽器與服務器的全雙工通訊,同時也是跨域的一種解決方案。WebSocket和HTTP都是應用層協議,都基於 TCP 協議。可是 WebSocket 是一種雙向通訊協議,在創建鏈接以後,WebSocket 的 server 與 client 都能主動向對方發送或接收數據。 同時,WebSocket 在創建鏈接時須要藉助 HTTP 協議,鏈接創建好了以後 client 與 server 之間的雙向通訊就與 HTTP 無關了。 原生WebSocket API使用起來不太方便,咱們使用 Socket.io,它很好地封裝了webSocket接口,提供了更簡單、靈活的接口,也對不支持webSocket的瀏覽器提供了向下兼容。
咱們先來看個例子:本地文件socket.html向 localhost:3000 發生數據和接受數據
// socket.html
<script>
let socket = new WebSocket('ws://localhost:3000');
socket.onopen = function () {
socket.send('我愛你');//向服務器發送數據
}
socket.onmessage = function (e) {
console.log(e.data);//接收服務器返回的數據
}
</script>
複製代碼
// server.js
let express = require('express');
let app = express();
let WebSocket = require('ws');//記得安裝ws
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
ws.on('message', function (data) {
console.log(data);
ws.send('我不愛你')
});
})
複製代碼
總結:CORS支持全部類型的HTTP請求,是跨域HTTP請求的根本解決方案 JSONP只支持GET請求,JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據。 無論是Node中間件代理仍是nginx反向代理,主要是經過同源策略對服務器不加限制。 平常工做中,用得比較多的跨域方案是cors和nginx反向代理
更多方法參考:juejin.im/post/5c2399…
<script>
axios.get('').then(function(){
}).catch(function(){
})
axios.post('').then(function(){
}).catch(function(){
})
</script>
複製代碼
在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是很是常見的需求。儘管咱們能夠在 methods 中輕鬆實現這點,但更好的方式是:methods 只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
爲了解決這個問題, Vue.js 爲 v-on 提供了 事件修飾符。經過由點(.)表示的指令後綴來調用修飾符。
<!-- 阻止單擊事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件再也不重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修飾符能夠串聯 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件偵聽器時使用事件捕獲模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只當事件在該元素自己(好比不是子元素)觸發時觸發回調 -->
<div v-on:click.self="doThat">...</div>
複製代碼
使用修飾符時,順序很重要;相應的代碼會以一樣的順序產生。所以,用 @click.prevent.self 會阻止全部的點擊,而 @click.self.prevent 只會阻止元素上的點擊。
js中有六種數據類型,包括五種基本數據類型(Number,String,Boolean,Undefined,Null),和一種複雜數據類型(Object)。
先判斷對象屬性的長度是否相等,再判斷每一個屬性的值是否相等
juejin.im/post/5c4169…
在父組件寫入子組件標籤時,給它綁定自定義監聽,給它指定回調函數,在子組件中分發事件,vue提供了$emit('指定時間名',數據),這時候數據就會從子組件傳遞給父組件
複製代碼
<div id="demo">
<input v-model="inputValue" />
<p>{{inputValue}}</p>
<input v-bind:value="inputValue2" v-on:input="inputValue2 = $event.target.value" />
</div>
<script>
var vm = new Vue({
el:"#demo",
data:{
inputValue:'',
inputValue2:''
}
})
</script>
複製代碼
//在router文件的index.js中進行懶加載
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Detail from '@/components/Detail'
function resolveView(view){
return ()=> import(/*webpack chunk name*/`@/components/${view}.vue`)
}
export default new Router({
routes:[
{
path:'/',
name:'HelloWorld',
component: resolveView('HelloWorld')
},
{
path:'/detail',
name:'Detail',
component: resolveView('Detail')
},
]
})
複製代碼
//子組件about.vue
<template>
<div>
<h2>關於插槽</h2>
<slot name="header"></slot> /*具名插槽*/
<slot></slot> /*匿名插槽*/
<slot name="footer" say="hello"></slot> /*say='hello'傳遞的參數*/
</div>
</template>
<script>
export default {
name:'about'
}
</script>
複製代碼
//父組件:helloWorld.vue
<template>
<div>
<About>
<h2>這是HelloWorld組件的內容</h2>
<div slot="footer" slot-scope="aaa">
{{aaa}}這是底部
</div>
<div></div>
<div slot="header" slot-scope="aaa">
{{aaa}}這是頭部
</div>
</About>
</div>
</template>
<script>
import About from '@/componts/About';
export defalut {
name:'HelloWorld',
components:{
About
}
}
</script>
複製代碼
// router/index.js
export default new Router({
routes:[
{
path:'/',
name:'HelloWorld',
component:resolveView('HelloWorld'),
meta:{
keepAlive:true
}
}
]
})
複製代碼
// App.vue
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
</div>
</template>
複製代碼
vue中專門提供了一個方法 nextTick() 用於解決dom的前後執行問題
複製代碼
var myswiper = new Swiper('.swiper-container',{
autoplay:true,
loop:true,
observer:true, //swiper跟子元素髮生變化時,自動初始化
observeParents:true //swiper跟父元素髮生變化時,自動初始化
})
複製代碼
npm install nvm //安裝nvm
nvm ls //查看安裝版本
nvm install v11.0.3 //安裝新的版本
nvm use v.11.0.3 //使用某個版本
複製代碼
if (true) {
const path = require('path');
} else {
const path = require('fs');
}
複製代碼
//錯 不能這樣寫
if (true) {
import a from 'a';
} else {
import b from 'b';
}
複製代碼
一、用戶打開URL連接(域名)
二、瀏覽器查詢的URL的DNS地址(IP地址)
三、DNS服務器查詢到IP以後返回給瀏覽器
四、瀏覽器根據返回的IP地址向web服務器發起請求
5 、web服務器接收請求並處理,以後返回相應的數據(HTML、css、js等信息)給瀏覽器
六、瀏覽器接收到返回的數據以後便開始解析數據過程以下:
a:解析HTML -- 語法分析
B:構建DOM樹
C:解析CSS文件
d:佈局DOM節點
瀏覽器在此過程當中還會遇到一些引用的圖片,此時還會繼續向服務器發出請求,但不會發生阻塞,而是繼續往下執行代碼;固然還有可能會遇到的JavaScript的標籤並執行,此時若是須要發出請求的話,瀏覽器會發生阻塞,知道請求,解析,執行完了以後纔會繼續往下執行代碼;(緣由是瀏覽器防止JS腳本中出現修改DOM的狀況致使須要從新佈局DOM節點)
e:繪製DOM節點(解析到HTML的結束符)---完成
f:迴流,簡單來講該步驟的執行是因爲dom節點受到了js或者是css的影響致使頁面發生重繪。
複製代碼
下面是常見的HTTP狀態碼:
200 - 請求成功
301 - 資源(網頁等)被永久轉移到其它URL
404 - 請求的資源(網頁等)不存在
500 - 內部服務器錯誤
複製代碼
請求行(request line)、請求頭部(header)、空行和請求數據
狀態行、消息報頭、空行和響應正文