前端基本功-示例代碼(一)

前端基本功-示例代碼 (一) 點這裏
前端基本功-示例代碼 (二) 點這裏javascript

1.ajax

var xhr = new XMLHttpRequest(); // 聲明一個請求對象

// 前端設置是否帶cookie
xhr.withCredentials = true;

xhr.open('GET', 'xxxx');
//xhr.open('post', 'http://www.domain2.com:8080/login', true);

// 如何設置請求頭? xhr.setRequestHeader(header, value);
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){  // readyState 4 表明已向服務器發送請求
        if(xhr.status === 200){ // status 200 表明服務器返回成功
            console.log(xhr.responseText); // 這是返回的文本
        } else{
            console.log("Error: "+ xhr.status); // 鏈接失敗的時候拋出錯誤
        }
    }
}

xhr.send(null); 
//xhr.send('user=admin');
// get方法 send null(亦或者不傳,則直接是傳遞 header) ,post 的 send 則是傳遞值

2.jsonp

1.)原生實現:

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 傳參並指定回調執行函數爲onBack
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
    document.head.appendChild(script);

    // 回調執行函數
    function onBack(res) {
        alert(JSON.stringify(res));
    }
 </script>

服務端返回以下(返回時即執行全局函數):css

onBack({"status": true, "user": "admin"})

2.)jquery ajax:

$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 請求方式爲jsonp
    jsonpCallback: "onBack",    // 自定義回調函數名
    data: {}
});

3.)vue.js:

this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'onBack'
}).then((res) => {
    console.log(res); 
})

4.)npm包jsonp:

npm install jsonp --save
import originJSONP from 'jsonp'   //引入jsonp

//進行封裝並export
export default function jsonp(url,data,option) {
    url += (url.indexOf('?')<0? '?' : '&')+param(data)

    return new Promise((resolve,reject)=>{
        originJSONP(url,option,(err,data)=>{
            if(!err){
                resolve(data)
            }else{
                reject(err)
            }
        })
    })
}

//對data進行處理,並encodeURIComponent()進行轉碼。
function param(data) {
    let url = ''
    for(var k in data) {
          let value = data[k] !== undefined? data[k] : ''
          url += '&' + k + '=' + encodeURIComponent(value)
    }
    return url ? url.substring(1) : ''
}

本節參考文章: vue項目中jsonp跨域獲取qq音樂首頁推薦html

3.實現一個簡單的Promise

Promise對象調用前端

let p =new Promise(function(resolve, reject){
    if(/* 異步操做成功 */){
        resolve(data)
    }else{
        reject(err)
    }
})
p.then((res)=>{
  console.log(res)
},(err)=>{
  console.log(err)
})

實現一個簡單的Promisevue

function Promise(fn){
  var status = 'pending'
  function successNotify(){
      status = 'fulfilled'//狀態變爲fulfilled
      toDoThen.apply(undefined, arguments)//執行回調
  }
  function failNotify(){
      status = 'rejected'//狀態變爲rejected
      toDoThen.apply(undefined, arguments)//執行回調
  }
  function toDoThen(){
      setTimeout(()=>{ // 保證回調是異步執行的
          if(status === 'fulfilled'){
              for(let i =0; i< successArray.length;i ++)    {
                  successArray[i].apply(undefined, arguments)//執行then裏面的回掉函數
              }
          }else if(status === 'rejected'){
              for(let i =0; i< failArray.length;i ++)    {
                  failArray[i].apply(undefined, arguments)//執行then裏面的回掉函數
              }
          }
      })
  }
  var successArray = []
  var failArray = []
  fn.call(undefined, successNotify, failNotify)
  return {
      then: function(successFn, failFn){
          successArray.push(successFn)
          failArray.push(failFn)
          return undefined // 此處應該返回一個Promise
      }
  }
}

解題思路:Promise中的resolve和reject用於改變Promise的狀態和傳參,then中的參數必須是做爲回調執行的函數。所以,當Promise改變狀態以後會調用回調函數,根據狀態的不一樣選擇須要執行的回調函數。java

本節參考文章:面向面試題和實際使用談promisenode

示例2jquery

const PENDING = "pending"; //等待
const FULFILLED = "fulfilled"; //已完成
const REJECTED = "rejected"; // 已拒絕

