移動端的前端問題

這裏主要回顧和記錄以前在app項目中所碰到的一些問題,以及須要注意的地方。若有錯誤請指出,虛心求教!css

首先咱們是採用phonegap(cordova) 調用底層插件實現ios,android的一套兼容。html

1.

做爲移動端適配問題就一個重點,ios,android的dpr不一樣展示出現的內容也不一樣,因此採用了手淘Flexible的方案,使用rem進行適配。android

;(function(win, lib) {
    var doc = win.document;
    var docEl = doc.documentElement;
    var metaEl = doc.querySelector('meta[name="viewport"]');
    var flexibleEl = doc.querySelector('meta[name="flexible"]');
    var dpr = 0;
    var scale = 0;
    var tid;
    var flexible = lib.flexible || (lib.flexible = {});
    
    if (metaEl) {
        console.warn('將根據已有的meta標籤來設置縮放比例');
        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    } else if (flexibleEl) {
        var content = flexibleEl.getAttribute('content');
        if (content) {
            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
            if (initialDpr) {
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
            if (maximumDpr) {
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
        }
    }

    if (!dpr && !scale) {
        var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
            // iOS下,對於2和3的屏,用2倍的方案,其他的用1倍方案
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // 其餘設備下,仍舊使用1倍的方案
            dpr = 1;
        }
        scale = 1 / dpr;
    }

    docEl.setAttribute('data-dpr', dpr);
    if (!metaEl) {
        metaEl = doc.createElement('meta');
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            var wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

    function refreshRem(){
        var width = docEl.getBoundingClientRect().width;
        if (width / dpr > 540) {
            width = 540 * dpr;
        }
        var rem = width / 10;
        docEl.style.fontSize = rem + 'px';
        flexible.rem = win.rem = rem;
    }

    win.addEventListener('resize', function() {
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300);
    }, false);
    win.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
        }
    }, false);

    if (doc.readyState === 'complete') {
        doc.body.style.fontSize = 12 * dpr + 'px';
    } else {
        doc.addEventListener('DOMContentLoaded', function(e) {
            doc.body.style.fontSize = 12 * dpr + 'px';
        }, false);
    }
    

    refreshRem();

    flexible.dpr = win.dpr = dpr;
    flexible.refreshRem = refreshRem;
    flexible.rem2px = function(d) {
        var val = parseFloat(d) * this.rem;
        if (typeof d === 'string' && d.match(/rem$/)) {
            val += 'px';
        }
        return val;
    }
    flexible.px2rem = function(d) {
        var val = parseFloat(d) / this.rem;
        if (typeof d === 'string' && d.match(/px$/)) {
            val += 'rem';
        }
        return val;
    }

})(window, window['lib'] || (window['lib'] = {}));

下面是引用網上找的源碼,通過一系列的計算後,會在html根節點處添加dpr和font-size。ios

css的寫法:都採用rem,在設計圖是ip6爲基準時,將尺寸/75。web

2.

在項目過程當中有時候須要判斷設備的類型:canvas

var browser = {
    versions: function() {
        var u = navigator.userAgent,
            app = navigator.appVersion;
        return { //移動終端瀏覽器版本信息
            trident: u.indexOf('Trident') > -1, //IE內核
            presto: u.indexOf('Presto') > -1, //opera內核
            webKit: u.indexOf('AppleWebKit') > -1, //蘋果、谷歌內核
            gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐內核
            mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否爲移動終端
            ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios終端
            android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android終端或uc瀏覽器
            iPhone: u.indexOf('iPhone') > -1, //是否爲iPhone或者QQHD瀏覽器
            iPad: u.indexOf('iPad') > -1, //是否iPad
            webApp: u.indexOf('Safari') == -1 //是否web應該程序,沒有頭部與底部
        };
    }(),
    language: (navigator.browserLanguage || navigator.language).toLowerCase()
}

navigator對象屬於BOM ,用於識別客戶端瀏覽器的事實標準,每一個瀏覽器都有一套本身的屬性。跨域

navigator.userAgent:瀏覽器的用戶代理字符串。數組

