H5 移动开发经验积累

CSS

1、-webkit-overflow-scrolling : touch;
IOS下用这个属性可以实现流畅滑动,但要注意和这几个属性一起用(Android上还是略卡)

.container{
   -webkit-overflow-scrolling : touch; 
   overflow-y:auto;
    height:固定高度
}

如果.container有同级元素,且该元素用fixed定位,那么.container也必须使用定位属性,且设置z-index值,否则该属性可能不会生效。
注:Android下要实现类似流畅滑动,可尝试使用iScroll.js,地址在这

2、实用css

-webkit-tap-highlight-color: rgba(0,0,0,0);            //去除点击阴影,IOS私有
user-select:none;         //禁止用户选择文本
-webkit-touch-callout: none   //禁止图片长按弹出菜单,img和a标签都要加
pointer-events: none;            //禁止一切鼠标事件
-webkit-appearance: none;   //消除输入框和按钮的原生外观
// 实现谷歌浏览器支持<12px字体,比如显示7px,可采用如下方案
.test_tag{  
    font-size:12px;  
    -webkit-transform-origin-x: 0;  
    -webkit-transform: scale(0.5833333333333334);   //  7/12=0.5833
}  

3、高请显示图片问题 image-set,最好用SVG来做
 image-set解决苹果的高请显示图片问题,不支持image-set的浏览器下,他们解析background-image中的背景图像;支持image-set:
            如果你的浏览器支持image-set,而是普通屏下,此时浏览器选择image-set中1x背景图像
            如果你的设备是高清屏幕下(ppi大于320时)时浏览器会选择image-set中@2x背景图像。
            仅支持background-image属性,而不能使用在''标签中,老的安卓4.4以下的不支持
            优点:image-set不需要告诉浏览器使用什么图像,而是直接提供了图像让浏览器选择