function Promise(executor) {
    let self = this;
    self.status = PENDING;

    self.value;
    self.reason;


    function resolve(value) {
        if (self.status === PENDING) {
            self.status = FULFILLED;
            self.value = value;
        }
    }

    function reject(reason) {
        if (self.status === PENDING) {
            self.status = REJECTED;
            self.reason = reason;
        }
    }
    try { // 規範提到,執行器拋異常會reject
        executor(resolve, reject);
    } catch(e) {
        reject(e)
    }
}
// then方法實現
Promise.prototype.then = function (onFulfilled, onRjected) {
    let self = this;
    /**
     * onFulfilled 和 onRejected 都是可選參數。
     * 若是 onFulfilled 不是函數,其必須被忽略
     * 若是 onRejected 不是函數,其必須被忽略
     */
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value) {
        return value;
    };
    onRjected = typeof onRjected === 'function' ? onRjected : function(reason) {
        throw reason;
    }
    
    if (self.status === FULFILLED) {
        onFulfilled(self.value);
    }
    if (self.status === REJECTED) {
        onRjected(self.reason);
    }
}

本節參考文章:Javascript Promise學習過程總結web

4.閉包

var fn = function() {
    var divs = document.querySelectorAll('div');
    for (var i = 0; i < 3; i++) {
        divs[i].onclick = (function(i) {
            return function() {
                    alert(i);
            };
        })(i);
    }
};
fn();

或者以下的寫法:面試

var fn = function() {
    var divs = document.querySelectorAll('div');
    for (var i = 0; i < 3; i++) {
        (function(i) {
            divs[i].onclick = function() {
                    alert(i);
            };
        })(i);
    }
};
fn();
for (var i = 0; i < 3; i++) {
    setTimeout((function(i) {
        return function() {
            console.log(i);
        };
    })(i), 0);
    console.log(i);
}

5.事件代理

事件代理(Event Delegation),又稱之爲事件委託。是 JavaScript 中經常使用綁定事件的經常使用技巧。「事件代理」便是把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。 事件代理的原理是DOM元素的事件冒泡
  • 減小事件註冊,節省內存佔用,提升性能
  • 能夠實現當新增子對象時無需再次對其綁定
<div class="wrap" id="wrap">
    <div class="btn" data-type="btn" data-feat="add">添加</div>
    <div class="btn" data-type="btn" data-feat="delete">繪畫</div>
    <div class="btn" data-type="btn" data-feat="delete">散步</div>
    <div class="btn" data-type="btn" data-feat="delete">靜坐</div>
  </div>
  <script type="text/javascript">
    var n = 0
    document.getElementById('wrap').addEventListener('click', function(e) {
      var target = e.target;
      var type = target.dataset.type;
      var feat = target.dataset.feat;

      if (type == 'btn') {
        switch (feat) {
          case 'add':
            this.innerHTML += `<div class="btn" data-type="btn" data-feat="delete">靜坐${n}</div>`
            n++
            return;
          case 'delete':
            target.parentNode.removeChild(target);
            return;
        }
      }

    }, false);
</script>

6.封裝dom查詢(面向對象)

function Elem(id){
  this.elem = document.getElementById(id)
}

 Elem.prototype.html = function(val){
   var elem = this.elem
   if(val) {
     elem.innerHTML = val
     return this  //鏈式
   } else {
     return elem.innerHTML
   }
 }

 Elem.prototype.on = function(type,fn){
   var elem = this.elem
   elem.addEventListener(type, fn)
   return this  //鏈式
 }

//調用
var div = new Elem('id')
div.html('<p>hello</p>').on('click',function(){
  console.log('suceess')
})

7.DOM劫持

function nodeToFragment (node) {
      var flag = document.createDocumentFragment();
      var child;
      // 首先,全部表達式必然會返回一個值,賦值表達式亦不例外
      // 理解了上面這一點,就能理解 while (child = node.firstChild) 這種用法
      // 其次,appendChild 調用之後 child 會從原來 DOM 中移除
      // 因此,第二次循環時,node.firstChild 已經再也不是以前的第一個子元素了
      while (child = node.firstChild) {
        flag.appendChild(child); // 將子節點劫持到文檔片斷中
      }
      return flag
    }

8.添加calssName

