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

栏目: jQuery · 发布时间: 7年前

内容简介:服务端返回如下(返回时即执行全局函数):本节参考文章:Promise对象调用

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>

服务端返回如下(返回时即执行全局函数):

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音乐首页推荐

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)
})

实现一个简单的Promise

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改变状态之后会调用回调函数,根据状态的不同选择需要执行的回调函数。

本节参考文章: 面向面试题和实际使用谈promise

示例2

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学习过程总结

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轮播图插件举例

优化前

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

优化后

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

本节详细: 如何让图片按比例响应式缩放、并自动裁剪的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的用法


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Is Parallel Programming Hard, And, If So, What Can You Do About

Is Parallel Programming Hard, And, If So, What Can You Do About

Paul E. McKenney

The purpose of this book is to help you understand how to program shared-memory parallel machines without risking your sanity.1 By describing the algorithms and designs that have worked well in the pa......一起来看看 《Is Parallel Programming Hard, And, If So, What Can You Do About 》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具