diff --git a/misc/ajax.js b/misc/ajax.js
index bb4a6e1..cfadcc8 100644
--- a/misc/ajax.js
+++ b/misc/ajax.js
@@ -230,16 +230,16 @@ Drupal.ajax = function (base, element, element_settings) {
  * will test to see if the key press is valid to trigger this event and
  * if it is, trigger it for us and prevent other keypresses from triggering.
  * In this case we're handling RETURN and SPACEBAR keypresses (event codes 13
- * and 32. RETURN is often used to submit a form when in a textfield, and 
- * SPACE is often used to activate an element without submitting. 
+ * and 32. RETURN is often used to submit a form when in a textfield, and
+ * SPACE is often used to activate an element without submitting.
  */
 Drupal.ajax.prototype.keypressResponse = function (element, event) {
   // Create a synonym for this to reduce code confusion.
   var ajax = this;
 
   // Detect enter key and space bar and allow the standard response for them,
-  // except for form elements of type 'text' and 'textarea', where the 
-  // spacebar activation causes inappropriate activation if #ajax['keypress'] is 
+  // except for form elements of type 'text' and 'textarea', where the
+  // spacebar activation causes inappropriate activation if #ajax['keypress'] is
   // TRUE. On a text-type widget a space should always be a space.
   if (event.which == 13 || (event.which == 32 && element.type != 'text' && element.type != 'textarea')) {
     $(ajax.element_settings.element).trigger(ajax.element_settings.event);
@@ -542,33 +542,43 @@ Drupal.ajax.prototype.commands = {
         Drupal.detachBehaviors(wrapper, settings);
     }
 
-    // Add the new content to the page.
-    wrapper[method](new_content);
+    // Add the new content to the DOM.
+    // jQuery will only allow an object to be added to the DOM tree once so,
+    // to maintain functionality with behaviours and effects, we explicitly
+    // clone and store a copy of new_content for each replacement.
+    var new_elements = [];
+    wrapper.each(function() {
+      var new_element = new_content.clone();
+      $(this)[method](new_element);
+      new_elements[] = new_element;
+    });
 
     // Immediately hide the new content if we're using any effects.
     if (effect.showEffect != 'show') {
-      new_content.hide();
+      $(new_elements).hide();
     }
 
     // Determine which effect to use and what content will receive the
     // effect, then show the new content.
-    if ($('.ajax-new-content', new_content).length > 0) {
-      $('.ajax-new-content', new_content).hide();
-      new_content.show();
-      $('.ajax-new-content', new_content)[effect.showEffect](effect.showSpeed);
+    if ($('.ajax-new-content', $(new_elements)).length > 0) {
+      $('.ajax-new-content', $(new_elements)).hide();
+      $(new_elements).show();
+      $('.ajax-new-content', $(new_elements))[effect.showEffect](effect.showSpeed);
     }
     else if (effect.showEffect != 'show') {
-      new_content[effect.showEffect](effect.showSpeed);
+      $(new_elements)[effect.showEffect](effect.showSpeed);
     }
 
-    // Attach all JavaScript behaviors to the new content, if it was successfully
-    // added to the page, this if statement allows #ajax['wrapper'] to be
-    // optional.
-    if (new_content.parents('html').length > 0) {
-      // Apply any settings from the returned JSON if available.
-      var settings = response.settings || ajax.settings || Drupal.settings;
-      Drupal.attachBehaviors(new_content, settings);
-    }
+    // Attach all JavaScript behaviors to the new elements one at a time,
+    // if it was the element was successfully added to the page, this if
+    // statement allows #ajax['wrapper'] to be optional.
+    $(new_elements).each(function() {
+      if ($(this).parents('html').length > 0) {
+        // Apply any settings from the returned JSON if available.
+        var settings = response.settings || ajax.settings || Drupal.settings;
+        Drupal.attachBehaviors($(this), settings);
+      }
+    });
   },
 
   /**
