4

I have this

if(noDelay){
  $(element).find("." + options.class).remove();
} else {
  $(element).find("." + options.class).fadeOut().remove();
}

Is there a way I could avoid repeating the sentence and only add the fadeOut() when a given condition is met?

I can't move fadeOut() till the end of the chain, which probably would've made things easier.

I'm thinking something like

$(element).find("." + options.class).(if(noDelay) fadeOut()).remove();

Thanks in advance, Leo

Emre Erkan
  • 8,433
  • 3
  • 48
  • 53
leopic
  • 2,958
  • 2
  • 27
  • 42

5 Answers5

11

There is nothing documented like you want but maybe this will work for you:

$(element).find("." + options.class).fadeOut(noDelay ? 0 : 400).remove();

Why 400, because the default duration for fadeOut is 400 milliseconds. (from documentation)

Emre Erkan
  • 8,433
  • 3
  • 48
  • 53
  • Beat me to it too. However, can you use `'normal'` instead of `400`? – Merlyn Morgan-Graham Dec 08 '11 at 20:03
  • Based on [documentation](http://api.jquery.com/fadeOut/) `slow` and `fast` is valid but not `normal`. – Emre Erkan Dec 08 '11 at 20:06
  • 5
    You could use any string to signify default, If the string is not recognized and cannot be converted to an integer, it will default to the default duration. It is probably a good idea to use 'normal' rather than 400 just in case the default duration has been changed on the page in question. – Kevin B Dec 08 '11 at 20:10
  • 1
    you could also use $.fx.speeds._default in place of 400, it will be equal to 400 unless changed from default to something else without relying on figuring out what 'normal' is. – Kevin B Dec 08 '11 at 20:14
  • http://www.w3schools.com/jquery/eff_fadeout.asp claims `'normal'` works. Could be wrong, or could be relying on fallback behavior tho. You're right that the docs don't explicitly mention it. – Merlyn Morgan-Graham Dec 08 '11 at 20:20
  • 1
    LEOPiC you should check @KevinB's answer too. His alternative method is very good. – Emre Erkan Dec 08 '11 at 20:22
3

You could do this with a $.fn.each:

$(element).find("." + options.class).each(function(){
  if (nodelay) {
    $(this).remove();
  }
  else {
    $(this).fadeOut().remove();
  }
});

however it is far less efficient than simply doing what you already are doing.

Edit: here's another way to do it:

$(element).find("." + options.class)[  noDelay ? "detach" : "fadeOut"  ]().remove();

basically, if noDelay is true, it will detach the elements before removing, else, it will fade them out before removing. Should be just as efficient as your code, just on 1 line.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
2

Any objection to something like this?

var $found = $(element).find("." + options.class);
if (noDelay){
  $found.remove();
} else {
  $found.fadeOut().remove();
}
artlung
  • 33,305
  • 16
  • 69
  • 121
  • Not really, that was option b, since it's very easy on the eyes and removes most of the repetition, but I believe I will try Emre Erkan's solution, thank you tho :) – leopic Dec 08 '11 at 20:12
2
var els = $(element).find("." + options.class);
if (!nodelay) els.fadeOut();
els.remove();

Or you could use a horrible hack:

$(element).find(…)[ nodelay ? 'somenoopfunction' : 'fadeOut' ]().remove();
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • I agree it feels hackish, but '.fadeOut(noDelay ? 0 : 400)' solves it IMO, thanks a lot tho :) – leopic Dec 08 '11 at 20:16
1

This particular problem:

Try rethinking the logic slightly, and make the noDelay actually effect the delay.

$(element).find("." + options.class).fadeOut(noDelay ? 0 : 'normal').remove();

Though I'm not sure if remove() is necessary.

When I was doing fadeOut() tests for another question, it seemed to hide and collapse the element. remove() would completely remove the element from the DOM, but I'm not sure it is necessary if you just want to make it disappear from the document and have it stop effecting document flow (no gap where it was).

Real goal:

Also, it looks like you're planning to wrap jQuery. You'll end up wrapping code like this:

$("someElement").find(".someClass").fadeOut().remove();

...and changing it to something like:

fadeOut("someElement", { "class" : "someClass" });

...or:

var element = new SomeClass("someElement");
element.options.class = "someClass";
element.fadeOut();

Unless you're planning on reusing that particular element a lot, I think you're going to be wasting your time. jQuery has pretty efficient syntax for one-off operations, and you can always store matched elements in a temporary variable.

If you have some other purpose in mind that I'm missing, please excuse this intrusion on your design :)

Community
  • 1
  • 1
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
  • The code is part of a widget, $(element) refers to the element where the widget will work on top off, so I'll be using it a lot :) The widget will always fadeOut the element, but for unit testing purposes I'd like something faster (ie avoid the fadeOut). Thanks a lot for your input tho, greatly appreciated :) – leopic Dec 08 '11 at 20:21
  • Yeah, thanks for that, I modified my original comment to match your answer. – leopic Dec 08 '11 at 20:22