自定義jquery插件

在當前這個前端mv**框架盛行的年代,翻譯這樣一篇關於如何編寫jquery插件的文章好像顯得有點多餘和那麼的不接時代,不過仍是自私點,努力翻譯一把起碼能夠提升本身(<_>)。javascript

jquery很是棒,它兼容性好,入門簡單,讓咱們在處理終端交互的時候來的垂手可得,同時他還有很是龐大的插件庫,幾乎你能想到的功能都能找到對應的插件。css

可是,咱們的業務需求是變幻無窮的,萬一咱們須要的功能找不到或者說找不到很是合適的插件的時候,咱們該怎麼辦?或者當項目漸漸龐大起來的時候,你想把通用的功能封裝起來的時候,咱們該怎麼辦(這個時候請你僞裝忘記:amd,cmd,es6module)?按照jquery的思路,這個時候就能夠經過自定義插件來解決了。html

jquery plugin的編寫並無想象中的難,下面經過編寫一個擁有屬性和一些回調函數的簡單插件介紹下如何編寫jquery plugin前端

建立文件目錄

# 準備基本環境
mkdir jquery-plugin-sample
cd jquery-plugin-sample
mkdir src
cd src
echo '' > index.js
# 文件結構以下
.
├── LICENSE
├── src
│   └── index.js # 這文件就是用來編寫插件具體內容

插件的代碼結構

;(function($){
    $.fn.helloWorld = function(){
        //Future home of "Hello, World!"
    }
})(jQuery)

上面的代碼幹了3件事情java

  1. 代碼被封裝在一個 (function(){}) self-enclosed 中,這樣保證了內部變量不會和全局環境相互影響
  2. 咱們將jQuery做爲參數傳遞給了內部函數,這樣作的目的是避免和其餘庫也聲明瞭 $相互衝突
  3. 咱們經過$.fn定義了咱們的插件,而且命名爲helloWorld

在插件中實線一些功能

在編寫功能以前,先基於webpack構建一個本地調試環境 本地環境構建node

// src/index.js
;(function($){
    $.fn.helloWorld = function(){
        this.each(function(){ //1
            $(this).text("Hello World")//2
        })
    }
})(jQuery);

上面的代碼須要注意2個地方jquery

  1. 1處的this表明就是jqueryDom 對象對象自己,所以不須要 $(this)來進行轉換
  2. 2處的this因爲遍歷時候的回調中的this指向dom自己,所以須要$(this)轉換爲jquery對象
// 測試插件功能
// demo/demo.js
import $ from 'jquery';
import '../src';

$(document).ready(()=>{
  // 找到頁面的dom
  $('.demo-wrap li').helloWorld();
})

此時,對應的瀏覽器頁面應該會出現如圖同樣的結果,OK,一個很是簡單的插件構建完成,該插件的功能就是將選中的dom的text 替換爲Hello World, 這個插件合格嗎?
測試結果webpack

完善插件的功能

咱們都知道jquery還有一個很是好的特性,就是api支持鏈式調用$('div').text('hell').addClass('red');那麼咱們本身寫的插件是否知足這個特性呢?經過測試代碼很明顯,這個helloWorld插件不知足這個特性,所以不是一個合格的插件,須要稍微處理下才能知足git

// 修改 src/index.js
;(function($){
    $.fn.helloWorld = function(){
        return this.each(function(){
            $(this).text("Hello World")
        })
    }
})(jQuery);

OK,到這裏爲止,一個jquery插件纔算真正到完成。es6

擴展插件,讓插件能夠接收參數

;(function($){
    $.fn.helloWorld = function(customText){
        return this.each(function(){
            $(this).text(customText)
        })
    }
})(jQuery);

OK,如今能夠將選中到dom到內容修改成你傳入到任何東西了

終極插件

雖然上面咱們擴展了插件,能夠知足根據輸入到內容修改匹配到dom的內容,可是若是須要樣式呢?須要修改字體大小呢?須要添加回調函數呢?因此,參數必須是個對象的形式,Ok,立馬修改代碼

;(function($){
    $.fn.helloWorld = function(options){
        var settings = $.extend({
          text:'Hello World',
          color:null,
          fontStyle:null,
          complete:null
        },options)
        return this.each(function(){
            $(this).text(settings.text);
            if(settings.color){
              $(this).css( 'color', settings.color );
            }
            if(settings.fontStyle){
              $(this).css( 'font-style', settings.fontStyle );
            }
            if ( $.isFunction( settings.complete ) ) {
              settings.complete.call( this );
            }
        })
    }
})(jQuery);
// 測試代碼 demo/demo.js
import $ from 'jquery';
import '../src';
$(document).ready(()=>{
  // 找到頁面的dom
  $('.demo-wrap li').helloWorld({
    color:'red',
    complete:()=>{
      console.log('sds')
    }
  }).addClass();
})

總結

靈活封裝jquery插件,不但能夠抽取公用代碼同時能夠很好的保證全局環境的乾淨。另外,這篇文字雖然是翻譯的文字,不過demo是本身手寫的,有須要的能夠去github上下載 jquery-plugin-sample,也能夠經過 npm install xxw-jquery-plugin-sample 來測試代碼

本地環境構建

cd jquery-plugin-sample
npm init -y
yarn add webpack webpack-dev-server babel-core babel babel-preset-env html-webpack-plugin babel-loader -D
mkdir demo
cd demo
echo '' > index.ejs
echo '' > demo.js
# 文件結構以下
.
├── LICENSE
├── demo
│   ├── demo.js
│   └── index.ejs
├── package.json
├── readme.md
├── src
│   └── index.js
└── yarn.lock
// 編寫webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const babel_options ={
  presets:[
    ['env',{
      "targets": {
        "browsers": ["last 4 versions", "safari >= 7"]
      }
    }]
  ]
}
module.exports = {
  entry:'./demo/demo.js',
  output:{
    path:path.resolve(__dirname,'./dist'),
    filename:'index.js'
  },
  module:{
    rules:[
      // es6 語法解析
      {
        test:/\.js$/,
        exclude: /(node_modules|bower_components)/,
        use:[
          {
            loader:'babel-loader',
            options:babel_options
          }
        ]
      }
    ]
  },
  plugins:[
    new HtmlWebpackPlugin({
      template:'./demo/index.ejs',
      filename:'index.html'
    })
  ],
  externals: {
    'jquery': 'jQuery'
  },
  devServer: {
    host: '127.0.0.1',
    port: 3000
  }
};
// 編寫ejs,添加jquery cdn
 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test jquery pllugin</title>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
  </head>
  <body>

  </body>
</html>
# 啓動項目
yarn webpack-dev-server
Project is running at http://127.0.0.1:3000/
webpack output is served from /
Hash: 137d7a562cabec2c7996
Version: webpack 3.10.0
Time: 1053ms
     Asset       Size  Chunks                    Chunk Names
  index.js     324 kB       0  [emitted]  [big]  main
index.html  266 bytes          [emitted]

在瀏覽器中輸入 http://127.0.0.1:3000/ 訪問測試頁面

相關文章
相關標籤/搜索