开发者

jQuery: How to apply a function to all elements including some which are loaded later via Ajax?

开发者 https://www.devze.com 2023-02-27 03:26 出处:网络
I have a simple jQuery function that resizes text areas, and I want it to apply to all text areas. For the most part, this works great:

I have a simple jQuery function that resizes text areas, and I want it to apply to all text areas.

For the most part, this works great:

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

However, because it is only called once when the document is ready, it fails to catch text areas that are later added onto the page using Ajax. I looked at the .live() function, which seems very close to what I'm looking. However, .live() must be bound to a specific event, whereas I just need this to fire once when they're done loading (the onLoad event doesn't work for individual elements).

The only thing I can get working is a really obtrusive inclusion of the JavaScript call directly into the Ajax. Is that the recommended way to be doing this?

Edit: Here is the rails source code for what it does for Ajax requests:

$('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 = el开发者_高级运维ement.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]);
  }
 });
}

So in my particular case, I've got a link, that has data-remote set to true, which points to a location that will return JavaScript instructing a form containing a text area to be appended to my document.


A simple way to do this would be to use ajaxComplete, which is fired after every AJAX request:

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

That says "every time an AJAX request completes, find all textarea elements that don't have the processed class (which seems to be added by the resizer plugin -- terrible name for its purpose!) and call the resizer plugin on them.

You may be able to optimise this further if we could see your AJAX call.


Generally speaking, I would do it this way..

$.ajax({
  type : "GET",
  url : "/loadstuff",
  success: function(responseHtml) {
    var div = $("#containerDiv").append(responseHtml);
    $("textarea", div).resizer("250px");
  }
});


Wondering if you could use .load for this. For example:

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

0

精彩评论

暂无评论...
验证码 换一张
取 消