问题整理

#1 - 微信中不能直接打开itunes的下载地址的问题 ?

知乎文章:https://www.zhihu.com/question/24029212

解决方案:

  • 方案一,申请应用宝,先跳转到应用宝页面,再点击下载根据设备的不同转去 AppStore 或是 Android 的应用宝下载地址。
  • 方案二,在页面前端做处理,如果无法跳转到 AppStore 就提示用户在微信里手动选择用 Safari 打开页面。
  • 方案三,二百二维码里面配置:http://hotapp.cn/?src=http://www.hao2b.cn

#2 - 如何防止网页被恶意嵌套入其他的网页中 ?

// 判断当前的window对象是否是top对象
if (window!=top){

    // 如果不是,将top对象的网址自动导向被嵌入网页的网址
    top.location.href =window.location.href;
}

// 升级版
try{
    top.location.hostname;
        if (top.location.hostname != window.location.hostname) {
                top.location.href =window.location.href;
        }
    }
catch(e){
    top.location.href = window.location.href;
}

#3 - 在iPhone中在li标签下的click事件无效

// 解决方案:

// 方案一,在对应的css中添加cursor:pointer样式
// 方案二,将li标签改成a标签

#4 - 时间日期格式问题

// 时间处理 no = ‘2016-12-12 11:48:20'
formatTime: function(no){
    var date= new Date(no);
    var year = date.getFullYear();
    var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
    var datetime = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
    return year + "-" + month + "-" + datetime;
}

// 表象:
// 上述时间处理在PC游览器端呈现的是正常的。
// 在IOS iphone6s 里面 展现出invalid date的报错

// 解决方案:
// 时间处理 no = ‘2016-12-12 11:48:20’
formatTime: function(no){
    no = no.replace(/-/g,':').replace(' ',':');
    no = no.split(':');
    var date = new Date(no[0],(no[1]-1),no[2],no[3],no[4],no[5]);
    var date= new Date(dateTime);
    var year = date.getFullYear();
    var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
    var datetime = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
    return year + "-" + month + "-" + datetime;
}
// 将no 日期格式转换成 ‘2016-12-12T11:48:20’ 或者 ‘2016/12/12 11:48:20’

#5 - htm5 无刷新改变url地址

// history里面会增加一个记录
window.history.pushState({}, 0, url);

// history替换当前的url记录
window.history.replaceState({}, 0, url);

#6 - 获取cookie

function getCookie(name) {
    var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
    if (arr != null){
        return unescape(arr[2]);
    }else{
        return null;
    };
}

#7 - 如何处理canvas的锯齿问题

最近在做转盘抽奖页面,然后转盘是套用一个插件来做的.插件用的是canvas元素画出来的. 宽度用的是300.然后在手机上会发现存在明显的锯齿现象.度娘 上的解决办法一搜有很多.在这里记录下我成功的解决办法:将canvaswidthheight设置成原来的4倍也就是1200然后将canvaswidth设置成inherit 父容器的宽度根据屏幕大小来在手机屏幕下缩放后锯齿就消失了

以下为参考的原文:

最近在做一个转盘抽奖页面, 然后转盘是使用HTML5的canvas元素画出来的. 然而在几个手机上测试都发现转盘有一点锯齿问题, 而且文字都比较模糊. 除了在上面的canvas标签中设置了width=”422px”,height=”422px”之外, 还在外部链接的CSS样式表中设置了该canvas的宽度为100%, 公司的”导师”告诉我, 这个应该是手机的宽是720像素的, 而这个canvas是按照422像素画出来的, 所以在720像素的手机上显示时, 这个canvas的内容其实是经过拉伸的, 所以会出现模糊和锯齿. 解决方案就是把canvas的行间样式的宽度设为手机端的最大像素值, 因为现在的手机端宽度的最大的只有1080像素宽, 所以我就把canvas的宽度设为422的4倍也就是1688像素, 按照这个像素画完之后, width:100%又会把canvas的宽度缩小至父元素的宽度那么大, 因此整个canvas的宽度被缩小了, 大尺寸的canvas内容被缩小了之后肯定不会产生锯齿现象, 所以这个解决方案也是可以的.

#8 - 获取页面的url参数