// 爲元素添加類名
export function addClass(el, className) {
  // 先判斷一下元素是否含有須要添加的類名,有則直接 return
  if(hasClass(el, className)) {
    return
  }
  // 把該元素含有的類名以空格分割
  let newClass = el.className.split(' ')
  // 把須要的類名 push 進來
  newClass.push(className)
  // 最後以空格拼接
  el.className = newClass.join(' ')
}

// 判斷是否有要查看的 className,有則返回true,不然返回 false
export function hasClass(el, className) {
  let reg = new RegExp('(^|\\s)' + className + '(\\s|$)')

  return reg.test(el.className)
}

9.自動添加遊覽器前綴

let elementStyle = document.createElement('div').style
// 主流瀏覽器內核
let vendor = (() => {
  let transfromNames = {
    webkit: 'webkitTransform',
    Moz: 'MozTransform',
    ms: 'msTransform',
    O: 'OTransform',
    standard: 'transform'
  }
  for(let key in transfromNames) {
    if(elementStyle[transfromNames[key]] !== undefined) {
    
      return key
    }
  }

  return false
})()

// 添加樣式的瀏覽器前綴
export function prefixStyle(style) {
  if(vendor === false) {
    return false
  }

  if(vendor === 'standard') {
    return style
  }

  return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}

10.圖片懶加載

定義:延遲加載也稱爲惰性加載,即在長網頁中延遲加載圖像。用戶滾動到它們以前,視口外的圖像不會加載。這與圖像預加載相反,在長網頁上使用延遲加載將使網頁加載更快。在某些狀況下,它還能夠幫助減小服務器負載。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Lazyload 1</title>
    <style>
        img {
        display: block;
        margin-bottom: 50px;
        height: 200px;
    }
    </style>
</head>
<body>
    <img src="images/loading.gif" data-src="images/1.png">
    <img src="images/loading.gif" data-src="images/2.png">
    <img src="images/loading.gif" data-src="images/3.png">
    <img src="images/loading.gif" data-src="images/4.png">
    <img src="images/loading.gif" data-src="images/5.png">
    <img src="images/loading.gif" data-src="images/6.png">
    <img src="images/loading.gif" data-src="images/7.png">
    <img src="images/loading.gif" data-src="images/8.png">
    <img src="images/loading.gif" data-src="images/9.png">
    <img src="images/loading.gif" data-src="images/10.png">
    <img src="images/loading.gif" data-src="images/11.png">
    <img src="images/loading.gif" data-src="images/12.png">
  <!--  <script>
        var num = document.getElementsByTagName('img').length;
        var img = document.getElementsByTagName("img");
        var n = 0; //存儲圖片加載到的位置,避免每次都從第一張圖片開始遍歷
        lazyload(); //頁面載入完畢加載但是區域內的圖片
        window.onscroll = lazyload;
        function lazyload() { //監聽頁面滾動事件
            var seeHeight = document.documentElement.clientHeight; //可見區域高度
            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滾動條距離頂部高度
            for (var i = n; i < num; i++) {
                if (img[i].offsetTop < seeHeight + scrollTop) {
                    if (img[i].getAttribute("src") == "images/loading.gif") {
                        img[i].src = img[i].getAttribute("data-src");
                    }
                    n = i + 1;
                }
            }
        }
    </script>-->
    //對比一下上下兩種代碼,一個變量是全局變量,一個是函數的局部做用域,
    <script>
        function lazyload() {
            var images = document.getElementsByTagName('img');
            var len    = images.length;
            var n      = 0;      //存儲圖片加載到的位置,避免每次都從第一張圖片開始遍歷        
            return function() {
                var seeHeight = document.documentElement.clientHeight;
                var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                for(var i = n; i < len; i++) {
                    if(images[i].offsetTop < seeHeight + scrollTop) {
                        if(images[i].getAttribute('src') === 'images/loading.gif') {
                          images[i].src = images[i].getAttribute('data-src');
                        }
                        n = n + 1;
                     }
                 }
             }
        }
        
        var loadImages = lazyload();
        
        loadImages();          //初始化首頁的頁面圖片
        
        window.addEventListener('scroll', loadImages, false);
</script>
</body>
</html>

jQuery

<script>
    var n = 0,
        imgNum = $("img").length,
        img = $('img');
    lazyload();
    $(window).scroll(lazyload);
    function lazyload(event) {
        for (var i = n; i < imgNum; i++) {
            if (img.eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())) {
                if (img.eq(i).attr("src") == "default.jpg") {
                    var src = img.eq(i).attr("data-src");
                    img.eq(i).attr("src", src);
                    n = i + 1;
                }
            }
        }
    }