navigator.appVersion:瀏覽器的版本信息。瀏覽器

3.

1).因爲生成二維碼的格式是base64。因此當咱們要展現二維碼時須要在img中設置格式app

<img src="data:image/png;base64,' + e + '" id=""/>

2).密碼提交在後臺前都須要先md5,最好進行加密一下。

3).在移動端會存在跨域的問題。

採用CORS在後臺程序中,設置Access-Control-Allow-Origin頭部設置了通配符,在進行權限限制。

4.

使用iscroll4.js進行拉上刷新下拉加載,在滑動區域動態添加多條數據時候,滑動該區域會出現卡頓,抖動狀況。

個人解決方法是在每次動態添加完數據改變dom後 就使用wrapper.refresh() 從新計算滑動區域的高度。

還有一種狀況:

就是在當手指從滑動區域一直拖到外部,會出現卡住的狀況,不會回彈。

解決方法實在iscroll.js的490行加個判斷,(若是有問題請指出,有點忘了還改了什麼地方)

if(point.pageY<0 || point.pageY>document.body.clientHeight){        
            this.options.onScrollEnd();        
            this._end(e);        
            this._startAni(e);        
            that._unbind(MOVE_EV, window);        
        }else{        
        }

5.

以前作了一個大轉盤的活動頁,獎品的信息,圖片經過請求獲取,獎品圖片放在大轉盤的每一快區域,是否中獎或者中哪一個獎由後臺接口返回,再控制大轉盤的停留位置。

個人思路是將每一個獎品的相同屬性的值放入數組當中。獲取到中單獎品的id後,獲取它在數組中的索引,經過索引控制旋轉的角度。

在過程當中碰到幾個問題 1.在畫布上放圖片  2.圖片沒法顯示所有。

1.在畫布上放圖片需用到canvas的方法:drawImage() ,它能在畫布上繪製圖像、畫布或視頻。

2.圖片沒法顯示所有的緣由在於,當圖片沒有徹底加載完前就進行描繪,致使了顯示不出,因此須要在圖片徹底加載完後執行描繪。

function draw() {
    var canvas = document.getElementById("wheelcanvas");
    canvas.width = 640;
    canvas.height = 640;
    if(canvas.getContext) {
        //根據獎品個數計算圓周角度
        var arc = Math.PI / (turnplate.restaraunts.length / 2);
        var ctx = canvas.getContext("2d");
        //在給定矩形內清空一個矩形
        ctx.clearRect(0, 0, 640, 640);
        ctx.strokeStyle = "#FFBE04";
        //ctx.font = '30px Microsoft YaHei';
        $.each(turnplate.Imgurl, function(key, value) {
            var img = new Image();
            img.src = value;
            img.onload = function() { //讓圖片加載完畢後執行描繪
                drawTrails()
            }
            function drawTrails() {
                var angle = turnplate.startAngle + key * arc;
                ctx.fillStyle = turnplate.colors[key];
                ctx.beginPath();
                //arc(x,y,r,起始角,結束角,繪製方向) 方法建立弧/曲線(用於建立圓或部分圓)    
                ctx.arc(320, 320, turnplate.outsideRadius, angle, angle + arc, false);
                ctx.arc(320, 320, turnplate.insideRadius, angle + arc, angle, true);
                ctx.stroke();
                ctx.fill();
                //鎖畫布(爲了保存以前的畫布狀態)
                ctx.save();
                
                //ctx.fillStyle = "#FFFFFF"; //字體顏色
                //var text = turnplate.restaraunts[i];
                //var line_height = 17; //字體行距      
                //translate方法從新映射畫布上的 (0,0) 位置
                ctx.translate(320 + Math.cos(angle + arc / 2) * turnplate.textRadius, 320 + Math.sin(angle + arc / 2) * turnplate.textRadius);
                //rotate方法旋轉當前的繪圖
                ctx.rotate(angle + arc / 2 + Math.PI / 2);
                ctx.drawImage(img, -35, -20, 80, 80) //設置圖片的位置及大小
                ctx.restore();
                

            }
        });
    }
}
相關文章
相關標籤/搜索