var getQuery = function(key){
    var t = {};
    location.search.replace("?","").replace(/&?([^=&]+)=([^=&]*)/g, function($0, $1,$2){ t[$1] = $2; });
    return typeof t[key] === "undefined" ? "" : t[key];
}

#9 - Object.keys() and array.some(callback[, thisObject])

Object.keys(): 返回一个由给定对象的自身可枚举属性组成的数组

array.some(): 测试数组中的某个元素是否通过由提供的功能来实现测试

#10 - 视频获取第一帧预览图

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>capture screen</title>
</head>
<body>
<script src="../src/jq.js"></script>
<style>
    .row{width: 100%; clear: both;}
    .w50{width: 50%; float: left;}
    .w50 video{max-width: 100%;}
</style>
<input id="file" name="file" type="file" value="" placeholder="点击上传" />
<div class="row">
    <div id="video" class="w50"></div>
    <div id="imgSmallView" class="w50"></div>
</div>
</body>
<script>
    (function() {
        "use strict";
        $('#file').on('change', function() {
            var files = this.files,
                video = $('#video').find('video'),
                videoURL = null,
                windowURL = window.URL || window.webkitURL;;
            if (files && files[0]) {

                videoURL = windowURL.createObjectURL(files[0]);

                $('#video').html('<video src="' + videoURL + '" controls="controls"></video>');

                setTimeout(function() {
                    createIMG();
                }, 500);

            }
        }).trigger('change');

        var createIMG = function() {
            var scale = 0.25,
                video = $('#video').find('video')[0],
                canvas = document.createElement("canvas"),
                canvasFill = canvas.getContext('2d');
            canvas.width = video.videoWidth * scale;
            canvas.height = video.videoHeight * scale;
            canvasFill.drawImage(video, 0, 0, canvas.width, canvas.height);

            var src = canvas.toDataURL("image/jpeg");
            $('#imgSmallView').html('<img id="imgSmallView" src="' + src + '" alt="预览图" />');
        }

    })()
</script>
</html>

#11 - onpageshow - 监听页面是否是缓存页面

// 以下是几种使用方式:

// 1。直接在HTMl中使用,注意只能在body上进行事件注册

<body onpageshow="myFunction(event)">

<p>该实例演示了如何向 body 元素添加 "onpageshow" 事件。</p>
<h1 id="demo"></h1>
<script>
function myFunction() {

alert("页面是否从浏览器缓存中加载? " + event.persisted);

}
</script>

// 2.JS中通过元素获取绑定在body上

document.getElementsByTagName("BODY")[0].onpageshow = function() {myFunction()};

// 3.在window上注册这个方法

window.addEventListener("pageshow", myFunction);
function myFunction(event) {

alert("页面是否从浏览器缓存中加载? " + event.persisted);
}.

// 通过以上方法,可以满足需求,也能判断当前页面是否是缓存页面。。。event的很多属性都有点意思。

#12 - 在手机端 animation-play-state 无效的解决方法

example:https://codepen.io/HaoyCn/pen/BZZrLd

if (that.isWifi()) {
    // JS绑定自动播放(操作window时,播放音乐)
    $(window).one('touchstart', function(){
        play();
    });
    // 微信下兼容处理
    document.addEventListener("WeixinJSBridgeReady", function () {
        play();
    }, false);
}

function pause() {
    isPlaying = false;
    var iTransform = getComputedStyle(image).transform;
    var cTransform = getComputedStyle(container).transform;
    container.style.transform = cTransform === 'none'
        ? iTransform
        : iTransform.concat(' ', cTransform);
    image.classList.remove('music-on');
    audio.pause();
}

function play() {
    isPlaying = true;
    image.classList.add('music-on');
    audio.play();
}

13 - 快速排序

“快速排序”的思想很简单,整个排序过程只需要三步:

  1. 在数据集之中,找一个基准点
  2. 建立两个数组,分别存储左边和右边的数组
  3. 利用递归进行下次比较
