jQuery:如何将函数应用于所有元素,包括通过Ajax后来加载的一些元素?

4
我有一个简单的jQuery函数,可以调整文本区域的大小,我希望它适用于所有的文本区域。
大多数情况下,这个函数都很好用:
$(document.ready(function(){$("text_area").resizer('250px')});

然而,因为它只在文档准备就绪时被调用一次,所以它不能捕获后来使用Ajax添加到页面上的文本区域。我看了一下.live()函数,它似乎非常接近我想要的东西。但是,.live()必须绑定到特定的事件,而我只需要在它们完成加载时触发一次(onLoad事件对单个元素不起作用)。

我唯一能让它工作的方式是将JavaScript调用明确地包含在Ajax中,这样做是否推荐呢?

编辑:这里是Ajax请求所做的Rails源代码:

$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
 var link = $(this);
 if (!allowAction(link)) return false;

 if (link.attr('data-remote') != undefined) {
  handleRemote(link);
  return false;
 } else if (link.attr('data-method')) {
  handleMethod(link);
  return false;
 }
});

// Submits "remote" forms and links with ajax
function handleRemote(element) {
 var method, url, data,
  dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);

 if (element.is('form')) {
  method = element.attr('method');
  url = element.attr('action');
  data = element.serializeArray();
  // memoized value from clicked submit button
  var button = element.data('ujs:submit-button');
  if (button) {
   data.push(button);
   element.data('ujs:submit-button', null);
  }
 } else {
  method = element.attr('data-method');
  url = element.attr('href');
  data = null;
 }

 $.ajax({
  url: url, type: method || 'GET', data: data, dataType: dataType,
  // stopping the "ajax:beforeSend" event will cancel the ajax request
  beforeSend: function(xhr, settings) {
   if (settings.dataType === undefined) {
    xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
   }
   return fire(element, 'ajax:beforeSend', [xhr, settings]);
  },
  success: function(data, status, xhr) {
   element.trigger('ajax:success', [data, status, xhr]);
  },
  complete: function(xhr, status) {
   element.trigger('ajax:complete', [xhr, status]);
  },
  error: function(xhr, status, error) {
   element.trigger('ajax:error', [xhr, status, error]);
  }
 });
}

在我特定的情况下,我有一个链接,它将data-remote设置为true,指向一个位置,该位置将返回JavaScript指令,指示一个包含文本区域的表单被附加到我的文档中。


您可以使用按类选择器,因此当新对象到来时(具有添加类的属性),它也将具有所需的属性。 - Eric Frick
@Eric,这适用于绑定事件处理程序的情况,但在这种特定情况下它是如何工作的呢? - jessegavin
@Eric Frick,你确定这个可行吗?我认为它会遇到相同的问题,即选择器只运行一次,除非你使用.live()。 - William Jones
@jessegavin,哦,我现在明白你在问什么了。我正在使用Rails,所以我所做的就是设置:remote => true,Rails会处理实际的Ajax链接。 - William Jones
@William,请展示给我们渲染后的JS代码。 - lonesomeday
@WilliamJones:你说得对,它不能正常工作。你应该像@jeseevagin一样提到检索对象。 - Eric Frick
3个回答

7

一个简单的方法是使用ajaxComplete,它会在每个 AJAX 请求之后触发:

$(document).ajaxComplete(function() {
    $('textarea:not(.processed)').resizer('250px');
});

这段代码的意思是:每次AJAX请求完成后,查找所有没有“processed”类的textarea元素(该类似乎是由调整大小插件添加的,用于其目的非常糟糕!),并对它们调用resizer插件。

如果我们能看到你的AJAX调用,可能还可以进一步优化。


你应该在第二行的末尾添加.addClass("processed") - jessegavin
@jessegavin 不需要,因为插件会自动处理。 - lonesomeday

1
通常来说,我会这样做...
$.ajax({
  type : "GET",
  url : "/loadstuff",
  success: function(responseHtml) {
    var div = $("#containerDiv").append(responseHtml);
    $("textarea", div).resizer("250px");
  }
});

1

想知道您是否可以使用.load来实现。例如:

$('text_area').load(function() { $("text_area").resizer('250px'); });


不幸的是,对于普通元素,load事件不会被发送,只有(来自jQuery加载文档)“与URL相关联的任何元素:图像、脚本、帧、iframe和窗口对象。” - William Jones
啊,谢谢你的澄清。在这种情况下,我认为lonesomeday的答案可能是最好的。 - Steve Costello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接