如何自己編寫一個easyui插件


本文介紹如何通過參考1.4.2版本的progressbar的源碼自己編寫一個HelloWorld級別的easyui插件,以及如何拓展插件的功能。

有利於我們理解easyui插件的實現,以及了解如何對easyui插件進行拓展,或者當發現bug時在不修改源碼的情況下對bug進行修復。

 

1. 首先讓我們來看看progressbar的源碼(已經刪除了一些對本文不重要的)。

比較了一下有源碼的那幾個插件,發現這個只有3KB,最小,所以拿這個學習最好了;而且這個progressbar沒有涉及繼承其他控件,易於理解。

(function($){
        function init(target) {
                $(target).addClass('progressbar');
		return $(target);
	}
	
	$.fn.progressbar = function(options, param){
		if (typeof options == 'string'){
			var method = $.fn.progressbar.methods[options];
			if (method){
				return method(this, param);
			}
		}
		
		options = options || {};
		return this.each(function(){
			var state = $.data(this, 'progressbar');
			if (state){
				$.extend(state.options, options);
			} else {
				state = $.data(this, 'progressbar', {
					options: $.extend({}, $.fn.progressbar.defaults, $.fn.progressbar.parseOptions(this), options),
					bar: init(this)
				});
			}
		});
	};
	
	$.fn.progressbar.methods = {
		options: function(jq){
			return $.data(jq[0], 'progressbar').options;
		},
		getValue: function(jq){
			return $.data(jq[0], 'progressbar').options.value;
		}
	};
	
	$.fn.progressbar.parseOptions = function(target){
		return $.extend({}, $.parser.parseOptions(target, ['width','height','text',{value:'number'}]));
	};
	
	$.fn.progressbar.defaults = {
		width: 'auto',
		height: 22,
		value: 0,	// percentage value
		text: '{value}%',
		onChange:function(newValue,oldValue){}
	};
})(jQuery);

我們倒着看,

①$.fn.progressbar.defaults定義了一些參數的默認值,而且是直接定義在$.fn.progressbar.defaults上的,是全局的。

②$.fn.progressbar.parseOptions是一個對data-options="......"中的屬性進行解析的方法,其實$.parser.parseOptions已經幫助我們做了主要工作,我們只需要設置一下參數是什么類型的數據就行,如這里的value設置為number類型。

③$.fn.progressbar.methods定義了這個插件的行為(一些方法),可以看出也是全局的。

④$.fn.progressbar這個是重點了,typeof options == 'string'時就是調用插件的某個方法,如$('#xxx').progressbar('setValue', 10);否則就相當於調用無參方法$('#xxx').progressbar(),有點像是個構造函數。

 

2. 實現自己的hello插件

jquery.hello.js

(function($){
    function init(target) {
        //注:此處還不能獲取options

        //所以這里可以進行一些如設置樣式、綁定事件的事情
        $(target).css('cursor', 'pointer');

        $(target).bind('click', function (e, preventBubble) {
            $.fn.hello.methods.sayHello($(e.target));
            return false;
        });

		return $(target);
	}

    //easyui插件函數
    $.fn.hello = function (options, param) {
        //如果options為string,則是方法調用,如$('#divMyPlugin').hello('sayHello');
		if (typeof options == 'string'){
		    var method = $.fn.hello.methods[options];
			if (method){
				return method(this, param);
			}
		}
		
        //否則是插件初始化函數,如$('#divMyPlugin').hello();
		options = options || {};
		return this.each(function(){
		    var state = $.data(this, 'hello');
			if (state){
				$.extend(state.options, options);
			} else {
                //easyui的parser會依次計算options、initedObj
			    state = $.data(this, 'hello', {
			        options: $.extend({}, $.fn.hello.defaults, $.fn.hello.parseOptions(this), options),
			        initedObj: init(this) //這里的initedObj名稱隨便取的
				});
			}

			$(this).css('color', state.options.myColor);
		});
	};
	
    //設置hello插件的一些方法的默認實現
    //注:第一個參數為當前元素對應的jQuery對象
	$.fn.hello.methods = {
		options: function(jq){
		    return $.data(jq[0], 'hello').options;
		},
		sayHello: function (jq) {
		    var opts = $.data(jq[0], 'hello').options; //獲取配置參數
		    for (var i = 0; i < opts.repeatTimes; i++) {
		        opts.howToSay(opts.to);
		    }
		}
	};
	
    //設置參數轉換方法
	$.fn.hello.parseOptions = function (target) {
	    var opts = $.extend({}, $.parser.parseOptions(target, ['to', 'myColor', { repeatTimes: 'number' }]));//這里可以指定參數的類型
	    return opts;
	};
	
    //設置hello插件的一些默認值
	$.fn.hello.defaults = {
	    to: 'world',
	    repeatTimes: 1,
	    myColor: null,
	    howToSay: function (to) {
	        alert('Hello, ' + to + "!");
	    }
	};
    
    //注冊自定義easyui插件hello
    $.parser.plugins.push("hello");
})(jQuery);

 

3. 給hello插件拓展功能

我們前面已經說了$.fn.hello.methods是全局的,所以所謂拓展就是直接給$.fn.hello.methods加方法。

如果需要改寫原有實現,可以直接將原來的方法覆蓋掉就可以了,如:$.fn.hello.methods.sayHello = function(jq){ ...... };

jquery.hello.extension.js

(function($){
    
    //拓展方法
    $.fn.hello.methods.sayHi = function (jq) {
        //var opts = $.data(jq[0], 'hello').options;
        alert("Hi");
    }
	
})(jQuery);

 

 

4. 使用hello插件

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="keywords" content="">
	<meta name="description" content="">
	<title></title>
	<link rel="stylesheet" type="text/css" href="http://www.jeasyui.com/easyui/themes/default/easyui.css">
	<link rel="stylesheet" type="text/css" href="http://www.jeasyui.com/easyui/themes/icon.css">
	<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
	<script type="text/javascript" src="http://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
    <script type="text/javascript" src="jquery.hello.js"></script>
    <script type="text/javascript" src="jquery.hello.extension.js"></script>
</head>
<body>
    <div id="divMyPlugin1" class="easyui-hello" data-options="to:'world', myColor:'red' ">點我sayHello一次</div>
    <div id="divMyPlugin2" class="easyui-hello" data-options="to:'world', repeatTimes:3, myColor:'green', howToSay:customeHowToSay">點我sayHello三次</div>
    <button onclick="invokePluginMethod()">調用插件的方法</button><button onclick="invokePluginExMethod()">調用插件的拓展方法</button><button onclick="$('#divMsg').empty()">Clear</button>
    <div id="divMsg">
        
    </div>
    <script type="text/javascript">

        function invokePluginMethod() {
            $('#divMyPlugin2').hello('sayHello');
        }

        function invokePluginExMethod() {
            $('#divMyPlugin2').hello('sayHi');
        }

        function customeHowToSay(to) {
            $('<p></p>').html('你好, <span style="color:red">' + to + '<span>!' + new Date().getTime()).appendTo($('#divMsg'));
        }

    </script>
</body>
</html>

 

5. 在線查看

這里


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM