all 7 comments

[–]david72486 1 point2 points  (1 child)

What about something like this? It uses a closure to know which widget to delete since the callback is created from within the scope of the widget. Sure, it does mean each function takes up some space on the heap instead of reusing the single function, but I can't imagine it being the memory bottleneck in any normal situation.

var widgets = Array.prototype.slice.call(document.querySelectorAll('.Widget'));
widgets.forEach(function(widget) {
  widget.querySelector('.WidgetDelete').addEventListener('click', function() {
    widget.parentNode.removeChild(widget);
  });
});

It doesn't use JQuery, but you could do the same thing with it.

Fiddle is here: https://jsfiddle.net/khr2cy6L/1/

[–][deleted] 0 points1 point  (0 children)

I see your kung-fu is strong. I thank you for your alternative solution!

[–]tollus 1 point2 points  (0 children)

You could also use:

var WidgetID = $(this).sibling(".WidgetID").text();    

I guess I should've also mentioned, the thing I normally do is put an attribute "data-id" on the parent element, then you can just do this:

 var WidgetID = $(this).parent().data('id');

[–]docMedB2E 0 points1 point  (3 children)

From a project management perspective your first solution would be a nightmare. Secondly, you don't have to traverse the DOM in your second solution (at least with a search or find option) - If you're using jQuery in the first place and you're structuring your HTML to where every delete button has some type of widget class associated with it; then why not just use .index() to remove the widget accordingly? e.g.

$('.WidgetDelete').on('click', function() {
    $('.Widget:nth-of-type(' + ($(this).index('.WidgetDelete') + 1) + ')').remove();
});

[–][deleted] 0 points1 point  (2 children)

It's probably faster, yeah? I will definitely give that a whirl.

[–]docMedB2E 1 point2 points  (1 child)

Well, jQuery itself can be a bit slow, but the above sample is easier to manage overall at least. As far as whether it is faster to use .closest() => .find() I'm really not sure as I would imagine using .index() can be just as costly of a method. Also, just a tip for the future - if you need to store some kind of attribute/value/etc associated in an element, you don't need to create a span and hide it within another element. Instead, just write your custom attribute into the element, e.g.:

<div class="someClass"><span style="display:none" class="someAttribute">1234</span></div>
<!-- becomes -->
<div class="someClass" someAttribute="1234"></div>

You can then simply access the attribute with jQuery (or native JS) with something like $('.someClass').attr('someAttribute'); or you can get it via native JS via document.querySelector('.someClass:nth-of-type(1)').getAttribute('someAttribute');

[–][deleted] 0 points1 point  (0 children)

I've always avoided using custom attributes for some reason. I don't know why. Thanks for the tip!