Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .wrap() not wrapping around a cloned element

(function($) {
  $.extend({
    notify: function(options, duration) {
      var defaults = {
        inline: true,
        href: '',
        html: ''
      };
      var options = $.extend(defaults, options);

      var body = $('body'),
        container = $('<ul></ul>').attr('id', 'notification_area'),
        wrapper = '<li class="notification"></li>',
        clone;

      if (!body.hasClass('notifications_active')) {
        body.append(container).addClass('notifications_active');
      }

      if (options.inline == true && options.href) {
        clone = $(options.href).clone().wrap(wrapper);
      }

      clone.css('visibility', 'hidden').appendTo(container);

      var clone_height = 0 - parseInt(clone.outerHeight());
      clone.css('marginBottom', clone_height);

      clone.animate({
        marginBottom: 0
      }, 'fast', function() {
        clone.hide().css('visibility', 'visible').fadeIn('fast');
      });
    }
  });
})(jQuery);

$(function() {
  $('a').click(function() {
    $.notify({
      inline: true,
      href: '#alert'
    }, 3000)
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

http://jsfiddle.net/sambenson/RmkEN/

In the above example I'm cloning an element and attempting to wrap it with and <li></li> but the clone isn't being wrapped at all. Why?

like image 939
Sam Avatar asked Dec 16 '11 09:12

Sam


2 Answers

The key is this line in the .wrap() documentation:

This method returns the original set of elements for chaining purposes.

.wrap() only operates on an element already in the DOM. So, you will need to insert it, then wrap it.

like image 182
Interrobang Avatar answered Sep 28 '22 04:09

Interrobang


The confusing part is that .wrap() returns the inner element, not the parent element.

So you have to use the parent object of the wrapped one as follows:

var $divA= $("<div/>").addClass('classA'),
    $divB= $("<div/>").addClass('classB');

console.log( $divA.wrap($divB).parent() );

($divA.parent() is equal to $divB after the wrapping)

So the key part is that $divA.wrap($divB) returns $divA, NOT $divB

see the reference:

This method returns the original set of elements for chaining purposes.

Please note: The elements DON'T have to be in the DOM, jQuery can operate on them without them already having been inserted into the DOM.

like image 29
Denes Papp Avatar answered Sep 28 '22 03:09

Denes Papp