</script>

11.img加載圖片失敗時,使用默認圖片

  • img標籤自帶onError屬性,當圖片加載失敗時,觸發error事件:

    <img src="image.png" onError='this.src="http://ww.jpg"' />

  • jQuery的error事件

    $('img').error(function(){
        $(this).attr('src',"http://ww.jpg");
    });
  • jQuery的one綁定
    使用onerror或者jQuery的error事件時,若是默認圖片也發生加載失敗,則會造成死循環,最好的辦法是使用one綁定事件,只執行一次

    $("img").one("error", function(e){
         $(this).attr("src", "http://ww.jpg");
    });

12.圖片按比例響應式縮放、裁剪

html部分:

<div class="zoomImage" style="background-image:url(images/test1.jpg)"></div>

css部分:

.zoomImage{
    width:100%;
    height:0;
    padding-bottom: 100%;
    overflow:hidden;
    //padding爲百分比的時候根據他父層的寬度來進行計算
    background-position: center center;
    background-repeat: no-repeat;
    -webkit-background-size:cover;
    -moz-background-size:cover;
    //把背景圖像擴展至徹底覆蓋背景區域
    background-size:cover;
}

總結:你所須要的比例,就是width與padding-bottom的比例
用的時候,直接把.zoomImage當成img標籤來用就能夠了。

思惟擴展
不少輪播的插件原本是響應式的, 但可能有兩個問題:
1.這個輪播圖你必需要給他一個高度,但高度不是固定死的,是須要按比例的...
2.輪播圖裏的圖片不是須要的比例...
因此咱們能夠用剛剛上面的padding方法
拿swiper輪播圖插件舉例

優化前

clipboard.png

優化後

clipboard.png

本節詳細:如何讓圖片按比例響應式縮放、並自動裁剪的css技巧

13.選項卡切換

html的結構和樣式:

<style type="text/css">
        #div1 div{
            width: 200px;
            height:200px;
            border: 1px #000 solid;
            display: none;
        }
        .active{
            background: red;
        }
</style>
<body>
    <div id="div1">
        <button class="active">1</button>
        <button>2</button>
        <button>3</button>
        <div style="display: block;">111</div>
        <div>222</div>
        <div>333</div>
    </div>
</body>
//過程式的編程思想
window.onload=function(){
    //獲取元素
    var oParent=document.getElementById('div1');
    var btns=oParent.getElementsByTagName('button');
    var divs=oParent.getElementsByTagName('div');
    //經過循環給每一個btn添加點擊事件
    for (var i = 0; i < btns.length; i++) {
        btns[i].index=i;//存儲當前btn的下標
        btns[i].onclick=function(){
            for (var i = 0; i < btns.length; i++) {
                btns[i].className='';
                divs[i].style.display='none';
            }
            this.className='active';
            divs[this.index].style.display='block';//讓對應當前btn的div顯示
        }
    }
}
//面向對象
window.onload = function(){
    var t1=new Tab();
    t1.init();
};
    
 function Tab() {
     this.btns=oParent.getElementsByTagName('button');
    this.divs=oParent.getElementsByTagName('div');
 }
 
Tab.prototype.init=function(){
    var This=this;
    for (var i = 0; i < this.btns.length; i++) {
        this.btns[i].index=i;
        this.btns[i].onclick=function(){
            This.change(this);
        }
    }
}
Tab.prototype.change=function(btn) {
    for (var i = 0; i < this.btns.length; i++) {
        this.btns[i].className='';
        this.divs[i].style.display='none';
    }
    btn.className='active';
    this.divs[btn.index].style.display='block';
};

14.元素拖拽

#div1{
    width: 100px;
    height: 100px;
    background: red;
    position: absolute;
}
<body>
    <div id='div1'></div>
</body>
//過程式的編程思想
window.onload=function(){
    var oDiv=document.getElementById('div1');
    
    var disX=0;
    var disY=0;

    oDiv.onmousedown=function(ev){
        var ev=ev || window.event;
        disX=ev.clientX-oDiv.offsetLeft;
        disY=ev.clientY-oDiv.offsetTop;

        document.onmousemove=function(ev){
            var ev=ev || window.event;
            oDiv.style.left=ev.clientX-disX+'px';
            oDiv.style.top=ev.clientY-disY+'px';
        };
        document.onmouseup=function(){
            document.onmousemove=null;
            document.onmouseup=null;
        }
        return false;
    }
}
//面向對象
window.onload = function() {
  var d1 = new Drag('div1');
  d1.init();
};

