但图片过大的时候,网速慢的时候,图片会呈现断片式加载一截一截的显示,显的比较难看。可以先显示压缩过的模糊的预览图片,在通过new Image() 的方式加载图片,当图片加载好后在替换页面上的图片
.div1{ width:100%; height:50px; overflow:hidden; }
.div1:hover{ overflow-y:auto }
.div2{  width:100%; margin-left:20px; height:2000px; }
隐藏滚动条
隐藏竖直滚动条,但页面依然可以滚动   兼容性:兼容 IE9及以上
html,body {height: 100%;}
html {overflow: hidden;}
body {overflow: auto;width: calc(100vw + 20px);}
::-webkit-scrollbar { display: none; }
弹窗滚动条不滚动
兼容:兼容 IE8 及以上
通过点击出现弹窗后,通过js设置外部滚动条为隐藏
<div class="buttom" style="width:100%;height:1500px;"></div>
<div class="shadow_box">
  <div class="shadow"></div>
  <div class="text_box"></div>
</div>
$('.buttom').click(function(){
  $('.shadow_box').show()
  $(document.body).css({"overflow-x":"hidden","overflow-y":"hidden"});
})
$('.shadow').click(function(){
    $('.shadow_box').hide()
  $(document.body).css({"overflow-x":"auto","overflow-y":"auto"});
})
通过禁止滚动条响应事件,在关闭弹窗后再响应
function handleStopWheel(e) {
  e.preventDefault();
}
$('.buttom').click(()=>{
  window.addEventListener("wheel",handleStopWheel,{passive: false})
})
$('#site-toLogin').click(() => {
  window.removeEventListener("wheel",handleStopWheel)
});
5:设备分类的参考
关于手机和 PC 的判断
window.location.href = /Android|webOS|iPhone|ipod|ipad|BlackBerry/i.test(navigator.userAgent) ? "https://www.baidu.com/" :  "http://news.baidu.com/";
关于屏幕大小属性参考
# 浏览器窗口大小(包括工具栏)
window.outerHeight
window.outerWidth
# 窗口文档显示区(不包含滚动条)
window.innerWidth
window.innerHeight
# 元素级内部大小(不包含滚动条)
clientWidth
clientHeight
关于手机横竖屏的判断
通过 window.orientation 属性进行判断, PC 端为 undefined,90或-90为横屏幕,剩下则是竖屏
手机和电脑长按的混合处理
let isAndroid=/Android|webOS|iPhone|ipod|ipad|BlackBerry/i.test(navigator.userAgent)
let set1,set2,isLong=0,start=false
let dom=document.getElementById('aaa')
  dom.removeEventListener('touchstart',a)
  dom.removeEventListener('touchmove',b)
  dom.removeEventListener('touchend',c)
  dom.removeEventListener('mousedown',a)
  dom.removeEventListener('mousemove',b)
  dom.removeEventListener('mouseup',c)
