如何从 html 属性值附加小部件?

发布于 2024-12-23 02:44:42 字数 1036 浏览 1 评论 0原文

我想要执行以下操作:

  1. 声明适用的小部件,例如这样: $.fn.myWidget = function(options) { ... }
  2. 在 html 中定义要应用于该元素的小部件:
    some text

如果我不动态插入代码,实现这样的事情几乎是微不足道的:

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

但是当代码动态插入时(例如从 AJAX ), 我们需要也遍历该新代码。所以有两个问题:

  1. 是否有插件、库或其他东西可以解决我更广泛的问题(ei 从 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() 和类似的调用并“从内部”隐式应用该方法还是很有趣的。

I want to do the following:

  1. declare applicable widgets, e.g. like this: $.fn.myWidget = function(options) { ... }
  2. define in html which widget to apply to the element: <div widget="myWidget">some text</div>

In case when I don't insert code dynamically, to implement such thing is almost trivial:

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

But when a code insert dynamically (e.g. from AJAX), we need to traverse that new code as well. So there are two questions:

  1. Is there a plugin, library or something that solve my wider problem (e.i. take widget name from html attribute and initialize the widget for that element)?
  2. Is there some functionality that allows handle (hook) cases when jQuery inserts html elements dynamically (using .html(), .prepend(), .load() etc)?

update: more details

Partially it's possible to solve problem using the following approach:

$.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());
}

and then use $(selector).htmlWithWidgets(html) instead of $(selector).html(html)

Still it would be interesting to learn how to intercept html() and similar calls and apply the approach implicitly, "from inside".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

场罚期间 2024-12-30 02:44:42

最后我得到了以下解决方案:

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

Finally I end up with the following solution:

  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() })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文