在AJAX加载后重新绑定jQuery样式的UI接口的首选模式是什么?

时间:2013-02-25 18:27:09

标签: javascript jquery

这总是让我感动。在网页上初始化所有可爱的UI元素之后,我加载了一些内容(例如,加载到模式或标签中),并且新加载的内容没有初始化UI元素。例如:

$('a.button').button(); // jquery ui button as an example
$('select').chosen(); // chosen ui as another example
$('#content').load('/uri'); // content is not styled :(

我目前的方法是创建一个需要绑定的元素注册表:

var uiRegistry = {
  registry: [],
  push: function (func) { this.registry.push(func) },
  apply: function (scope) {
    $.each(uiRegistry.registry, function (i, func) {
      func(scope);
    });
  }
};

uiRegistry.push(function (scope) {
  $('a.button', scope).button();
  $('select', scope).chosen();
});

uiRegistry.apply('body'); // content gets styled as per usual

$('#content').load('/uri', function () {
  uiRegistry.apply($(this)); // content gets styled :)
});

我不能成为唯一有这个问题的人,所以有没有更好的模式呢?

2 个答案:

答案 0 :(得分:1)

我的答案与您概述的答案基本相同,但我使用jquery事件来触发设置代码。我称之为“模式”事件。

当我加载新内容时,我会在父级上触发我的事件:

parent.append(newcode).trigger('moddom');

在小部件中,我查找该事件:

$.on('moddom', function(ev) {
  $(ev.target).find('.myselector')
})

这是过于简化的,以说明事件方法。

实际上,我将它包装在一个函数domInit中,它接受一个选择器和一个回调参数。只要找到与选择器匹配的新元素,它就会调用回调 - 以jquery元素作为第一个参数。

所以在我的小部件代码中,我可以这样做:

domInit('.myselector', function(myelement) {
  myelement.css('color', 'blue');
})

domInit在有问题的元素“domInit”上设置数据,这是已经应用的函数的注册表。

我的完整domInit功能:

window.domInit = function(select, once, callback) {
  var apply, done;
  done = false;
  apply = function() {
    var applied, el;
    el = $(this);
    if (once && !done) {
      done = true;
    }
    applied = el.data('domInit') || {};
    if (applied[callback]) {
      return;
    }
    applied[callback] = true;
    el.data('domInit', applied);
    callback(el);
  };
  $(select).each(apply);
  $(document).on('moddom', function(ev) {
    if (done) {
      return;
    }
    $(ev.target).find(select).each(apply);
  });
};

现在我们只需记住在我们进行dom更改时触发'moddom'事件。

如果您不需要“一次”功能,则可以简化此操作,这是一种非常罕见的边缘情况。它只调用一次回调。例如,如果在找到匹配的任何元素时要进行全局操作 - 但它只需要发生一次。简化而未完成参数:

window.domInit = function(select, callback) {
  var apply;
  apply = function() {
    var applied, el;
    el = $(this);
    applied = el.data('domInit') || {};
    if (applied[callback]) {
      return;
    }
    applied[callback] = true;
    el.data('domInit', applied);
    callback(el);
  };
  $(select).each(apply);
  $(document).on('moddom', function(ev) {
    $(ev.target).find(select).each(apply);
  });
};

在我看来,当dom发生变化时,浏览器应该有办法接收回调,但我从来没有听说过这样的事情。

答案 1 :(得分:0)

最好的方法是将所有ui代码包装在一个函数中 - 即使是更好的单独文件 - 并在ajax加载时只需将该函数指定为回调.. 这是一个小例子

假设您有代码将文本字段与类someclass-for-date绑定到日期选择器,那么您的代码将如下所示..

$('.someclass-for-date').datepicker();

这是我认为最好的

function datepickerUi(){
    $('.someclass-for-date').datepicker();
}

这是负载应该是什么样的

$('#content').load('/uri', function(){

    datepickerUi();

})

或者你可以在脚本标签的html末尾加载它..(但我不喜欢它,因为它更难调试)

这里有一些提示

让您的代码和CSS样式尽可能干净。这意味着对于应该是日期选择器的文本字段,它们会在整个网站上为它们提供一个类。 按照这个速度,您的所有代码都将是干净且易于维护的。

在OOCss上阅读更多信息,这将清楚我的意思。

主要是jquery,这完全是关于组织......给它一些思考,你会用一行代码得到你想要的东西..

修改

这里有一个js小提琴类似于你的东西,但我想它有点清洁click here