• 【笔记】web前端琐碎代码学习片段整理


    1.JS设计模式片段

    Function.prototype.addMethod = function (name,fn) {
       this.prototype[name] = fn;
       return this;
    };
    var Methods = function(){};
    Methods.addMethod('checkName',function () {
       //验证姓名
       console.log('姓名');
    }).addMethod('checkEmail',function () {
       //验证邮箱
       console.log('邮箱');
    });
    var m = new Methods();
    m.checkName();
    m.checkEmail();

    2.canvas图片预加载及进度条的实现

    /*star
     *loading模块
     *实现图片的预加载,并显示进度条
     *参数:图片数组对象,加载完成的回调函数
     */
    function loadImages(sources,callback){    
        var loadedImages = 0;    
        var numImages = 0;  
        ctx.font='14px bold';
        ctx.lineWidth=5;
        var clearWidth=canvas.width;
        var clearHeight=canvas.height;
        // get num of sources    
        for (var src in sources) {    
            numImages++;    
        }    
        for (var src in sources) {    
            images[src] = new Image();
            //当一张图片加载完成时执行    
            images[src].onload = function(){ 
                //重绘一个进度条
                ctx.clearRect(0,0,clearWidth,clearHeight);
                ctx.fillText('Loading:'+loadedImages+'/'+numImages,200,280);
                ctx.save();
                ctx.strokeStyle='#555';
                ctx.beginPath();
                ctx.moveTo(200,300);
                ctx.lineTo(600,300);
                ctx.stroke();
                ctx.beginPath();
                ctx.restore();
                ctx.moveTo(200,300);
                ctx.lineTo(loadedImages/numImages*400+200,300);  
                ctx.stroke();
                //当所有图片加载完成时,执行回调函数callback
                if (++loadedImages >= numImages) {    
                    callback();    
                }    
            };  
            //把sources中的图片信息导入images数组  
            images[src].src = sources[src];    
        }    
    }    
    //定义预加载图片数组对象,执行loading模块
    window.onload = function(){    
        var sources = {    
            PaperBoy1: "images/run/PaperBoy1.png",    
            PaperBoy2: "images/run/PaperBoy2.png", 
            PaperBoy3: "images/run/PaperBoy3.png",    
            PaperBoy4: "images/run/PaperBoy4.png" 
        };    
        //执行图片预加载,加载完成后执行main
        loadImages(sources,main);    
    };   
    /*end*/

    3.JS实现跨浏览器添加事件与移除事件怎样做才最优?

    一般的兼容做法,如下:

    跨浏览器添加事件

    //跨浏览器添加事件
        function addEvent(obj,type,fn){
            if(obj.addEventListener){
                obj.addEventListener(type,fn,false);
            }else if(obj.attachEvent){//IE
                obj.attchEvent('on'+type,fn);
            }
        }

    跨浏览器移除事件

    //跨浏览器移除事件
    function removeEvent(obj,type,fn){
        if(obj.removeEventListener){
            obj.removeEventListener(type,fn,false);
        }else if(obj.detachEvent){//兼容IE
            obj.detachEvent('on'+type,fn);
        }
    }

    推荐写法

        function addEvent( obj, type, fn ) {
          if ( obj.attachEvent ) {
            obj['e'+type+fn] = fn;
            obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
            obj.attachEvent( 'on'+type, obj[type+fn] );
          } else
            obj.addEventListener( type, fn, false );
        }
        function removeEvent( obj, type, fn ) {
          if ( obj.detachEvent ) {
            obj.detachEvent( 'on'+type, obj[type+fn] );
            obj[type+fn] = null;
          } else
            obj.removeEventListener( type, fn, false );
        }

    参考地址:

    addEvent() recoding contest entry

    addEvent() – Follow Up

    4.Ajax用jsonp方式跨域发送请求小实例

    众所周知,Ajax是通过创建XMLHttpRequest对象或ActiveXObject来连接服务器、发送请求以及响应数据,但它却不能跨域。而在分布式系统中我们又需要跨域发送接受数据,于是jsonp出现了...

    它是一种跨域请求方式,主要利用了script标签里的src属性,该属性可以跨域发送请求,然后服务器返回js代码,网页端便响应其信息,然后我们可以对其传过来的js代码做处理提取其中的信息。

    jsonp发送请求只需在src后面添加“?callback=函数名”就可以,例如“http://www.item.com/list?callback=myfunction",则只需在服务端接受参数myfunction并将函数名与想要返回的数据拼接就可以例如在java中响应该请求,可以获取参数callback的值myfunction,再拼接成myfunction+"("+data+")"格式返回就行,在前端写同名函数接受data并处理就可以了。但在jquery中对jsonp进行了封装,返回函数就是success,数据也用success接受。

    例如:

    前端代码:

    //发送请求  
    $.ajax({  
       //url:"http://localhost:8081/rest/itemcat/list?callback=getMessage",  
        url:"http://localhost:8081/rest/itemcat/message",      
        type:"get",  
        cache:false,  
        dataType:"jsonp",  
        jsonp:"callback", //这里定义了callback的参数名称,以便服务获取callback的函数名即getMessage  
        jsonpCallback:"getMessage", //这里定义了jsonp的回调函数  
        success:function(data){  
            alert("success:"+data);  
        },  
        error:function(){  
            alert("发生异常");  
        }  
    });  
    
    function getMessage(jsonp){  
        alert("message:"+jsonp);  
    }

    这样发出的请求为:http://localhost:8081/rest/itemcat/message?callback=getMessage
    jsonp:"callback",
    jsonpCallback:"getMessage",
    这两个参数的值会自动拼接在url后面,所以用jquery的$.ajax方法发出的url可以不用在后面添加callback=getMessag,返回函数则变为了success而不是getMessage

    5.使用高德地图API创建地图以及获取当前地址经纬度

    创建API地图带有点标记

    <script src="http://webapi.amap.com/maps?v=1.4.1&key=bcf87f3263f98cc37309298bca20c622"></script>
    <script type="text/javascript">
        // 实例化点标记
     function addMarker() {
            marker = new AMap.Marker({
                icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
                position: [116.41, 39.91]
            });
            marker.setMap(map);
        }
    
     var map = new AMap.Map('container', {
            resizeEnable: true,
            center: [116.40, 39.91],
            zoom: 13
        });
     addMarker();
    </script>

    根据浏览器定位获取当前经纬度

    <div id="container_display"></div>
    <script src="https://webapi.amap.com/maps?v=1.4.1&key=bcf87f3263f98cc37309298bca20c622"></script>
    <script>
    function loadingCurrentPosition(callback){
        
        document.getElementById('container_display').innerHTML = '';
          //加载地图,调用浏览器定位服务
        map = new AMap.Map('container_display', {
            resizeEnable: true
        });
        map.plugin('AMap.Geolocation', function() {
            geolocation = new AMap.Geolocation({
                enableHighAccuracy: true,//是否使用高精度定位,默认:true
                timeout: 10000,          //超过10秒后停止定位,默认:无穷大
                buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
                zoomToAccuracy: true,      //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
                buttonPosition:'RB'
            });
            map.addControl(geolocation);
            geolocation.getCurrentPosition();
            AMap.event.addListener(geolocation, 'complete', onComplete);//返回定位信息
            AMap.event.addListener(geolocation, 'error', onError);      //返回定位出错信息
        });
        //解析定位结果
        function onComplete(data) {
            var getLngdata = data.position.getLng();
            var getLatdata = data.position.getLat();
            if(callback){
                callback(getLngdata,getLatdata); //回调参数中传递经度与纬度
            }
        }
        //解析定位错误信息
        function onError(data) {
            alert('定位失败');
        }
    }
    
    $(function(){
        var getLng = ''; //存经度
        var getLat = ''; //存纬度
        //默认加载一次自动获取当前人的位置
        loadingCurrentPosition(function(lngdata,Latdata){
            getLng = lngdata;
            getLat = Latdata;
        });
        $(".getCurrentPosition").on('click',function(){
            loadingCurrentPosition(function(lngdata,Latdata){
                getLng = lngdata;
                getLat = Latdata;
            });
        });
    })
    
    </script>

    高德地图根据浏览器定位获取当前经纬度API案例地址:http://lbs.amap.com/api/javascript-api/example/location/browser-location
    高德开放平台:http://lbs.amap.com/api

    6.JS创建canvas学习小例代码

    1.HTML5中的Canvas标签的创建

    window.onload = function(){
         createCanvas();
    }
    function createCanvas(){
        var canvas_width= 200, canvas_height = 200;
        document.body.innerHTML = "<canvas id="canvas" width=""+canvas_width+"" height=""+canvas_height+""></canvas>";
    }

    2.HTML5Canvas标签绘制图形

    var canvas_width= 500, canvas_height = 500;
    var mycanvas, context;
    window.onload = function(){
        createCanvas();
        drawRect();
    }
    function createCanvas(){
       document.body.innerHTML = "<canvas id="mycanvas" width=""+canvas_width+"" height=""+canvas_height+""></canvas>";
       mycanvas = document.getElementById("mycanvas");
       context = mycanvas.getContext("2d");
    }
     
    function drawRect(){
        context.fillStyle ="#FF0000";
        //context.rotate(45);//旋转45度
        //context.translate(200,200);//移动
        //context.scale(2,0.5);//缩放
        context.fillRect(0,0,200,200);
     }

    3.HTML5Canvas标签绘制图片

    var canvas_width= 500, canvas_height = 500;
    var mycanvas, context;
    window.onload = function(){
        createCanvas();
        drawImage();
    }
    function createCanvas(){
        document.body.innerHTML = "<canvas id="mycanvas" width=""+canvas_width+"" height=""+canvas_height+""></canvas>";
        mycanvas = document.getElementById("mycanvas");
        context = mycanvas.getContext("2d");
    }
     
    function drawImage(){
        var img = new Image();
        img.onload = function(){
            context.drawImage(img,0,0);
        }
         img.src = "1.png";
    }

     7.Promise里的代码为什么比setTimeout先执行实例

    Promise和setTimeout实例

    我们把宿主发起的任务称为宏观任务,把 JavaScript 引擎发起的任务称为微观任务。许多的微观任务的队列组成了宏观任务。

    为了理解微任务始终先于宏任务,我们设计一个实验:执行一个耗时 1 秒的 Promise。

    setTimeout(()=> console.log('d'),0);
    var r = new Promise(function(resolve,reject){
        resolve();
    });
    
    r.then(() => {
        var begin = Date.now();
        while(Date.now() - begin < 1000);
        console.log("c1");
        
        new Promise(function(resolve,reject){
            resolve();
        }).then(() => console.log("c2"));
        
    })
    //c1 c2 d

    这里我们强制了 1 秒的执行耗时,这样,我们可以确保任务 c2 是在 d 之后被添加到任务队列。

    我们可以看到,即使耗时一秒的 c1 执行完毕,再 enque 的 c2,仍然先于 d 执行了,这很好地解释了微任务优先的原理。

    再看一个复杂点的例子:

    function sleep(duration) {
        return new Promise(function(resolve, reject) {
            console.log("b");
            setTimeout(resolve,duration);
        })
    }
    console.log("a");
    sleep(5000).then(()=>console.log("c"));
    
    //a b c

    这是一段非常常用的封装方法,利用 Promise 把 setTimeout 封装成可以用于异步的函数。

    我们首先来看,setTimeout 把整个代码分割成了 2 个宏观任务,这里不论是 5 秒还是 0 秒,都是一样的。

    第一个宏观任务中,包含了先后同步执行的 console.log(“a”); 和 console.log(“b”);。

    setTimeout 后,第二个宏观任务执行调用了 resolve,然后 then 中的代码异步得到执行,所以调用了 console.log(“c”),最终输出的顺序才是: a b c。

    Promise 是 JavaScript 中的一个定义,但是实际编写代码时,我们可以发现,它似乎并不比回调的方式书写更简单,但是从 ES6 开始,我们有了 async/await,这个语法改进跟 Promise 配合,能够有效地改善代码结构。

    新特性:async/await

    async/await 是 ES2016 新加入的特性,它提供了用 for、if 等代码结构来编写异步的方式。它的运行时基础是 Promise,面对这种比较新的特性,我们先来看一下基本用法。

    async 函数必定返回 Promise,我们把所有返回 Promise 的函数都可以认为是异步函数。

    async 函数是一种特殊语法,特征是在 function 关键字之前加上 async 关键字,这样,就定义了一个 async 函数,我们可以在其中使用 await 来等待一个 Promise。

    function sleep(duration) {
        return new Promise(function(resolve, reject) {
            setTimeout(resolve,duration);
        })
    }
    async function foo(){
        console.log("a")
        await sleep(2000)
        console.log("b")
    }
    
    foo();  //a b

    这段代码利用了我们之前定义的 sleep 函数。在异步函数 foo 中,我们调用 sleep。

    async 函数强大之处在于,它是可以嵌套的。我们在定义了一批原子操作的情况下,可以利用 async 函数组合出新的 async 函数。

    function sleep(duration) {
        return new Promise(function(resolve, reject) {
            setTimeout(resolve,duration);
        })
    }
    async function foo(name){
        await sleep(2000)
        console.log(name);
    }
    
    async function foo2(){
        await foo('a');
        await foo('b');
    }
    
    foo2(); //a b

     练习:我们现在要实现一个红绿灯,把一个圆形 div 按照绿色 3 秒,黄色 1 秒,红色 2 秒循环改变背景色。

    (function (){
        var btn = document.getElementById('status');
        function sleep(duration){
            return new Promise(function(resolve,reject){
                setTimeout(resolve,duration);
            })
        }
        
        async function changeColor(duration,color){
            btn.style.background = color;
            await sleep(duration);
        };
        async function fn(){
            while(true){
                await changeColor(3000,'green');
                await changeColor(1000,'yellow');
                await changeColor(2000,'red');
            }
        } 
        fn();
    })();
  • 相关阅读:
    cesium计算当前地图范围extent以及近似当前层级zoom
    Cesium专栏-雷达遮罩动态扫描(附源码下载)
    Cesium专栏-地形开挖2-任意多边形开挖(附源码下载)
    Cesium 限制相机进入地下
    Cesium专栏-terrain地形、3dtiles模型、gltf模型 高度采样
    GeoTools介绍、环境安装、读取shp文件并显示
    基于vue+leaflet+echart的足迹分享评论平台
    10个JavaScript调试技巧,帮你更好、更快地调试代码
    后台权限管理,看这篇就够了
    编程狮-在线工具
  • 原文地址:https://www.cnblogs.com/moqiutao/p/9872054.html
Copyright © 2020-2023  润新知