前端适配问题
什么是前端适配?
我们希望在不同尺寸的设备下,页面可以自适应的展示或者进行等比例的缩放。从而在不同尺寸下,出现相似的结果。
像素分类
1.设备像素(物理像素): 设备屏幕的物理像素,在同一个设备上,它的物理像素都是固定的。 2.css像素(逻辑像素): 是为web开发者创造的,在CSS和javascript中使用的一个抽象的层。
dpr是指物理像素和css像素的比例。当dpr=1时,说明物理像素和css像素是1:1。此时一个物理像素等于一个css像素。当dpr=2时,说明物理像素是css像素的2倍,那么这时候4个物理像素为一个css像素
在pc端,css的一个像素往往都是对应电脑屏幕的一个物理像素,
在移动端,如iphone8,css像素为375px677px,dpr是2,设备像素是750px1354px。1个逻辑像素占4个物理像素 (4个物理像素来显示1个css逻辑像素)。
什么是viewPort
MDN上说meta标签是:元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。
- 如果设置了
name属性,meta元素提供的是文档级别(document-level)的元数据,应用于整个页面。 - 如果设置了
http-equiv属性,meta元素则是编译指令,提供的信息与类似命名的 HTTP 头部相同。 - 如果设置了
charset属性,meta元素是一个字符集声明,告诉文档使用哪种字符编码。 - 如果设置了
itemprop属性,meta元素提供用户定义的元数据。
viewPort是meta标签中name属性中的一个。指页面上用户可见区域。网页容器,用多大的空间来渲染页面。
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
这段代码的意思是将布局视口的宽度设置为设备宽度,初始缩放比例为1,最大缩放比例为1,用户不能缩放。
适配相关
第一种:使用lib-flexible 和 postcss-pxtorem
// main.js引入flexible和全局样式
// 移动端适配
import 'lib-flexible/flexible.js';
// 引入全局样式
import '@/assets/scss/index.scss';
// 配置不同,基础尺寸比例
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: {
autoprefixer: {
overrideBrowserslist: ['Android 4.1', 'iOS 7.1', 'Chrome > 31', 'ff > 31', 'ie >= 8']
},
'postcss-pxtorem': {
rootValue: 37.5,
propList:['*'],
selectorBlackList :['html'],
minPixelValue :1.5,
mediaQuery:false,
exclude:'common',
}
}
}
// @mixin 指令允许我们定义一个可以在整个样式表中重复使用的样式。
// @include 指令可以将混入(mixin)引入到文档中。
@import './mixin.scss';
html {
@include root-font-size();
}
// 清除浮动
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
// 多行隐藏
@mixin textoverflow($clamp:1) {
display: block;
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $clamp;
/*! autoprefixer: ignore next */
-webkit-box-orient: vertical;
}
//flex box
@mixin flexbox($jc:space-between, $ai:center, $fd:row, $fw:nowrap) {
display: flex;
display: -webkit-flex;
flex: 1;
justify-content: $jc;
-webkit-justify-content: $jc;
align-items: $ai;
-webkit-align-items: $ai;
flex-direction: $fd;
-webkit-flex-direction: $fd;
flex-wrap: $fw;
-webkit-flex-wrap: $fw;
}
/* 移动端页面设计稿宽度 */
$design-width: 750;
/* 移动端页面设计稿dpr基准值 */
$design-dpr: 2;
/* 将移动端页面分为10块 */
$blocks: 10;
/* 缩放所支持的设备最小宽度 */
$min-device-width: 320px;
/* 缩放所支持的设备最大宽度 */
$max-device-width: 750px;
/*
rem与px对应关系,1rem代表html font-size值(为一块的宽度),$rem即为$px对应占多少块
$px $rem
------------- === ------------
$design-width $blocks
*/
/* html根元素的font-size定义,简单地将页面分为$blocks块,方便计算 */
@mixin root-font-size() {
font-size: 100vw / $blocks;
body {
@include container-min-width();
}
/* 最小宽度定义 */
@media screen and (max-width: $min-device-width) {
font-size: $min-device-width / $blocks;
}
/* 最大宽度定义 */
&[data-content-max] {
body[data-content-max] {
@include container-max-width();
}
@media screen and (min-width: $max-device-width) {
font-size: $max-device-width / $blocks;
}
}
}
/* 单位px转化为rem */
@function px2rem($px) {
@return #{$px / $design-width * $blocks}rem;
}
/* 单位rem转化为px,可用于根据rem单位快速计算原px */
@function rem2px($rem) {
@return #{$rem / $blocks * $design-width}px;
}
/**
* 实现固定宽高比
* @param {string} $position: relative 定位方式
* @param {string} $width: 100% 容器宽度
* @param {string} $sub: null 容器的目标子元素
* @param {number} $aspectX: 1 容器宽
* @param {number} $aspectY: 1 容器高
*/
@mixin aspect-ratio($position: relative,
$width: 100%,
$sub: null,
$aspectX: 1,
$aspectY: 1) {
overflow: hidden;
position: $position;
padding-top: percentage($aspectY / $aspectX);
width: $width;
height: 0;
@if $sub==null {
$sub: "*";
}
&>#{$sub} {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
/* 设置容器拉伸的最小宽度 */
@mixin container-min-width() {
margin-right: auto;
margin-left: auto;
min-width: $min-device-width;
}
/* 设置容器拉伸的最大宽度 */
@mixin container-max-width() {
margin-right: auto;
margin-left: auto;
max-width: $max-device-width;
}
/* 设置字体大小,不使用rem单位, 根据dpr值分段调整 */
@mixin font-size($fontSize) {
font-size: $fontSize / $design-dpr;
[data-dpr="2"] & {
font-size: $fontSize / $design-dpr * 2;
}
[data-dpr="3"] & {
font-size: $fontSize / $design-dpr * 3;
}
}
/* 清除浮动 */
@mixin clearfix {
*zoom: 1;
&:after {
content: "";
display: block;
height: 0;
visibility: hidden;
clear: both;
}
}
/*
*$line:超出显示几行省略号
*$substract:预留区域百分比
*/
@mixin text-overflow($line:1, $substract:0) {
overflow: hidden;
@if $line==1 {
white-space: nowrap;
text-overflow: ellipsis;
width: 100% -$substract;
}
@else {
display: -webkit-box;
-webkit-line-clamp: $line;
-webkit-box-orient: vertical;
}
}
@mixin WH($Width:100%, $Height:100%) {
width: $Width;
height: $Height;
}
第二种:通过动态计算屏幕高度尺寸来设置html根目录下的fontSize大小
// 来自 https://github.com/amfe/lib-flexible/blob/2.0/index.js
(function flexible(window, document) {
var docEl = document.documentElement;
// 获取当前显示设备的物理像素分辨率与CSS像素分辨率之比;
var dpr = window.devicePixelRatio || 1;
//根据分辨率调整全局字体大小
function setBodyFontSize() {
// html已完成加载,则立即调整字体大小,否则等待html加载完成再调整字体大小
if (document.body) {
document.body.style.fontSize = 12 * dpr + "px";
} else {
// 监听DOMContentLoaded 事件——当初始的 HTML 文档被完全加载和解析完成之后触发,无需等待样式表
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// 根据屏幕宽度,重置1rem的长度为当前屏幕宽度的1/10
function setRemUnit() {
var rem = docEl.clientWidth / 10;
// 1rem的值永远为根元素的字体大小,所以此处通过调整全局字体大小来重置rem
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// 监听resize事件——屏幕大小发生变化时触发
window.addEventListener("resize", setRemUnit);
// 监听pageshow事件——显示页面时触发
window.addEventListener("pageshow", function (e) {
// 若是浏览器中点击后退时显示页面,则重置rem
if (e.persisted) {
setRemUnit();
}
});
// 检测是否支持0.5px
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})(window, document);
echarts中字体设置
// 字体转换 px -> rem
export function fontChart(res) {
let docEl = document.documentElement,
clientWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (!clientWidth) return;
// 此处的3840 为设计稿的宽度,记得修改!
let fontSize = clientWidth / 1920;
return res * fontSize;
}
第三种:通过scale设置
采用了css3的缩放transform: scale(X)属性。我们只要监听浏览器窗口大的小,同时控制变化的比例就可以了。
<template>
<div
class="ScreenAdapter"
:style="style"
>
<slot />
</div>
</template>
<script>
export default {
name: '',
//参数注入
props: {
width: {
type: String,
default: '1920'
},
height: {
type: String,
default: '1080'
}
},
data() {
return {
style: {
width: this.width + 'px',
height: this.height + 'px',
transform: 'scale(1) translate(-50%, -50%)'
}
}
},
mounted() {
this.setScale()
window.onresize = this.Debounce(this.setScale, 1000)
},
methods: {
Debounce: (fn, t) => {
const delay = t || 500
let timer
return function() {
const args = arguments
if (timer) {
clearTimeout(timer)
}
const context = this
timer = setTimeout(() => {
timer = null
fn.apply(context, args)
}, delay)
}
},
// 获取放大缩小比例
getScale() {
const w = window.innerWidth / this.width
const h = window.innerHeight / this.height
return [w,h];
},
// 设置比例
setScale() {
this.style.transform = 'scale(' + this.getScale()[0] + ','+ this.getScale()[1] + ') translate(-50%, -50%)'
console.log('任你千变万化,我都不会影响性能')
}
}
}
</script>
<style lang="scss" scoped>
.ScreenAdapter {
transform-origin: 0 0;
position: absolute;
left: 50%;
top: 50%;
transition: 0.3s;
background: red;
}
</style>
数据可视化常用网站
Echarts : Documentation - Apache ECharts
Echarts :ppchart.com/#/
Make A Pie: Make A Pie
Make a pie(代替1)ppchart.com/#/
make a pie (代替2) analysis.datains.cn/finance-adm…
make a pie (代替3)www.isqqw.com/homepage
DataV:DataV
HighCharts: Highcharts 演示 | Highcharts
vue-seamless-scroll: chenxuan0000.github.io/vue-seamles…
数据可视化平台(各个地区的json文件) 各个地区的json文件 用来echarts注册地图