2011-12-27 58 views
0

我想要做以下事情:如何從html屬性值附加小部件?

  1. 聲明適用的小部件,例如,像這樣:$.fn.myWidget = function(options) { ... }
  2. 定義HTML中小部件應用到元素:<div widget="myWidget">some text</div>

在情況下,我不動態插入代碼,來實現這樣的事情幾乎是微不足道的:

$(function() { 
    $('*[widget]').each(function() { $(this)[$(this).attr('widget')]() }) 
}) 

但是,當一個代碼動態插入(例如來自AJAX)時,我們還需要遍歷新代碼。因此,有兩個問題:

  1. 有一個插件,庫或解決我的問題更廣泛的東西(E.I.從HTML屬性取部件名稱和初始化該元素的小工具)?
  2. 是否有一些功能,允許處理(掛鉤)的情況下,當jQuery動態插入html元素(使用.html(),.prepend(),.load()等)?

更新:更多的細節

部分很可能使用以下方法來解決問題:

$.fn.applyWidgets = function() { 
    this.each(function() { 
    var $e = $(element); 
    var widget = $e.attr('widget'); 
    if(widget) $e[widget](); 
    }); 
} 

$.fn.htmlWithWidgets = function(html) { 
    this.html($(html).applyWidgets()); 
} 

然後使用$(selector).htmlWithWidgets(html)代替$(selector).html(html)

不過這將是有趣學習如何攔截html()和類似的調用,並隱式應用該方法,「從內部」。

+1

請停止標記標題。 – 2011-12-27 20:25:36

+0

Tomalak,你能詳細說明我的標籤有什麼問題嗎? – Alexey 2011-12-27 21:04:40

+0

沒有。但標籤進入標籤;請不要在標題中重複它們。 – 2011-12-27 21:05:46

回答

0

最後,我結束了以下解決方案:

var _widget_bindings = {} 

    // registers css_class and associates with widget_initializer callback 
    function bind_widget(css_class, widget_initializer) { 
    if (jQuery.fn[css_class]) throw "widget with name "+css_class+"already defined"; 
    _widget_bindings[css_class] = widget_initializer; 
    jQuery.fn[css_class] = widget_initializer; 
    } 

    // for each element in set takes DOM subtree and for each element in the subtree with registered css_class 
    // invokes corresponding widget_initializer 
    jQuery.fn.init_widgets = function() { 
    this.find('*[class]').andSelf().each(function() { 
     if (!this.className) return; 
     var classes = this.className.split(/\s+/); 
     for (var i = 0, l = classes.length; i < l; i++) { 
     var css_class = classes[i]; 
     if (css_class && _widget_bindings.hasOwnProperty(css_class)) 
      _widget_bindings[css_class].apply(jQuery(this)); 
     } 
    }) 
    return this; 
    } 

    // invokes a method (can be .html(), .append(), .prepend(), .before(), .after()) by given method_name 
    // and initializes widgets for newly created elements 
    jQuery.fn.with_widgets = function(method_name, elements) { 
    var j_elements = jQuery(elements); 
    this[method_name](j_elements); 
    j_elements.init_widgets(); 
    return this; 
    } 

    jQuery(document).ready(function() { (document.body).init_widgets() })