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();
/*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*/
通常的兼容作法,以下:javascript
跨瀏覽器添加事件html
//跨瀏覽器添加事件 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); } }
推薦寫法java
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 ); }
參考地址:jquery
addEvent()
recoding contest entryweb
衆所周知,Ajax是經過建立XMLHttpRequest對象或ActiveXObject來鏈接服務器、發送請求以及響應數據,但它卻不能跨域。而在分佈式系統中咱們又須要跨域發送接受數據,因而jsonp出現了...json
它是一種跨域請求方式,主要利用了script標籤裏的src屬性,該屬性能夠跨域發送請求,而後服務器返回js代碼,網頁端便響應其信息,而後咱們能夠對其傳過來的js代碼作處理提取其中的信息。canvas
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
<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
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"; }
咱們把宿主發起的任務稱爲宏觀任務,把 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 是 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(); })();