function Drag(id) {
  this.oDiv = document.getElementById(id);
  this.disX = 0;
  this.disY = 0;
}
Drag.prototype.init = function() {
  var This = this;
  this.oDiv.onmousedown = function(ev) {
    var ev = ev || window.event;
    This.fnDown(ev);
    return false;
  };
};

Drag.prototype.fnDown = function(ev) {
  var This = this;
  this.disX = ev.clientX - this.oDiv.offsetLeft;
  this.disY = ev.clientY - this.oDiv.offsetTop;

  document.onmousemove = function(ev) {
    var ev = ev || window.event;
    This.fnMove(ev);
  };
  document.onmouseup = function() {
    This.fnUp();
  }
};


Drag.prototype.fnMove = function(ev) {

  this.oDiv.style.left = ev.clientX - this.disX + 'px';
  this.oDiv.style.top = ev.clientY - this.disY + 'px';
};

Drag.prototype.fnUp = function() {
  document.onmousemove = null;
  document.onmouseup = null;
};

15.函數節流(throttle)

//fn 要執行的函數
//delay 延遲
//atleast  在time時間內必須執行一次
function throttle(fn, delay, atleast) {
    var timeout = null,
         startTime = new Date();
    return function() {
        var curTime = new Date();
        clearTimeout(timeout);
         // 若是達到了規定的觸發時間間隔,觸發 handler
        if(curTime - startTime >= atleast) {
            fn();
            startTime = curTime;
        }else {
         // 沒達到觸發間隔,從新設定定時器
            timeout = setTimeout(fn, delay);
        }
    }
}
    
// 實際想綁定在 scroll 事件上的 handler
function lazyload(event) {
  console.log('觸發了')
}
// 採用了節流函數
window.addEventListener('scroll',throttle(lazyload,500,1000));

16.函數去抖(debounce)

// debounce函數用來包裹咱們的事件
function debounce(fn, delay) {
  // 持久化一個定時器 timer
  let timer = null;
  return function() {
    // 若是事件被觸發,清除 timer 並從新開始計時
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn();
    }, delay);
  }
}

// 實際想綁定在 scroll 事件上的 handler
function lazyload(event) {
    console.log('觸發了')
}
// 採用了去抖函數
window.addEventListener('scroll',debounce(lazyload,500));

17.分時函數

若是一次得到了不少數據(好比有10W數據),而後在前端渲染的時候會卡到爆,因此在處理這麼多數據的時候,咱們能夠選擇分批進行。

function timeChunk(data, fn, count = 1, wait) {
    let obj, timer;

    function start() {
        let len = Math.min(count, data.length);
        for (let i = 0; i < len; i++) {
            val = data.shift();     // 每次取出一個數據,傳給fn當作值來用
            fn(val);
        }
    }

    return function() {
        timer = setInterval(function() {
            if (data.length === 0) {    // 若是數據爲空了,就清空定時器
                return clearInterval(timer);
            }
            start();    
        }, wait);   // 分批執行的時間間隔
    }
}

// 測試用例
let arr = [];
for (let i = 0; i < 100000; i++) {  // 這裏跑了10萬數據
    arr.push(i);
}
let render = timeChunk(arr, function(n) {   // n爲data.shift()取到的數據
    let div = document.createElement('div');
    div.innerHTML = n;
    document.body.appendChild(div);
}, 8, 20);

render();

參考文章:高階函數,你怎麼那麼漂亮呢!

18.惰性載入函數

假如你要寫一個函數,裏面有一些判斷語句

function foo(){
    if(a != b){
        console.log('aaa')
    }else{
        console.log('bbb')
    }
}

若是你的a和b是不變的,那麼這個函數不論執行多少次,結果都是不變的,可是每次執行還要進行if判斷,這就形成了沒必要要的浪費。
惰性載入表示函數執行的分支只會發生一次,這裏有兩種解決方式。

