日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jQuery UI Widget(1.8.1)工作原理--转载

發布時間:2025/4/5 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jQuery UI Widget(1.8.1)工作原理--转载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先看下代碼的相關注釋:

/*!* jQuery UI Widget 1.8.1** Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)* Dual licensed under the MIT (MIT-LICENSE.txt)* and GPL (GPL-LICENSE.txt) licenses.** http://docs.jquery.com/UI/Widget*/ (function( $ ) {var _remove = $.fn.remove;$.fn.remove = function( selector, keepData ) {return this.each(function() {if ( !keepData ) {if ( !selector || $.filter( selector, [ this ] ).length ) {$( "*", this ).add( this ).each(function() {$( this ).triggerHandler( "remove" );});}}//dom元素在被刪除前,觸發一下remove事件,jquery框架本身沒有對元素刪除綁定事件return _remove.call( $(this), selector, keepData );}); };$.widget = function( name, base, prototype ) {var namespace = name.split( "." )[ 0 ],fullName;name = name.split( "." )[ 1 ];fullName = namespace + "-" + name;//比如ui.tab,上面的name='tab';fullName='ui-tab';if ( !prototype ) {prototype = base;base = $.Widget;}//如果沒有prototype,那么prototype就是base參數,實際base默認為$.Widget// create selector for plugin$.expr[ ":" ][ fullName ] = function( elem ) {return !!$.data( elem, name );};$[ namespace ] = $[ namespace ] || {};//是否有命名空間$[ namespace ][ name ] = function( options, element ) {//根據上面的例子,即初始化了$.ui.tab=func// allow instantiation without initializing for simple inheritanceif ( arguments.length ) {this._createWidget( options, element );}};var basePrototype = new base();//初始化,一般都是調用了new $.Widget()// we need to make the options hash a property directly on the new instance// otherwise we'll modify the options hash on the prototype that we're// inheriting from // $.each( basePrototype, function( key, val ) { // if ( $.isPlainObject(val) ) { // basePrototype[ key ] = $.extend( {}, val ); // } // });basePrototype.options = $.extend( {}, basePrototype.options );//初始化options值,注意不需要深度拷貝$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {namespace: namespace,widgetName: name,widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,widgetBaseClass: fullName}, prototype );//為新的ui模塊創建原型,使用深度拷貝,在basePrototype上擴展一些模塊基本信息,在擴展prototype,比如ui.tabs.js中就是tab的擁有各種方法的大對象 $.widget.bridge( name, $[ namespace ][ name ] );//將此方法掛在jQuery對象上 };$.widget.bridge = function( name, object ) {$.fn[ name ] = function( options ) {var isMethodCall = typeof options === "string",args = Array.prototype.slice.call( arguments, 1 ),returnValue = this;//如果第一個參數是string類型,就認為是調用模塊方法//剩下的參數作為方法的參數,后面會用到// allow multiple hashes to be passed on initoptions = !isMethodCall && args.length ?$.extend.apply( null, [ true, options ].concat(args) ) :options;//可以簡單認為是$.extend(true,options,args[0],...),args可以是一個參數或是數組// prevent calls to internal methodsif ( isMethodCall && options.substring( 0, 1 ) === "_" ) {return returnValue;}//開頭帶下劃線的方法都是私有方法,不讓調用if ( isMethodCall ) {//如果是調用函數this.each(function() {var instance = $.data( this, name ),//得到實例,實例作為一個數據和元素關聯上methodValue = instance && $.isFunction( instance[options] ) ?instance[ options ].apply( instance, args ) ://如果實例和方法均存在,調用方法,把args作為參數傳進去instance;//否則返回undefinedif ( methodValue !== instance && methodValue !== undefined ) {//如果methodValue不是jquery對象也不是undefinedreturnValue = methodValue;return false;//跳出each,一般獲取options的值會走這個分支 }});} else {//不是函數調用的話this.each(function() {var instance = $.data( this, name );if ( instance ) {//實例存在if ( options ) {//有參數instance.option( options );//調用option函數,一般是設置狀態之類的操作 }instance._init();//再次調用此函數,根據options調整} else {$.data( this, name, new object( options, this ) );//沒有實例的話,給元素綁定一個實例。注意這里的this是dom,object是模塊類 }});}return returnValue;//返回,有可能是jquery對象,有可能是其他值 }; };$.Widget = function( options, element ) {//所有模塊的基類// allow instantiation without initializing for simple inheritanceif ( arguments.length ) {//如果有參數,調用初始化函數this._createWidget( options, element );} };$.Widget.prototype = {widgetName: "widget",widgetEventPrefix: "",options: {disabled: false},//上面的屬性會在創建模塊時被覆蓋_createWidget: function( options, element ) {// $.widget.bridge stores the plugin instance, but we do it anyway// so that it's stored even before the _create function runsthis.element = $( element ).data( this.widgetName, this );//緩存實例,保存jquery對象this.options = $.extend( true, {},this.options,$.metadata && $.metadata.get( element )[ this.widgetName ],options );//參數處理var self = this;this.element.bind( "remove." + this.widgetName, function() {self.destroy();});//注冊銷毀事件this._create();//創建this._init();//初始化 },_create: function() {},_init: function() {},destroy: function() {//銷毀模塊:去除綁定事件、去除數據、去除樣式、屬性this.element.unbind( "." + this.widgetName ).removeData( this.widgetName );this.widget().unbind( "." + this.widgetName ).removeAttr( "aria-disabled" ).removeClass(this.widgetBaseClass + "-disabled " +"ui-state-disabled" );},widget: function() {//返回jquery對象return this.element;},option: function( key, value ) {//設置選項函數var options = key,self = this;if ( arguments.length === 0 ) {// don't return a reference to the internal hashreturn $.extend( {}, self.options );//返回一個新的對象,不是內部數據的引用 }if (typeof key === "string" ) {if ( value === undefined ) {return this.options[ key ];//取值 }options = {};options[ key ] = value;//設置值 }$.each( options, function( key, value ) {self._setOption( key, value );//調用內部的_setOption });return self;},_setOption: function( key, value ) {this.options[ key ] = value;if ( key === "disabled" ) {//增加或是去除classNamethis.widget()[ value ? "addClass" : "removeClass"](this.widgetBaseClass + "-disabled" + " " +"ui-state-disabled" ).attr( "aria-disabled", value );}return this;},enable: function() {return this._setOption( "disabled", false );},disable: function() {return this._setOption( "disabled", true );},_trigger: function( type, event, data ) {var callback = this.options[ type ];event = $.Event( event );event.type = ( type === this.widgetEventPrefix ?type :this.widgetEventPrefix + type ).toLowerCase();data = data || {};// copy original event properties over to the new event// this would happen if we could call $.event.fix instead of $.Event// but we don't have a way to force an event to be fixed multiple timesif ( event.originalEvent ) {//把原始的event屬性重新賦到event變量上for ( var i = $.event.props.length, prop; i; ) {prop = $.event.props[ --i ];event[ prop ] = event.originalEvent[ prop ];}}this.element.trigger( event, data );return !( $.isFunction(callback) &&callback.call( this.element[0], event, data ) === false ||event.isDefaultPrevented() );} };})( jQuery );

上面是jquery.ui.widget.js的源碼,jquery ui的所有模塊都是基于其中的widget方法進行擴展,使用統一的命名規范和編碼風格。?
先來說一下原理:?
$.widget此函數完成了對jQuery本身的擴展,根據第一個參數來確定模塊的命名空間和函數名;第二個參數確定模塊的基類(默認是$.Widget);第三個參數實現模塊本身的方法。比如標簽切換插件jquery.ui.tabs.js中開始:?
$.widget(“ui.tabs”, {…});//這里只有兩個參數,那么基類就默認是$.Widget?
第一個參數:”ui.tabs”用來表示在jQuery上選擇(或增加)一個命名空間,即如果jQuery.ui不存在,則定義jQuery.ui = {},然后在jQuery.ui上增加一個函數,名稱為tabs.最后調用$.widget.bridge將tabs方法掛在jQuery對象上。這樣,所有的jquery對象將擁有tabs方法。?

注意:jquery ui有嚴格的命名規范,每個控件對外只暴露一個借口。控件所有方法或屬性通過向此借口傳遞不同參數來調用和獲取。?

jquery ui的大部分控件是基于$.Widget基類實現的。所以一般我們做控件是都要重寫$.Widget類中的一些方法。一般來說,一個ui控件需要實現下列的方法或屬性:?
屬性:?
options 用來緩存控件各項參數?
私有方法,使用“$(xx).tabs(私有方法)”這種方式來調用私有方法時會立刻返回,調用不能成功:?
_create 控件初始化調用,多次調用$(xx).tabs()這樣不帶參數的方法只會執行一次?
_init 一般不用實現,默認為空函數,每次“$(xx).tabs()”這樣調用時會調用此方法?
_setOption “$(xx).tabs(‘option’,xxx)”這種調用方式會調用此方法?
公開方法:?
destroy 銷毀模塊?
option 設置或獲取參數?
enable 啟用模塊功能?
disable 禁用功能?

幾乎所有的jquery ui控件都會重寫這些接口,同時增加控件相關的私有或公有方法。?

記住,jquery ui的實例是和元素關聯起來的,作為數據保存起來了。暴露給用戶使用的只是jquery對象上增加的方法。一般我們不需要獲取ui的實例。

原文地址:http://xj19891016.iteye.com/blog/789201

轉載于:https://www.cnblogs.com/davidwang456/p/4024433.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的jQuery UI Widget(1.8.1)工作原理--转载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产高清一区在线观看 | 亚洲欧美在线免费观看 | 午夜精品国产 | 日韩免费高清一区二区 | 女人久久| 光棍影院一区二区 | 加勒比一区在线 | 蜜桃99视频一区二区三区 | 免费成人av | 少妇一级淫免费播放 | 久久精品国产亚洲AV无码麻豆 | 咪咪成人网 | 在线免费播放 | av噜噜在线 | 国产精品天美传媒沈樵 | 成人福利视频导航 | 超碰人人cao| 91精品免费看 | 欧美3p视频 | 一级片少妇| 钰慧的mv视频在线观看 | 国产精品18久久久久久久久 | 男同互操gay射视频在线看 | 在线成人毛片 | а√天堂中文在线资源8 | 成人在线a| 伊人精品 | 永久国产| 激情欧美一区二区免费视频 | 91视频在线 | 青青草原成人网 | 日韩欧美一本 | 中文字幕在线观看视频一区二区 | 国产精品视屏 | 久久发布国产伦子伦精品 | 影音先锋三级 | 亚洲性天堂 | 性猛╳xxx乱大交 | 亚洲喷水 | 日韩一区不卡视频 | 蜜桃视频污在线观看 | 亚洲成人黄色小说 | 午夜少妇久久久久久久久 | 精品一区二区三区久久久 | 国产亚洲精品久久久久久 | 婷婷狠狠 | 91国内精品久久久 | 日韩久久一区 | 日韩激情网址 | 天堂社区av| 丝袜熟女一区二区三区 | 国产伦精品一区二区三区妓女下载 | 精品动漫一区 | 在线看黄网 | 69亚洲 | 国产精品久久..4399 | 久久午夜精品 | 日本成人黄色片 | 精品视频在线看 | 美女狠狠干 | 四虎影院在线视频 | 得得的爱在线视频 | 中文字幕久久网 | 在线观看 亚洲 | 爱爱激情网 | 欧美日韩一区二区三区在线播放 | 海角社区在线视频播放观看 | chinese麻豆新拍video | 波多野结衣视频观看 | 中文字幕视频网 | 灌篮高手全国大赛电影 | 欧美激情16p| 在线中文字幕第一页 | 91精品国自产在线偷拍蜜桃 | 亚洲字幕av一区二区三区四区 | av在线免费网站 | 长腿校花无力呻吟娇喘的视频 | 大尺度av| 女的高潮流时喷水图片大全 | 美女啪啪网址 | 在线免费不卡视频 | 欧美另类一区 | 巨胸大乳www视频免费观看 | 精品人伦一区二区三 | 欧美精品一区二区三区四区 | 免费av在线电影 | 天天干一干 | 国产精品国产三级国产a | 亚洲五月花 | 久久综合婷婷国产二区高清 | 伊人久在线 | 最近中文字幕免费mv视频7 | 大奶骚 | 欧美成人第一页 | 可以看av的网址 | 在线看b | 成人亚洲网站 | 国产精品中文字幕在线 | 精品国产一区二区三区av性色 |