zoukankan      html  css  js  c++  java
  • 【记】移动布局

    移动端设计稿尺寸:750*1334 (iphone6) 为标准
    设备像素比:
    设备物理像素和设备独立像素的比例; 也就是 DPR = 物理像素 / 设备独立像素 iphone6以下 dpr=2
    可以通过 window.devicePixelRatio 来获取


    移动布局开发准备工作

    一、搭建本地静态html页面服务器

    # 1. 全局安装 http-server
    npm i -g http-server
    
    # 2. 在项目文件夹下: 执行 npm init -y 得到 package.json 文件, 然后配置 script
    "script": {
    	"dev": "http-server ./ -o --port 8089"
    }
    # 启动服务
    npm run dev
    

    二、VSCode编辑设置 LESS 自动编译成 CSS

    /* #步骤:
     * 1. 在扩展中安装 Easy LESS 插件 (切记插件名没有中横杆)
     * 2. 在设置中找到 setting.json 文件进行一下配置
     */
    "less.compile": {
    	"compress": false, // 是否压缩
    	"sourceMap": false, // 是否生产map文件,可在控制台看到less行数
    	"out": "${workspaceRoot}\css\",
    	"outExt": ".css" // 输出文件后缀, 小程序可以写 .wxss
    }
    

    三、VSCode编辑器安装插件输入 px 提示 rem 转换值
    一般UI给我们的稿子大小是750的。就以这个为例子:在flexible.js中,把750px分为10份,1rem 为 75px。所以font-size的基准值为75px;
    css换算成rem公式为: px值 / 75 = rem, 例如:100px=100/75=1.33rem

    /* #步骤:
     * 1. 在扩展中安装 cssrem 插件 
     * 2. 选项 -> 设置 -> 扩展下的cssrem 设置基准 foot-size 为 75 
     */
    

    四、使用iconfont字体图标
    登录iconfont.cn, 选择你需要的图标保存至项目。并生成在线连接, 将代码保存至本地即可使用。

    // style/iconfont.css
    @font-face {
      font-family: "iconfont"; /* Project id 2524131 */
      src: url('//at.alicdn.com/t/font_2524131_8g1ggguc7ig.woff2?t=1619912299648') format('woff2'),
           url('//at.alicdn.com/t/font_2524131_8g1ggguc7ig.woff?t=1619912299648') format('woff'),
           url('//at.alicdn.com/t/font_2524131_8g1ggguc7ig.ttf?t=1619912299648') format('truetype');
    }
    
    .iconfont {
      font-family: "iconfont" !important;
      font-size: 16px;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    .icon-shuben:before {
      content: "e6ca";
    }
    

    iconfont 的使用
    全局引入:在main.js文件中进行全局引入, import './style/iconfont.css'
    具体使用: <span class="iconfont icon-shuben'><!--书本--></span>


    移动端开发适配

    一、 设置meta标签

    <!-- 强制让文档与设备的宽度保持1:1 -->
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <!-- 禁止识别电话和邮箱 -->
    <meta name="format-detection" content="telephone=no,email=no" />
    

    二、动态设置html根节点的字体大小,实现 rem 适配

    // 动态设置html的字体: font-size设为100px, 1rem = 100px
    (function(win, doc) {
        if (!win.addEventListener) return;
        function setHtmlFontSize() {
            var html = document.documentElement;
            var k = 750;
            html.style.fontSize = html.clientWidth / k * 100 + "px";
        }  
        doc.addEventListener('DOMContentLoaded', setHtmlFontSize, false);
        win.addEventListener('resize', setHtmlFontSize, false);
        win.addEventListener('load', setHtmlFontSize, false); 
    })(window, document)
    

    H5界面淘宝提供的适配方案flexible.js

    github地址:https://github.com/amfe/lib-flexible
    官方文档地址:https://github.com/amfe/article/issues/17

    Flexible.js的使用:
    使用了flexible.js,页面模板不需要设置 <meta name="viewport">的标签,会自动设置根元素html的font-size、动态创建viewport、针对retina屏做dpr

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta content="yes" name="apple-mobile-web-app-capable">
            <meta content="yes" name="apple-touch-fullscreen">
            <meta content="telephone=no,email=no" name="format-detection">
            <script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
            <link rel="apple-touch-icon" href="favicon.png">
            <link rel="Shortcut Icon" href="favicon.png" type="image/x-icon">
            <title>案例实战</title>
        </head>
        <body>
            <!-- 页面结构写在这里 -->
        </body>
    </html>
    

    移动端常见问题【解决方案】

    一、禁止电话与邮箱
    添加meta标签全局禁用
    <meta name="format-detection" content="telephone=no,email=no" />
    局部使用:

    <a href="tel:15919829191">电话: 15919829191</a>
    <a href="mailto:645629118@qq.com">邮箱: 645629118@qq.com</a>
    

    二、解决链接按钮高亮问题
    使用 a 标签作为按钮时,移动端页面中的链接长按会触发一个色块高亮效果;

    a {
    	-webkit-tap-highight-color: transparent;
    }
    /* 或者设置你需要的颜色 */
    a {
    	-webkit-top-highlight-color: rgba(0,0,0,0);
    }
    

    三、解决按钮圆角过圆的问题

    <style>
    input{
    	border-radius: 10px;
    	-webkit-appearance: none;
    }
    </style>
    
    <input type="button" value="按钮" />
    

    四、font-boosting 问题
    Foot Boosting 是 webkit给移动端提供的一个特性。当在手机浏览器上缩小页面后字体很小看不清,这时浏览器会自动增大字体大小 ,解决方案: 设置最大高度

    p {
    	font-size: 14pxl
    	max-height: 99999px;
    }
    

    五、1物理像素问题

    <style>
    #test:before {
    	position: absolute;
    	bottom: -1px;
    	content: "";
    	display: block;
    	 100%;
    	height: 1px;
    	background: #f00;
    }
    @media only screen and(-webkit-device-pixel-ration: 2) {
    	#test:before {
    		transform: scaleY(0.5)
    	}
    }
    @media only screen and(-webkit-device-pixel-ration: 3) {
    	#test:before {
    		transform: scaleY(0.33)
    	}
    }
    </style>
    <div id="test">1物理像素</div>
    

    六、移动端触摸事件【点透】问题解决方案

    /*
     * 底层节点阻止默认行为 
     * 1. 解决IOS10下设置meta无法禁止用户缩放的兼容性问题
     * 2. 解决IOS10下溢出隐藏的问题 body,html{ 100%; overflow: hidden;}
     * 3. 阻止橡皮筋效果(页面华东到最顶和最低部的缓冲反弹的效果)
     * 4. 禁止长按选中文字、选中图片、弹出菜单等
     * 5. 阻止默认行为后,元素无法获取焦点,元素阻止冒泡后可正常使用
     */
    document.addEventListener("touchstart", function(ev) {
    	ev.preventDefault();
    })
    // 缺点: a 链接等可获取焦点的元素的默认行为无法使用,需要手动添加事件绑定
    var aNodes = document.querySelectorAll("a")
    for(var i = 0; i < aNodes.length; i++) {
    	aNodes[i].addEventListener("touchstart", function() {
    		this.isMoved = false;
    	})
    	aNodes[i].addEventListener("touchmove", function() {
    		this.isMoved = true
    	})
    	aNodes[i].addEventListener("touchend", function() {
    		if(!this.isMoved) {
    			window.location.href = this.href;
    		}
    	})
    }
    

    导航拖拽效果 - 橡皮筋效果

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no" />
        <title></title>
        <style>
        	* { margin: 0; padding: 0; }
            li, ol { list-style: none; }
            html, body {  100%; overflow: hidden; height: 100%; }
            body { font-size: 14px; }
            .slide-nav {
              height: 1rem;
              background: #f4f6fd;
              font-size: 16px;
            }
            .slide-nav > ul {
              float: left;
              white-space: nowrap;
              display: flex;
              align-items: center;
              height: 100%;
            }
            .slide-nav > ul > li {
              display: inline-block;
              padding: 0 0.3rem;
            }
        </style>
        <script>
          // 动态设置html的字体
          (function (win, doc) {
            if (!win.addEventListener) return;
            function setHtmlFontSize() {
              var html = document.documentElement;
              var k = 750;
              html.style.fontSize = (html.clientWidth / k) * 100 + "px";
            }
            doc.addEventListener("DOMContentLoaded", setHtmlFontSize, false);
            win.addEventListener("resize", setHtmlFontSize, false);
            win.addEventListener("load", setHtmlFontSize, false);
          })(window, document);
    
          /** 
           * 封装设置样式和获取样式的方法
           */
          function css(node, type, val) {
            var filedStr = "transform"
            if (typeof node === "object" && typeof node[filedStr] === "undefined") { 
              node[filedStr] = {} 
            } 
    
            if(arguments.length >= 3) {
              // 设置
              var text = ''
              node[filedStr][type] = val;
              
              for(item in node[filedStr]) { 
                if(node[filedStr].hasOwnProperty(item)) {
                  switch (item) {
                    case "translateX":
                    case "translateY":
                      text += item + "("+node[filedStr][item]+"px)"
                      break;
                    case "scale":
                      text += item + "("+node[filedStr][item]+")"
                      break;
                    case "rotate":
                      text += item + "("+node[filedStr][item]+"deg)"
                      break;
                  }
                }
              }  
              node.style[filedStr] = node.style.webkitTransform = text; 
            } else if(arguments.length == 2) {
              // 读取
              var val = node[filedStr][type];  
              if (typeof val === "undefined") {
                switch (type) {
                  case "translateX":
                  case "translateY":
                  case "rotate": 
                    val = 0;
                    break;
                  case "scale":
                    val = 1
                    break;
                }
              } 
              return val;
            }
          }
    
          window.onload = function () {
            // 滑动导航
            drag();
            function drag() {
              var slideEle = document.querySelector(".slide-nav"),
                slideItem = document.querySelector(".items"),
                // 记录元素开始位置, 手指开始位置
                startX = 0,
                elementX = 0,
                // (可视区宽 - 滑动内容宽) 
                minX = slideEle.clientWidth - slideItem.offsetWidth;
              // 快速滑屏:
              var lastTime = 0,
                  lastPoint = 0,
                  timeDis = 0,
                  pointDis = 0;
              
              slideEle.addEventListener("touchstart", function (ev) {
                ev = ev || event;
                var touchC = ev.changedTouches[0] 
    
                startX = touchC.clientX;
                elementX = css(slideItem, 'translateX')
                slideItem.style.transition = "none";
    
                lastTime = new Date().getTime();
                lastPoint = touchC.clientX
    
                // 清楚速度
                pointDis = 0;
              }); 
    
              slideEle.addEventListener("touchmove", function(ev) {
                ev = ev || event;
                var touchC = ev.changedTouches[0]
                var nowX = touchC.clientX;
                var disX = nowX - startX;
                var translateX = elementX + disX
                var winW = document.documentElement.clientWidth
    
                var nowTime = new Date().getTime();
                var nowPoint = touchC.clientX;
                timeDis = nowTime - lastTime;
                pointDis = nowPoint - lastPoint;
                lastTime = nowTime;
                lastPoint = nowPoint;
                 
                slideItem.handMove = false; 
                // 范围限制
                if (translateX > 0) { 
                  slideItem.handMove = true; // 用于判断是快速滑动还是普通滑动
                  var scale = winW/((winW + translateX) * 2); // (0, .5) 
                  translateX = css(slideItem, "translateX") + pointDis * scale; 
                } else if (translateX < minX){
                  slideItem.handMove = true; 
                  var overW = minX - translateX;
                  var scale = winW/((winW + overW) * 2); // (0, .5) 
                  translateX = css(slideItem, "translateX") + pointDis * scale; 
                }
                css(slideItem, "translateX", translateX)
              })
    
              slideEle.addEventListener("touchend", function() {
                var translateX = css(slideItem, "translateX"); 
                if (!slideItem.handMove) {
                  // 快速滑动 + 橡皮筋效果
                  var speed = pointDis/timeDis; // 速度越大,位移越远
                  speed = Math.abs(speed) < 0.5 ? 0 : speed; // 
                  var targetX = translateX + speed * 200;
                  var time = Math.abs(speed) * 0.2;
                  time = time < 0.8 ? 0.8 : time;
                  time = time > 2 ? 2 : time;
    
                  var bsr = '';
                  if (targetX > 0) {
                    targetX = 0
                    bsr = 'cubic-bezier(.33,1.27,.58,1.42)'
                  } else if (targetX < minX){
                    targetX = minX
                    bsr = 'cubic-bezier(.33,1.27,.58,1.42)'
                  }
                  slideItem.style.transition = time + "s " + bsr + " transform"; 
                  css(slideItem, "translateX", targetX)
                } else {  
                  // 普通滑动
                  if (translateX > 0) {
                    translateX = 0
                  } else if (translateX < minX){
                    translateX = minX
                  }
                  slideItem.style.transition = "1s transform";
                  css(slideItem, "translateX", translateX)
                }
              }) 
            }
          };
        </script>
      </head>
      <body>
        <div class="slide-nav">
       		<ul class="items">
                <li>新闻</li>
                <li>电视剧</li>
                <li>在线热点</li>
                <li>预览</li>
                <li>我</li>
                <li>职场信息</li>
                <li>最新资讯</li>
                <li>新风向</li>
                <li>娱乐圈</li>
                <li>信用</li>
        		<li>周边房价</li>
        	</ul>
        </div>
      </body>
    </html>
    

    CSS 实现 贝塞尔曲线(cubic-bezier) 运动

    贝塞尔曲线运动

    animation: 1s cubic-bezier(.31,1.13,.41,1.39) transform;
    

    媒体查询

    什么是媒体查询:查询屏幕类型和屏幕大小;
    为何要媒体查询:为了兼容,根据屏幕大小写样式
    媒体类型:

    • all:默认类型,表示全部的
    • screen:浏览器页面
    • print:打印页面
    • speech:正对残障人士设计的
    // min-width规则为: 当媒体类型 大于或等于 指定的宽度时, 大括号内的样式生效
    @media screen and (min- 900px) {
    	...
    }
    // max-width规则为: 当媒体类型 小于或等于 指定的宽度时,大括号内的样式生效
    @media screen and (max- 900px) {
    	...
    }
    

    媒体查询中的逻辑:

    • 与 (and)
    • 或 (,)
    • 非 (not)
    // 同时设置多个媒体特性
    // 最大宽度为1000px, 最小宽度为700px。大于等于700px且小于等于1000px的范围内设置生效
    @media screen and (max- 1000px) and (min- 700px) {
    	...
    }
    // 
    

    根据设备尺寸加载不同的样式表:

    // 根据屏幕设备的尺寸来设置相应的样式 
    <link rel="stylesheet" media="screen and (max-device-weidth:480px)" href="iphone.css" />
    
  • 相关阅读:
    mvc3在各个IIS版本中的部署
    linq学习
    常用的正则表达式
    Jenkins+Git+Maven+Tomcat的初步学习
    12个用得着的JQuery代码片段
    JQuery原理介绍及学习方法
    【前端学习】javascript面向对象编程(继承和复用)
    c# throw和throw ex
    .net 信息采集ajax数据
    C# FileSystemWatcher 并发
  • 原文地址:https://www.cnblogs.com/yuxi2018/p/14855213.html
Copyright © 2011-2022 走看看