function quickSort(arr){
    if(arr.length<=1){
        return arr;//如果数组只有一个数,就直接返回;
    }

    var num = Math.floor(arr.length/2);//找到中间数的索引值,如果是浮点数,则向下取整

    var numValue = arr.splice(num,1);//找到中间数的值
    var left = [];
    var right = [];

    for(var i=0;i<arr.length;i++){
        if(arr[i]<numValue){
            left.push(arr[i]);//基准点的左边的数传到左边数组
        }
        else{
           right.push(arr[i]);//基准点的右边的数传到右边数组
        }
    }

    return quickSort(left).concat([numValue],quickSort(right));//递归不断重复比较
}

alert(quickSort([32,45,37,16,2,87]));//弹出“2,16,32,37,45,87

14 - 前端精度问题

一般方法(toFixed):

parseFloat((1.0 - 0.9).toFixed(10)) // 结果为 0.1

加法函数:

/**
 ** 加法函数,用来得到精确的加法结果
 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
 ** 调用:accAdd(arg1,arg2)
 ** 返回值:arg1加上arg2的精确结果
 **/
function accAdd(arg1, arg2) {
    var r1, r2, m, c;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    c = Math.abs(r1 - r2);
    m = Math.pow(10, Math.max(r1, r2));
    if (c > 0) {
        var cm = Math.pow(10, c);
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace(".", ""));
            arg2 = Number(arg2.toString().replace(".", "")) * cm;
        } else {
            arg1 = Number(arg1.toString().replace(".", "")) * cm;
            arg2 = Number(arg2.toString().replace(".", ""));
        }
    } else {
        arg1 = Number(arg1.toString().replace(".", ""));
        arg2 = Number(arg2.toString().replace(".", ""));
    }
    return (arg1 + arg2) / m;
}

// 给Number类型增加一个add方法,调用起来更加方便。
Number.prototype.add = function (arg) {
    return accAdd(arg, this);
};

减法函数:

/**
 ** 减法函数,用来得到精确的减法结果
 ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
 ** 调用:accSub(arg1,arg2)
 ** 返回值:arg1加上arg2的精确结果
 **/
function accSub(arg1, arg2) {
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

// 给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.sub = function (arg) {
    return accMul(arg, this);
};

乘法函数:

/**
 ** 乘法函数,用来得到精确的乘法结果
 ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
 ** 调用:accMul(arg1,arg2)
 ** 返回值:arg1乘以 arg2的精确结果
 **/
function accMul(arg1, arg2) {
    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length;
    }
    catch (e) {
    }
    try {
        m += s2.split(".")[1].length;
    }
    catch (e) {
    }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}

// 给Number类型增加一个mul方法,调用起来更加方便。
Number.prototype.mul = function (arg) {
    return accMul(arg, this);
};

除法函数:

/**
 ** 除法函数,用来得到精确的除法结果
 ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
 ** 调用:accDiv(arg1,arg2)
 ** 返回值:arg1除以arg2的精确结果
 **/
function accDiv(arg1, arg2) {
    var t1 = 0, t2 = 0, r1, r2;
    try {
        t1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
    }
    try {
        t2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
    }
    with (Math) {
        r1 = Number(arg1.toString().replace('.', ''));
        r2 = Number(arg2.toString().replace('.', ''));
        return (r1 / r2) * pow(10, t2 - t1);
    }
}

// 给Number类型增加一个div方法,调用起来更加方便。
Number.prototype.div = function (arg) {
    return accDiv(this, arg);
};

15 - JSON.parse(JSON.stringify(object))的问题

// 作为深拷贝的时候,时区、函数和prototype会存在错误。
JSON.parse(JSON.stringify(object))

16 - WebSocket

WebSocket 的长连接会因为 Nginx 的访问超时时间而断开链接。 所以为了解决问题:一般要给出断线重连、心跳检测重连机制

17 - Vue单页面应用会造成页面chunk 0 failed重新刷新下正常。

暂未找到原因

Uncaught SyntaxError: Unexpected token <
Error: Loading chunk 0 failed.
at HTMLScriptElement.onScriptComplete (app.js:99)
[vue-router] Failed to resolve async component default: Error: Loading chunk 0 failed.
Error: Loading chunk 0 failed.
at HTMLScriptElement.onScriptComplete (app.js:99)

目前的解决方法: 可能原因是不支持延迟加载 Vue 组件 解决方法是在 webpack 中加上:

output: {
    publicPath: '/'
}

这个配置就可以了。 具体的效果等待验证。