Я хочу сделать следующее:
- объявить применимые виджеты, например. вот так:
$.fn.myWidget = function(options) { ... }
- определить в html, какой виджет применить к элементу:
<div widget="myWidget">some text</div>
В случае, когда я не вставляю код динамически, реализовать такую вещь почти тривиально:
$(function() {
$('*[widget]').each(function() { $(this)[$(this).attr('widget')]() })
})
Но когда код вставляется динамически (например, из AJAX), нам также нужно пройти этот новый код. Итак, есть два вопроса:
- Есть ли плагин, библиотека или что-то, что решает мою более широкую проблему (например, взять имя виджета из атрибута html и инициализировать виджет для этого элемента)?
- Есть ли какая-то функциональность, которая позволяет обрабатывать (перехватывать) случаи, когда 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 ответ
Наконец, я получаю следующее решение:
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() })
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Имейте в виду, что JavaScript — это НЕ то же самое, что Java! Включите все ярлыки, относящиеся к вашему вопросу; например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [svelte] и т. д.