• 兼容和Error捕获


    兼容

    IE兼容

    • ie没有forEach
    if(!Array.prototype.forEach) {
        Array.prototype.forEach = function(fun){
            var len = this.length;
            if(typeof fun != "function"){
                throw new TypeError();
            }
            var thisp = arguments[1];
            for(var i = 0; i < len; i++){
                if (i in this){
                    fun.call(thisp, this[i], i, this);  
                } 
            }
        }
    }  
    
    • ie没有trim
    String.prototype.trim=function(){
        return this.replace(/(^s*)|(s*$)/g,"");
    }  
    
    • ie没有json
    if (!window.JSON) {
        // 添加json对象      
        window.JSON = {
            parse: function(jsonStr) {
                console.log(123)
                return eval('(' + jsonStr + ')');
            },
            stringify: function(jsonObj) {
                var result = '',curVal;
                if (jsonObj === null) {
                    return String(jsonObj);
                }
                switch (typeof jsonObj) {
                    case 'number':
                    case 'boolean':
                        return String(jsonObj);
                    case 'string':
                        return '"' + jsonObj + '"';
                    case 'undefined':
                    case 'function':
                        return undefined;
                }
                switch (Object.prototype.toString.call(jsonObj)) {
                    case '[object Array]':
                        result += '[';
                        for (var i = 0, len = jsonObj.length; i < len; i++) {
                            curVal = JSON.stringify(jsonObj[i]);
                            result += (curVal === undefined ? null : curVal) + ",";
                        }
                        if (result !== '[') {
                            result = result.slice(0, -1);
                        }
                        result += ']';
                        return result;
                    case '[object Date]':
                        return '"' + (jsonObj.toJSON ? jsonObj.toJSON() : jsonObj.toString()) + '"';
                    case '[object RegExp]':
                        return "{}";
                    case '[object Object]':
                        result += '{';
                        for (i in jsonObj) {
                            if (jsonObj.hasOwnProperty(i)) {
                                curVal = JSON.stringify(jsonObj[i]);
                                if (curVal !== undefined) {
                                    result += '"' + i + '":' +curVal + ',';
                                }
                            }
                        }
                        if (result !== '{') {
                            result = result.slice(0, -1);
                        }
                        result += '}';
                        return result;
    
                    case '[object String]':
                        return '"' + jsonObj.toString() + '"';
                    case '[object Number]':
                    case '[object Boolean]':
                        return jsonObj.toString();
                }
            }
        };
    }  
    
    • ie没有xhr(jq做了兼容)
    • ie没有addEventListener(jq做了兼容)
    • ie没有event.stopPropagation(改成e.cancelBubble=true)
    • ie没有event.preventDefault(改成window.event.returnValue = false;//注意加window)
    • ie没有console.log(改成alert)

    苹果手机

    • 苹果手机日期转时间不支持"xxxx-xx-xx",只能用"xxxx/xx/xx"
    • 苹果手机键盘回弹页面不回弹,移动开发软键盘兼容
    document.body.addEventListener('click',function (e) {
       if(e.target.type == "text" || e.target.type == "password" || e.target.tagName == "TEXTAREA" ){
    	var nowTop = document.documentElement.scrollTop || document.body.scrollTop || 0;
    	e.target.addEventListener('blur',mimeBlur)
    	function mimeBlur() {
    	    var e = event || window.event;
    	    e.target.removeEventListener('blur',mimeBlur)
    	    setTimeout(function() {
    		window.scrollTo(0,nowTop);
    	    }, 100);
    	}
       }
    })
    
    • 苹果的画布内容大小不能大于3m (这个无解)
    • 移动端input只读属性在iOS上点击还是有光标
    <input type="text" unselectable="on" οnfοcus="this.blur();" readonly />
    // unselectable属性作用 
    // 在IE浏览器中,当input获得焦点时,点击有unselectable=”on”属性的标签时,不会触发onblur事件。 
    // onfocus=”this.blur()”方法作用 
    // 获取焦点时调用失去焦点事件
    
    • 苹果手机没有window.open方法

    安卓手机

    • 安卓手机的微信分享API不能用1.4的js-sdk(继续用即将废弃的写法)
    • 安卓需要去除300毫秒的双击延迟,原因和解决方案

    所有手机

    • fixed弹窗上添加输入框,点击输入框,如果最底层页面没有滚动条,可以把fixed改成absolute,如果最底层页面有滚动条,弹出的手机键盘会把最底层页面往上推,弹窗却不会上移,导致键盘遮挡输入框,解决方案是记录页面的滚动高度,把底层页面设置超出隐藏禁止滚动,等关闭弹窗再恢复滚动,并自动滚动到原位置,下面附上小程序的代码,原生js同理进行修改就行
    <view style="{{hide ? 'height:100vh;overflow:hidden;' : ''}}">
       ...
    </view>
    <van-popup
      show="{{ showMask }}"
      bind:close="closeMask">
      <input value="{{ value }}" />
    </van-popup>
    
    data:{
       scrollTop: 0,
       scrollTop2: 0,
       hide: false,
       showMask: false,
       value: "在fixed里的输入框"
    },
    // 页面滚动触发事件的处理函数
    onPageScroll: function (e) {
      this.setData({
        scrollTop: e.scrollTop
      })
    },
    openMask:function(){
      this.setData({
        hide: true,
        showMask: true,
        scrollTop2: this.data.scrollTop
      })
    },
    closeMask:function(){
      this.setData({
        hide: false,
        showMask: false,
      })
      wx.pageScrollTo({
          scrollTop: this.data.scrollTop2,
          duration: 0
      })
    },
    
    • 滚动穿透,就是有一个弹窗,滚动到顶端和底端再接着滚动会变成滚动页面的滚动条,所以需要去阻止A层的滚动事件,但是直接阻止A层的滚动是会导致B也不能滚动,自己亲测,所以有什么时候阻止A的滚动就需要一个全局变量,上代码
    <div class="A" style="position: fixed; 100%;height: 100%;overflow: hidden;top: 0;left: 0;background-color: rgba(100,100,100,0.5);"> 
      <div class="B" style="position: absolute;  80%;height:50%;left: 50%; top: 50%;transform: translate(-50%,-50%);overflow: scroll;">
         <div>
    	<div style="height: 100vh;"></div>
    	<div style="height: 100vh;"></div>
         </div>
      </div>
    </div>
    
    var y = 0;
    var flag = true;
    function ts(){
        y = event.targetTouches[0].clientY
        flag = false;
    }
    
    function tm(){
        var top = this.scrollTop
        // 这里取的是第一个子元素,所以不管B里面放多少东西,都要用个div装在一起 
        var ch = $(this).children().eq(0).height()
        var h =  $(this).height()
        if(event.targetTouches[0].clientY < y){
            // 向下
            if(top > ch - h - 50){
                event.preventDefault()
            }
        }else{
            // 向上
            if(top < 50){
                event.preventDefault()
            }
        }
        y = event.targetTouches[0].clientY
    }
    function te(){
        flag = true
    }
    
    function ftm(){
        if(flag){
            event.preventDefault()
        }
    }
    
    function addtouchFun(className,flagClass) {
        $('.'+className).on('touchstart',ts)
        $('.'+className).on('touchmove',tm)
        $('.'+className).on('touchend',te)
        if(flagClass){
            $('.'+flagClass).on('touchmove',ftm)
        }
    }
    
    // 使用
    addtouchFun('B','A')
    

    微信浏览器

    • 手机端和微信端添加了autoplay以后还是不可以自动播放,这是因为手机端为了节约流量所设置的
    //这也不行就得用接口签名之后再ready里执行play了
    document.addEventListener("WeixinJSBridgeReady", function () {
         audio.play();
    }, false);
    
    • 微信的reload刷新地址无效
    // location.reload()无效
    location.href = location.href  + '_t=' + new Date().getTime()
    

    上面的是开发过程中遇到的,其他文章有
    移动开发兼容问题整理笔记
    浏览器兼容性问题解决方案
    渔人码头的经验

    错误捕获

    文章来自
    错误拦截插件,付费

    常见错误

    • JS 语法错误、代码异常
    • AJAX 请求异常
    • 静态资源加载异常
    • Promise 异常
    • Iframe 异常
    • 跨域 Script error
    • 崩溃和卡顿

    错误捕获方式

    • 可疑区域增加 Try-Catch,try-catch 只能捕获到同步的运行时错误,对语法和异步错误却无能为力,捕获不到
    • 全局监控 JS 异常 window.onerror,onerror最好写在所有 JS 脚本的前面,否则有可能捕获不到错误
    /**
    * @param {String}  message    错误信息
    * @param {String}  source    出错文件
    * @param {Number}  lineno    行号
    * @param {Number}  colno    列号
    * @param {Object}  error  Error对象(对象)
    */
    window.onerror = function(message, source, lineno, colno, error) {
       console.log('捕获到异常:',{message, source, lineno, colno, error});
    }
    
    • 全局监控静态资源异常 window.addEventListener
    window.addEventListener('error', (error) => {
        console.log('捕获到异常:', error);
    }, true)
    
    • 捕获没有 Catch 的 Promise 异常:unhandledrejection
    window.addEventListener("unhandledrejection", function(e){
      e.preventDefault()
      console.log('捕获到异常:', e);
      return true;
    });
    
    • VUE errorHandler 和 React componentDidCatch
    Vue.config.errorHandler = (err, vm, info) => {
      console.error('通过vue errorHandler捕获的错误');
      console.error(err);
      console.error(vm);
      console.error(info);
    }
    
    • 监控网页崩溃:window 对象的 load 和 beforeunload
    • 跨域 crossOrigin 解决
  • 相关阅读:
    重构drf后的环境变量配置
    分离的前后台交互
    虚拟环境的搭建
    Python
    Python
    Python
    Python操作MongoDb数据库
    Python操作SQLite/MySQL/LMDB
    数据库-如何创建SQL Server身份验证用户
    Python
  • 原文地址:https://www.cnblogs.com/pengdt/p/12072487.html
Copyright © 2020-2023  润新知