// 常見的例子
if (window.addEventListener) {
    ele.addEventListener(type, fn, false);
} else  if (window.attachEvent) {
    ele.attachEvent('on' + type, fn);
}

在函數被調用時再處理函數

function foo(){
    if(a != b){
        foo = function(){
            console.log('aaa')
        }
    }else{
        foo = function(){
            console.log('bbb')
        }
    }
    return foo();
}

這樣進入每一個分支後都會對foo進行賦值,覆蓋了以前的函數,以後每次調用foo就不會再執行if判斷

在聲明函數時就指定適當的函數

var foo = (function foo(){
    if(a != b){
        return function(){
            console.log('aaa')
        }
    }else{
        return function(){
            console.log('bbb')
        }
    }
})();

本節參考文章:JS高級技巧(簡潔版)

19.實現once函數

function test(){
  alert('hello');
}
var once = function (fn) {
  var isFirst = true;
  return function () {
    if (isFirst) {
      isFirst = !isFirst;
      fn();
    }
  };
};
once(test);
once(test);

20.requirejs架子

require.js的誕生,就是爲了解決這兩個問題:   

  • 實現js文件的異步加載,避免網頁失去響應;
  • 管理模塊之間的依賴性,便於代碼的編寫和維護。
/** 網頁中引入require.js及main.js **/
<script src="js/require.js" data-main="js/main"></script>

/** main.js 入口文件/主模塊 **/
// 首先用config()指定各模塊路徑和引用名
require.config({
  baseUrl: "js/lib",
  paths: {
    "jquery": "jquery.min",  //實際路徑爲js/lib/jquery.min.js
    "underscore": "underscore.min",
  }
});
// 執行基本操做
require(["jquery","underscore"],function($,_){
  // some code here
});

引用模塊的時候,咱們將模塊名放在[]中做爲reqiure()的第一參數;若是咱們定義的模塊自己也依賴其餘模塊,那就須要將它們放在[]中做爲define()的第一參數。

// 定義math.js模塊
define(function () {
    var basicNum = 0;
    var add = function (x, y) {
        return x + y;
    };
    return {
        add: add,
        basicNum :basicNum
    };
});
// 定義一個依賴underscore.js的模塊
define(['underscore'],function(_){
  var classify = function(list){
    _.countBy(list,function(num){
      return num > 30 ? 'old' : 'young';
    })
  };
  return {
    classify :classify
  };
})

// 引用模塊,將模塊放在[]內
require(['jquery', 'math'],function($, math){
  var sum = math.add(10,20);
  $("#sum").html(sum);
});

加載非規範的模塊
理論上,require.js加載的模塊,必須是按照AMD規範、用define()函數定義的模塊。可是實際上,雖然已經有一部分流行的函數庫(好比jQuery)符合AMD規範,更多的庫並不符合。那麼,require.js是否可以加載非規範的模塊呢?

這樣的模塊在用require()加載以前,要先用require.config()方法,定義它們的一些特徵。舉例來講,underscore和backbone這兩個庫,都沒有采用AMD規範編寫。若是要加載它們的話,必須先定義它們的特徵。
require.config({
    shim: {

      'underscore':{
        exports: '_'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
});
require.config()接受一個配置對象,這個對象除了有前面說過的paths屬性以外,還有一個shim屬性,專門用來配置不兼容的模塊。具體來講,每一個模塊要定義(1)exports值(輸出的變量名),代表這個模塊外部調用時的名稱;(2)deps數組,代表該模塊的依賴性。

好比,jQuery的插件能夠這樣定義:

shim: {
    'jquery.scroll': {
      deps: ['jquery'],
      exports: 'jQuery.fn.scroll'
    }
}

require.js插件

require.js還提供一系列插件,實現一些特定的功能。domready插件,可讓回調函數在頁面DOM結構加載完成後再運行。

require(['domready!'], function (doc){
  // called once the DOM is ready
});

  
text和image插件,則是容許require.js加載文本和圖片文件。

define([
  'text!review.txt',
  'image!cat.jpg'
 ],
    function(review,cat){
    console.log(review);
    document.body.appendChild(cat);
  }
 );

 相似的插件還有json和mdown,用於加載json文件和markdown文件。

本節參考文章:require.js的用法

華米科技 招前端

聯繫: 於夢中(wx:tsw0618) 內推,備註來意,簡歷請甩 weihongjie@huami.com

相關文章
相關標籤/搜索