Javascript 在AJAX加载之后,重新绑定jQuery风格的UI界面的首选模式是什么?

Javascript 在AJAX加载之后,重新绑定jQuery风格的UI界面的首选模式是什么?,javascript,jquery,Javascript,Jquery,这总是让我抓狂。初始化网页上所有可爱的UI元素后,我在中加载了一些内容(例如,加载到模式或选项卡中),而新加载的内容没有初始化UI元素。例如: $('a.button').button();//以jqueryui按钮为例 $('select').selected();//选择ui作为另一个示例 $('#content')。加载('/uri');//内容未设置样式:( 我当前的方法是创建需要绑定的元素的注册表: var ui注册表={ 注册表:[], push:function(func){th

这总是让我抓狂。初始化网页上所有可爱的UI元素后,我在中加载了一些内容(例如,加载到模式或选项卡中),而新加载的内容没有初始化UI元素。例如:

$('a.button').button();//以jqueryui按钮为例
$('select').selected();//选择ui作为另一个示例
$('#content')。加载('/uri');//内容未设置样式:(
我当前的方法是创建需要绑定的元素的注册表:

var ui注册表={
注册表:[],
push:function(func){this.registry.push(func)},
应用:功能(范围){
$.each(uiRegistry.registry,function(i,func){
func(范围);
});
}
};
uiRegistry.push(函数(作用域){
$('a.button',scope.button();
$('select',scope).selected();
});
uiRegistry.apply('body');//内容按常规设置样式
$('#content')。加载('/uri',函数(){
uiRegistry.apply($(this));//内容的样式:)
});

我不可能是唯一一个有这个问题的人,那么有没有更好的模式来解决这个问题呢?

最好的方法是将所有ui代码包装在一个函数中,甚至最好是一个单独的文件- 在ajax加载中,只需将该函数指定为回调函数。。 这里有一个小例子

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

$('.someclass-for-date').datepicker();
这是我认为最好的

function datepickerUi(){
    $('.someclass-for-date').datepicker();
}
这里是负载的样子

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

    datepickerUi();

})
或者,您可以在脚本标记中的html末尾加载它。。(但我不喜欢这样,因为调试起来比较困难)

这里有一些提示

尽可能保持代码和css样式的整洁。。这意味着,对于应该是日期选择器的文本字段,在您的网站上为其设置一个类。。 以这种速度,您的所有代码都将是干净且易于维护的

阅读更多关于OOCss的内容,这将明确我的意思

大多数情况下,jquery都是关于组织的。。。想一想,你就可以用一行代码完成你想要的

编辑


这是一个类似于您的js文件,但我想它更干净了一点

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

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

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”事件

如果不需要“一次”功能,您可以简化此过程,这是一种非常罕见的边缘情况。它只调用回调一次。例如,如果要在找到匹配的元素时执行全局操作,但只需执行一次。简化而不带done参数:

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发生变化时接收回调的方法,但我从来没有听说过这样的事情。

您的方法至少比大多数方法更好,它只针对好的新元素。不过我不会用“apply”作为属性名,这可能会让人困惑。同意,你的方法很好。这与jQuery Mobile在容器元素上触发
create
事件时所做的差不多,只是它使用
data-
属性而不是类来匹配元素并确定要用于扩展它们的小部件。谢谢。我会去查看jQuery移动代码,看看他们在那里做了什么有趣的事情。我会更详细地看一下。