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属性,而不能使用在'<img>'标签中,老的安卓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的事情,具体参看这里

<script>
(function(doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        recalc = function() {
            var clientWidth = docEl.clientWidth;
            if (!clientWidth) return;
            docEl.style.fontSize = clientWidth / 7.5 + 'px';
        };
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    recalc();
})(document, window);
    </script>

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
<script type="text/javascript">
// we will use this function in-line in this page
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;
}

// a large number, so that the computation time is sensible
var number = "1000001111111111";
// including the worker's code
var w = new Worker('webworkers.js');
// the callback for the worker to call
w.onmessage = function(e) {
    if (e.data) {
        alert(number + ' is prime. Now I\'ll try calculating without a web worker.');
        var result = isPrime(number);
        if (result) {
            alert('I am sure, it is prime. ');
        }
    } else {
        alert(number + ' is not prime.');
    }
};
// sending a message to the worker in order to start it
w.postMessage(number);

</script>
<p style="height: 200px; width: 400px; overflow: scroll;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce blandit tristique risus, a rhoncus nisl posuere sed. Praesent vel lorem.
</p>

// 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做一个三个点加载动画
本技巧来源于这里

<a href="javascript:" class="grebtn">订单提交中<dot>...</dot></a>
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)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,478评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 每当自己收拾好心情,想让自己心无杂念,一心只为工作狂的时候,总有那么些不和谐的声音来破坏你好不容易酝酿的热情。 我...
    小谢总阅读 552评论 0 1
  • 不经意间已经下霜了,太阳下山之前如果还没把衣服给收起来,那么就只能等着明天再晒了,不然你等会看看,衣服都落成湿漉...
    默燃0204阅读 207评论 0 0
  • 身体不适,从睡梦中醒来。 世界是寂静的,我赤脚走在地板上,昨天不小心碰倒的一本书,还保持着原来的姿势。我拉开了厚厚...
    不喜灰阅读 437评论 1 3