在移动端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)、空行和请求数据
状态行、消息报头、空行和响应正文