if(isAndroid){
  dom.addEventListener('touchstart',a)
  dom.addEventListener('touchmove',b)
  dom.addEventListener('touchend',c) 
}else{
  dom.addEventListener('mousedown',a)
  dom.addEventListener('mousemove',b)
  dom.addEventListener('mouseup',c)
}
function a(){
  
  start=true
  set1=setTimeout(function(){
    console.log('这次是长按')
    isLong=1
  },800)
}
function b(){
  
  if(start){
    isLong=2
    clearTimeout(set1)
  }
}
function c(){
  
  if(isLong==0){
    clearTimeout(set1)
    console.log('这次是单击')
  }
  isLong=0
  start=false
}
6:功能的相关参考
禁止使用页面后退
兼容性:不支持IE
不支持IE
history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
    history.pushState(null, null, document.URL);
});
点击关闭当前页面
浏览器出于安全策略的考虑,只允许Javascript 关闭由Javascript 打开的页面,所以当我们需要关闭当前页面的时候,你可以这样
<a onClick="window.opener=null;window.open('','_self');window.close();">关闭</a>
window.opener是一个可读可写的属性,返回对创建该窗口的 Window 对象的引用
window.opener.lose()可以关闭父级窗口
思路,先设置opener为空,当打开一个空的新窗口,关闭父级窗口,因为打开的是空,所有新的子页面不会出现
表单自动填入功能
在部分浏览器中,会默认开启自动完成功能。注意 属性 name 和 id 会影响改功能;
<input type="text"/> 
// 当不存在name 或 id 的时候,自动完成不会开启,只有当其中一个出现的时候才会启动。
<form>
<input type="email" name="email" autocomplete="off" />
// 也可以通过 autocomplate 进行控制。
// 自动填写功能默认为黄色,下面的样式会重置它
input:-webkit-autofill,
input:-webkit-autofill:hover, 
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
  border: 1px solid green;
  -webkit-text-fill-color: green;
  -webkit-box-shadow: 0 0 0px 1000px #000 inset;
  transition: background-color 5000s ease-in-out 0s;
}
html动态加载 js文件
function loadScript(url,callback){
    var script=document.createElement("script");
    script.type="text/javascript";
    if(script.readyState){
        script.onreadystatechange=function(){
            if(script.readyState=="load"||script.readyState=="complete"){
                script.onreadystatechange=null;
                callback();
            };
        }
    }else{
        script.onload=function(){
            callback();
        }
    }
    script.src=url;
}
loadScript("jquery.js",function(){
    console.log('加载完成')
})
prototype 原型改造
var a=document.getElementById("en")
a.addClass=function(name){
    var a=this.getAttribute("class")
    if(a){
        a=a+" "+name;
        this.setAttribute("class",a)
    }else{
        console.log(this)
    }
}
a.addClass("name")
String.prototype.lengths=function(name){
    console.log(this.length)
}
"lenght".lengths()
页面打印及4A大小的设置
let dom="<!DOCTYPE html>...</html>"
function doPrint3(dom){
    
    var iframe=document.getElementById("print-iframe");
    if(!iframe){  
        var el = document.getElementById("printcontent");
        iframe = document.createElement('IFRAME');
        iframe.setAttribute("id", "print-iframe");
        
        iframe.setAttribute('style', 'width:794px;height:1090px;'); 
        document.body.appendChild(iframe);
        
        iframe.contentWindow.document.documentElement.innerHTML=dom
        var doc = iframe.contentWindow.document;
        
        doc.write("<LINK rel="stylesheet" type="text/css" href="css/print.css">");
        
        
        
        
    }
    iframe.contentWindow.print();
    if (navigator.userAgent.indexOf("MSIE") > 0){ 
      document.body.removeChild(iframe);
    }
}
doPrint3(dom){
    
    var iframe=document.getElementById("print-iframe");
    if(!iframe){
      iframe = document.createElement('IFRAME');
      iframe.setAttribute("id", "print-iframe");
      
      iframe.setAttribute('style', 'width:794px;height:1090px;'); 
      document.body.appendChild(iframe);
      iframe.contentWindow.document.documentElement.innerHTML=dom  
    }
    setTimeout(function(){
      iframe.contentWindow.print();
      var doc = iframe.contentWindow.document;
      doc.close();
      iframe.contentWindow.focus(); 
      document.body.removeChild(iframe);
    },10)
},
数据表格和固定头部的样式
React 代码
import * as React from 'react'
var $ = require('jquery')
export class LTable extends React.Component<any,any>{
  constructor(props:any) {
    super(props);
    this.resize=this.resize.bind(this)
    this.state = {
      id:this.props.id||'l_'+new Date().getTime(),
      clas:this.props.className||'',
      height:this.props.height||'300px',
    }
  }
  static contextTypes={  
    router: function(){
      return null
    }
  }
  mounted = false;
  componentWillMount(){
    this.mounted = true;
  }
  componentDidMount() {
    window.addEventListener('resize', this.resize)
    this.resize()
  }
  componentDidUpdate(){
    this.resize()
  }
  componentWillUnmount(){
    window.removeEventListener('resize',this.resize);
    this.mounted = false;
  }
  resize(){
    let id=this.state.id
    let tbody=this.props.tbody
    if(tbody.length>0){
      let ltable=document.getElementById(id)!.getElementsByTagName('table')
      let thead0=ltable[0].getElementsByTagName('thead')[0]
      let thead1=ltable[1].getElementsByTagName('thead')[0]
      let ltbody=document.getElementById(id)!.getElementsByClassName('l_table_body')[0]
      let th0=thead0.getElementsByTagName('th')
      let th1=thead1.getElementsByTagName('th')
      thead0.style.minWidth=thead1.offsetWidth+'px'
      ltable[0].style.width=ltable[1].offsetWidth+'px'
      for(let i=0;i<th1.length;i++){
        th0[i].style.width=th1[i].offsetWidth+'px'
      }
      $(ltbody).scroll(function(e:any){
        let div=document.getElementById(id)!.getElementsByClassName('l_table_head')[0]
        div.scrollLeft=e.target.scrollLeft
      })
    }
  }
  render(){
    let thead=this.props.thead,tbody=this.props.tbody
    return (
    <div id={this.state.id} className={"l_table "+this.state.clas}>
      {this.props.title?
        <h3 className="l_table_title">{this.props.title}</h3>:''
      }
      <div className="l_table_head l_scroll_hide">
        <table>
          <thead>
            <tr>
            {thead.map((e:any,i:any)=>
              <th key={i}>{e.title}</th>
            )}
            </tr>
          </thead>
        </table>
      </div>
      <div className="l_table_body" style={{height:this.state.height}}>
        {tbody.length>0?
        <table>
          <thead>
            <tr>
            {thead.map((e:any,i:any)=>
              <th key={i}>{e.title}</th>
            )}
            </tr>
          </thead>
          <tbody>
            {tbody.map((tr:any,a:any)=>
              <tr key={a}>
              {thead.map((td:any,b:any)=>{
                if(td.render){
                  return <td key={b}>{td.render(tr)}</td>
                }else{
                  return <td key={b}>{td.title}</td>
                }
              })}
              </tr>
            )}
          </tbody>
        </table>:
        <div className="l_nodata">
          <span>No Date</span>
        </div>
        }
      </div>
    </div>
    )
  }
}
.l_table{border: 1px solid #c3c3c3;background: #fff;margin-bottom:20px;}
.l_table table{width:100%}
.l_table th,.l_table td{word-break:keep-all;overflow:hidden;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis;}
.l_table table,.l_table th,.l_table td{border:0;border-spacing:0;}
.l_table td{padding: 6px 10px;max-width: 150px;}
.l_table_title{text-align:center;font-weight:700;margin:0;padding:16px 0;position:relative;top:1px;font-size:14px;color:rgba(0,0,0,0.65);padding-right:17px;}
.l_scroll_hide::-webkit-scrollbar{background:transparent}
.l_scroll_hide{scrollbar-color: transparent transparent;}
.l_table th{background:#fafafa;position:relative;z-index:1;box-sizing:border-box;padding:0px 10px;text-align:left}
.l_table .l_table_head{border-top:1px solid #e8e8e8;}
.l_table .l_table_body td,.l_table_head th,.l_table .l_table_body th{border-right: 1px solid #e8e8e8;border-bottom: 1px solid #e8e8e8}
.l_table .l_table_head{overflow-x:hidden;overflow-y:scroll;}
.l_table .l_table_body{overflow-y:scroll;margin-top: -35px;}
.l_table_head,.l_table_body thead{line-height:34px}
.l_table_body thead{visibility:hidden;}
.l_nodata{position:relative;height:100%}
.l_nodata span{position:absolute;top:calc(50% + 10px);left:50%;transform:translate(-25%);}
自动化填充的样式修改
无论浏览器的元素默认样式设置的再怎么绚丽,我们都希望有足够的自由(修改所有的一切);更何况自动填写那一块黄色的背景和我们设置的风格完全无法融合;
input:-webkit-autofill,
input:-webkit-autofill:hover, 
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
  border: 1px solid green;
  -webkit-text-fill-color: green;
  -webkit-box-shadow: 0 0 0px 1000px #000 inset;
  transition: background-color 5000s ease-in-out 0s;
}
7:浏览器开发调试
CONSOLE 各种提示信息的集合
console.log('文字信息');
console.info('提示信息');
console.warn('警告信息');
console.error('错误信息');
throw new Error('这是一个错误提示');
throw { name: '参数错误', message: 'data[0]不存在'}
console.assert(false,'看不见')
console.log("%c我要变色了","color:blue;font-size:20px")
console.group('第一个组');
    console.log("1-1");
    console.log("1-2");
    console.log("1-3");
console.groupEnd();
console.group('第一个组');
    console.group("1-1");
        console.group("1-1-1");
            console.log('内容');
        console.groupEnd();
    console.groupEnd();
    console.group("1-2");
        console.log('内容');
        console.log('内容');
        console.log('内容');
    console.groupEnd();
console.groupEnd();
var Obj = {
    Obj1: {
        a: "aaa",
        b: "bbb",
        c: "ccc"
    },
    Obj2: {
        a: "aaa",
        b: "bbb",
        c: "ccc"
    }
}
var Arr = [
    ["aa","bb","cc"],
    ["dd","ee","ff"],
    ["gg","hh","ii"],
]
console.table(Obj);
console.table(Arr);
console.trace('调用')
console.time("Chrome中循环1000次的时间");
for(var i = 0; i < 1000; i++){ }
console.timeEnd("Chrome中循环1000次的时间");
8:加密方案
AES对称加密
一般现在的项目,为了通信安全,会考虑信息加密的方案,通过使用AES对传输的内容进行加密,再通过RSA对AES的秘钥进行加密。最后将AES密文和RSA密文传输到后端。
像AES对称加密,是通过一个秘钥进行的加密和解密的,所以这个秘钥的安全性极为重要。
import CryptoJS from "crypto-js"
const AesString=(SymmetricKey,ivString,text)=>{、
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  let encrypted = CryptoJS.AES.encrypt(text, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  
  let ciphertext = encrypted.toString();
  return ciphertext
}
const AesDcString=(SymmetricKey,ivString,text)=>{
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  let encrypted = CryptoJS.AES.decrypt(text, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  
  let message = decrypted.toString(CryptoJS.enc.Utf8);
  return message
}
import CryptoJS from "crypto-js"
const AesFile=(SymmetricKey,ivString,file)=>{
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  let reader = new FileReader();
  
  reader.readAsArrayBuffer(file);
  
  reader.onloadend = function () {
    
    let buffer = reader.result;
    
    let wordArray = CryptoJS.lib.WordArray.create(buffer);
    
    let encrypted = CryptoJS.AES.encrypt(wordArray, key, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    });
    
    let ciphertext = encrypted.toString();
    return ciphertext
  };
}
const AesDcFile=(SymmetricKey,ivString,fileText,filename)=>{
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  var decrypted = CryptoJS.AES.decrypt(fileText, key,{
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  
  var buffer = new ArrayBuffer(decrypted.sigBytes);
  var view = new Uint8Array(buffer);
  for (var i = 0; i < decrypted.sigBytes; i++) {
      view[i] = decrypted.words[i >>> 2] >>> (24 - (i % 4) * 8) & 0xff;
  }
  
  var blob = new Blob([buffer]);
  
  saveAs(blob,filename);
}
import { saveAs } from "file-saver";
import CryptoJS from "crypto-js"
import JSZip from 'jszip'
const AesFileZip=(SymmetricKey,ivString,fileList,save=false,name='encryption.txt')=>{
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  const zip = new JSZip()
  for(let i in fileList){
    zip.file(fileList[i].name, fileList[i].raw)
  }
  
  zip.generateAsync({type:"uint8array"}).then(function(zipData) {
    
    const encryptedData = CryptoJS.AES.encrypt(CryptoJS.lib.WordArray.create(zipData), key, {
      iv:iv,
      padding: CryptoJS.pad.Pkcs7,
      mode: CryptoJS.mode.CBC
    });
    
    const encryptedBase64 = encryptedData.toString();
    if(save){ 
      let str = new Blob([encryptedBase64], {type: 'text/plain;charset=utf-8'});
      saveAs(str,encryption.txt);
    }
    return encryptedBase64
  });
}
const AesDcStrToZip=(SymmetricKey,ivString,text,save=true,name='deciphering.zip')=>{
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  var decrypted = CryptoJS.AES.decrypt(text, key,{
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  
  if(save){
    
    var buffer = new ArrayBuffer(decrypted.sigBytes);
    var view = new Uint8Array(buffer);
    for (var i = 0; i < decrypted.sigBytes; i++) {
        view[i] = decrypted.words[i >>> 2] >>> (24 - (i % 4) * 8) & 0xff;
    }
    
    var blob = new Blob([buffer], {type: "text/plain"});
    
    saveAs(blob,name);
  }
  return decrypted
}
const AesDcStrFileToZip=(SymmetricKey,ivString,file,save=true,name='deciphering.zip')=>{
  
  const key = CryptoJS.enc.Utf8.parse(SymmetricKey);
  const iv = CryptoJS.enc.Utf8.parse(ivString);
  
  let reader = new FileReader();
  
  reader.readAsText(file, "UTF-8");
  
  reader.onload = function() {
    
    let ciphertext = this.result;
    var decrypted = CryptoJS.AES.decrypt(ciphertext, key,{
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    })
    if(save){
      
      var buffer = new ArrayBuffer(decrypted.sigBytes);
      var view = new Uint8Array(buffer);
      for (var i = 0; i < decrypted.sigBytes; i++) {
          view[i] = decrypted.words[i >>> 2] >>> (24 - (i % 4) * 8) & 0xff;
      }
      
      var blob = new Blob([buffer], {type: "text/plain"});
      
      saveAs(blob,name);
    }
    return decrypted
  };
}
RSA非对称加密
非对称加密
import forge from 'node-forge';
const encrypt=(key,text)=>{ 
  var privateKey = forge.pki.publicKeyFromPem(key); 
  
  var encrypted = privateKey.encrypt(text, 'RSA-OAEP', {
    md: forge.md.sha256.create(),
    mgf1: {
      md: forge.md.sha1.create()
    }
  })
  return btoa(encrypted) 
}
const decrypt=(key,text)=>{ 
  var privateKey = forge.pki.privateKeyFromPem(key); 
  
  var encrypted = privateKey.decrypt(atob(text), 'RSA-OAEP', {
    md: forge.md.sha256.create(),
    mgf1: {
      md: forge.md.sha1.create()
    }
  })
  return encrypted
}
const decryptFile=(file,text)=>{ 
  return new Promise(function(resolve, reject) {
    let reader = new FileReader();
    reader.readAsText(file, "UTF-8");
    reader.onload = function() {
      let ciphertext = this.result;
      console.log(ciphertext)
      let privateKey = forge.pki.privateKeyFromPem(ciphertext);
      try{
        let encrypted = privateKey.decrypt(atob(text), 'RSA-OAEP', {
          md: forge.md.sha256.create(),
          mgf1: {
            md: forge.md.sha1.create()
          }
        });
        resolve(encrypted);
      }catch(err){
        reject(err)
      }
    }
  })
}
9:数据处理
数组去除符合条件的子元素
如果直接使用 for 循环去除,那么会出现错误,原因是函数在不断的去除,而索引没变
var arr = [0,1,2,3,4,5,1,2,3]
for (let i=0;i<arr.length;i++) {
    if(arr[i] == 2){
        arr.splice(i--,1)
    }
}
JS 浮点数精确度问题
当js进行浮点型计算的时候,会导致计算出错。例:0.6910=6.8999999999999995,因为js作为解释性语言,同其他语言一样在计算小数的时候将小数转二进制不好转换
解决办法:将小数转换成整数,计算完成后转换成小数。0.69100*10/100
5.324.toFixed(2)==5.32
数字转成每隔3位加逗号
var num_s = "1232134456.546 ";
var num=parseFloat(num_s).toLocaleString();
本地时间规则化
new Date.toLocaleTimeString()
获取当前时间及前半个小时
var a= new Date();
var y=a.getFullYear();
var m=a.getMonth()+1;
var d=a.getDate();
var h=a.getHours();
var f=a.getMinutes();
h<10?h="0"+h:h=h;
f<10?f="0"+f:f=f;
$scope.end_time=y+"-"+m+"-"+d+" "+h+":"+f
var b= new Date(a.getTime()-1000*60*30);
y=b.getFullYear();
m=b.getMonth()+1;
d=b.getDate();
h=b.getHours();
f=b.getMinutes();
$scope.start_time=y+"-"+m+"-"+d+" "+h+":"+f
10:网络请求
AJax停止网络请求 abort()
var currentAjax = null;  
function startAjax(){  
    
    if(currentAjax) {currentAjax.abort();} 
    currentAjax = $.ajax({
           type:'POST',
           beforeSend:function(){},  
           url:'test.php',  
           data:'username=xxx',  
           dataType:'JSON',  
           error:function(){alert('error')},
           success:function(data){alert(data)}
    });  
}
angular.js $http停止请求
通过注入 $q 服务,使用$q.defer来停止
var _enj;
$scope.clconversations=function(){
    if(_enj){_enj.resolve()};
    _enj = $q.defer();
    $http.get('/Iridium/public/tcpanalysis/getconversations',{
        params:{
            start_time: $scope.start_time,
            end_time:$scope.end_time,
        },
        timeout:_enj.promise
    }).then(function(response){
        console.log('')
	});
}
Rem布局
1:网易的rem布局
1:设置viewport
<!--viewport 如果页面不允许缩放请加上 user-scalable=no-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,minimal-ui">
2:根据750px设计稿计算比例
//750px/100=7.5   在页面加载后:需要动态设置font-size
document.documentElement.style.fontSize = document.documentElement.clientWidth /7.5 + 'px';
// 也可以设置成百分比 页面中默认100%=16px
// {w/(750/100)}/16
// (w/7.5)/16
// w/120
document.documentElement.style.fontSize = document.documentElement.clientWidth /1.2 + '%';
2:淘宝rem 布局
<head>
<script>!function(e){function t(a){if(i[a])return i[a].exports;var n=i[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var i={};return t.m=e,t.c=i,t.p="",t(0)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=window;t["default"]=i.flex=function(normal,e,t){var a=e||100,n=t||1,r=i.document,o=navigator.userAgent,d=o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i),l=o.match(/U3\/((\d+|\.){5,})/i),c=l&&parseInt(l[1].split(".").join(""),10)>=80,p=navigator.appVersion.match(/(iphone|ipad|ipod)/gi),s=i.devicePixelRatio||1;p||d&&d[1]>534||c||(s=1);var u=normal?1:1/s,m=r.querySelector('meta[name="viewport"]');m||(m=r.createElement("meta"),m.setAttribute("name","viewport"),r.head.appendChild(m)),m.setAttribute("content","width=device-width,user-scalable=no,initial-scale="+u+",maximum-scale="+u+",minimum-scale="+u),r.documentElement.style.fontSize=normal?"50px": a/2*s*n+"px"},e.exports=t["default"]}]);  flex(false,100, 1);</script>
</head>
此方案默认1rem=100px,如需更改,在代码代码最后更改flex(false,100, 1),此代码仅适用手机,设计稿按屏幕分辨率设计,
在相当数量的布局情境中(比如底部导航元素平分屏幕宽,大尺寸元素),你必须使用百分比或者flex才能完美布局!
Flex布局
Flex布局(弹性布局)在未来将成为主流,目前推荐在手机端使用,React native系列官方建议项目使用flex布局; IE10+
// 设为 Flex 后,子元素的float、clear和vertical-align属性将失效
// Webkit 内核的浏览器,必须加上-webkit前缀
.box{
    display: -webkit-flex;
    display: flex;
}