```javascript
    selector{
        background-image:url(no-image-set.png);
        background:image-set(url(foo-lowres.png) 1x,url(foo-highres.png) 2x) center;
    }

4、1px 边框方案

@mixin border-1px ($color) {
    position:relative;
    &::after{
        diplay:block;
        position:absolute;
        content:"";
        left:0;
        bottom:0;
        width:100%;
        border-top:1px solid $color;
    }
    @media(-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5){
        &::after{
            -webkit-transform:scaleY(0.7);
            transform:scaleY(0.7);
        }
    }
    @media(-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2){
        &::after{
            -webkit-transform:scaleY(0.5);
            transform:scaleY(0.5);
        }
    }
    @media(-webkit-min-device-pixel-ratio:3),(min-device-pixel-ratio:3){
        &::after{
            -webkit-transform:scaleY(0.33);
            transform:scaleY(0.33);
        }
    }
}

5、移动端垂直居中问题(带四周边框)
为了兼容IOS和Android,可设置line-height比height少1-2个像素,flex都不好使的

6、做弹窗时,会涉及到z-index问题,最好将弹窗的div层级与主内容并列

7、伪类与伪元素的区别:有没有创建一个文档树之外的元素

8、~ 与 + 选择器的区别: + 是选中紧挨其后的兄弟元素,~是选中其后的兄弟元素,不一定紧挨

9、页面出现垂直方向滚动条时抖动问题
原理是:vw取的是window.innerWidth,包含滚动条;100%不包含滚动条

.wrap-outer {
    margin-left: calc(100vw - 100%);
}

10、父元素设置了左右padding,子元素想突破这个padding,怎么做?

.parent{
    overflow-x:hidden; //消除水平方向由于滚动条导致的微小偏移
}
.child{
    position:relative;
    width:100vw;
    left: calc((100% - 100vw) / 2);
}

JS

1、事件代理是个好的事件处理技巧,但是要特别注意代理元素的选取,一般选取body,如果出现这种层级结构body>main>button,且main设置了opacity:1,那么想在body上代理button的点击事件是做不到的,因为body被main挡住了(PC端不会,但移动端会),解决方式是将代理设到main元素上,其实这个问题的根源在于opacity会挡住比他层级底的元素,使得事件冒泡无法进行。此外不要重复执行绑定操作,否则会被绑定多次(场景:A页面跳到B页面,在B页面做了修改A页面数据的操作,修改完返回到A页面,A页面需要重新拉数据渲染页面。这时应该只执行页面渲染操作,不能再执行事件绑定操作),浏览器对匿名函数的绑定会重复绑定,对命名函数的绑定不会多次绑定。

2、monitorEvents(dom,eventName),可以模拟某元素上所有事件


eventName可取值.png

3、webpack设置代理问题:


代理路径.png

不能把backend放在backend2前面,根源在于不能使用正则匹配,导致/backend2会被/backend代理。

4、正则
要写一个复杂的正则,不一定要写成一个完整的形式;还可以通过分步的形式来实现,比如

var hasNumberReg = /[0-9]/g,
      hasLetterReg = /[a-zA-Z]/g,
      hasSpecialReg = /[~!@#¥\$%\^&\*\(\)-_+=:;'",\.\<\>\/\|\\?\[\]{}]/g;
// 必须包含字母数字和特殊符号的密码,可以这样分步写
hasNumberReg.test(value) && hasLetterReg.test(value)&&hasSpecialReg.test(value)

5、REM布局
设置html的font-size时机要很早才不会有闪烁的感觉,直接在head里内联以下脚本即可,rem布局可能会产生小数像素问题,这会导致使用background-img时被裁掉一点,解决方案是设置background-img时注意留点空白,也就1px的事情,具体参看这里


6、对于scroll事件或mousewheel事件,使用passive模式的监听器,可使滑动更顺畅。如何不择手段提升scroll事件的性能

window.addEventListeners('scroll',handler,{passive:true})
兼容性

7、DOMContentLoaded(蓝线),Loaded(红线),First Paint(绿线)


image.png

First Paint 一般位于二者之间,但最好在DOMContentLoaded之前
对于defer的js文件会在DOMContentLoaded之前执行。js执行期间与页面渲染是一个竞态,若js操作了dom,以往的渲染会被取消。这个问题在首屏的骨架屏需要注意

8、函数节流throttle和防抖debounce
节流:保证m时间内必定执行一次,如图片懒加载,不希望滑动停止时才开始加载,而是在滑动过程中就要开始加载
防抖:m时间内触发多次只执行一次,如scroll,resize等事件的触发

// 简单的节流函数
function throttle(func, wait, mustRun) {
    var timeout,
        startTime = new Date();
 
    return function() {
        var context = this,
            args = arguments,
            curTime = new Date();
 
        clearTimeout(timeout);
        // 如果达到了规定的触发时间间隔,触发 handler
        if(curTime - startTime >= mustRun){
            func.apply(context,args);
            startTime = curTime;
        // 没达到触发间隔,重新设定定时器
        }else{
            timeout = setTimeout(func, wait);
        }
    };
};
// 简单的防抖动函数
function debounce(func, wait) {
    // 定时器变量
    var timeout;
    return function() {
        // 每次触发 scroll handler 时先清除定时器
        clearTimeout(timeout);
        // 指定 xx ms 后触发真正想进行的操作 handler
        timeout = setTimeout(func, wait);
    };
};

9、webworker使用方式

// in html

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce blandit tristique risus, a rhoncus nisl posuere sed. Praesent vel lorem.

// in webworkers.js function isPrime(number) { if (number === 0 || number === 1) { return true; } var i; for (i = 2; i <= Math.sqrt(number); i++) { if (number % i === 0) { return false; } } return true; } // this is the point of entry for the workers onmessage = function(e) { // you can support different messages by checking the e.data value number = e.data; result = isPrime(number); // calling back the main thread postMessage(result); };

10、requestAnimationFrame提升滚动动画

const newScrollTop = this.getPosition(this.panes[index].$refs.content).top - this.distance
function scrollStep() {
    document.documentElement.scrollTop += 5
    if (document.documentElement.scrollTop < newScrollTop) {
        window.requestAnimationFrame(scrollStep)
    }
}
window.requestAnimationFrame(scrollStep)

可以将requestAnimationFrame看做一个钩子,刚好卡在浏览器重绘前向我们的操作伸出橄榄枝。实际上它更像定时器,每秒60次执行回调——符合屏幕的刷新频率,遇到耗时长的操作,这个数字会降到30来保证稳定的帧数。

HTML

1、IOS下input问题

  • 输入框被弹起的系统键盘挡住
    当输入框在底部时,往往会使用固定定位fixed,当输入框获得焦点时,系统键盘会弹起,有时键盘会挡住输入框。
    解决办法:当输入框获得焦点时,用setInterval定时器不断调整input上方元素的scrollTop
    当输入框失去焦点时,取消该setInterval定时器
  • 输入框弹起后,点返回按钮键盘没有收起
    解决方法:路由切换时,使用document.activeElement.blur()手动触发blur事件
  • input几个常用事件
    change:开始输入时触发
    input:每次输入新值都会触发,对于根据input是否有内容来实时设置button样式很有用
    关于手机端IOS系统微信中虚拟键盘遮挡input输入框问题的解决方案
    IOS fixed input focus bug

2、使用content做一个三个点加载动画
本技巧来源于这里

订单提交中...
dot {
    display: inline-block; 
    height: 1em; line-height: 1;
    vertical-align: -.25em;
    overflow: hidden;
}
dot::before {
    display: block;
    content: '...\A..\A.';
    white-space: pre-wrap;
    animation: dot 3s infinite step-start both;
}
@keyframes dot {
    33% { transform: translateY(-2em); }
    66% { transform: translateY(-1em); }
}

原理:1 \A可以换行;2 before元素可以覆盖其寄生元素;3 用动画调整每次显示的content;4 不支持animation时只显示三个点(优雅降级&渐进增强)

3、PC端分享到微博、QQ空间、微信的做法

  • 分享到微博
function shareToXl(title,url,picurl){
      var sharesinastring='http://v.t.sina.com.cn/share/share.php?title='+title+'&url='+url+'&content=utf-8&sourceUrl='+url+'&pic='+picurl;
      window.open(sharesinastring,'newWindowName','height=400,width=400,top=100,left=100');
}
  • 分享到QQ空间
function shareToQq(title,url,picurl){
    var shareqqzonestring='http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?summary='+title+'&url='+url+'&pics='+picurl;
    window.open(shareqqzonestring,'newwindow','height=400,width=400,top=100,left=100');
}
  • 分享到微信
    将要分享的网页链接URL转成二维码,让用户扫二维码进入微信WebView进行分享

移动端开发踩过的一些坑](https://www.zhihu.com/people/qiangdada520)
](https://zhuanlan.zhihu.com/p/30419351?utm_source=com.jianshu.haruki&utm_medium=social)

你可能感兴趣的:(H5 移动开发经验积累)