26

Long question

Is it possible to add a DOM element only if it does not already exists?

Example

I have implemented the requirement like so:

var ins = $("a[@id='iframeUrl']");
ins.siblings('#myIframe:first').remove().end().parent().prepend('<iframe id="myIframe"  src="'+ins.attr("href")+'"></iframe>');

Is it possible to replace the second line with something more elegant? Like ins.siblings('#myIframe:first').is().not().parent().prepend ...

I could check ins.siblings('#myIframe:first').length and then add IFrame, but the curiosity took over and I'm trying to do that in the least amount of statements possible.

Mark Bell
  • 28,985
  • 26
  • 118
  • 145
Audrius
  • 2,836
  • 1
  • 26
  • 35

2 Answers2

37

I think the way you suggested (counting length) is the most efficient way, even if it does involve a bit more code:

var ins = $("a[@id='iframeUrl']");

if(ins.siblings('#myIframe:first').length == 0)
    ins.parent().prepend('<iframe id="myIframe" src="'+ins.attr("href")+'"></iframe>');

Also, the :first selector would be redundant here as there should only ever be one element with that ID, so:

var ins = $("a[@id='iframeUrl']");

if($('#myIframe').length == 0)
    ins.parent().prepend('<iframe id="myIframe" src="'+ins.attr("href")+'"></iframe>');

would also work.

Edit: as Fydo mentions in the comments, the length check can also be shortened, so the tersest form would be:

var ins = $("a[@id='iframeUrl']");

if(!$('#myIframe').length)
    ins.parent().prepend('<iframe id="myIframe" src="'+ins.attr("href")+'"></iframe>');

Note the exclamation mark before the selector in the if condition!

Mark Bell
  • 28,985
  • 26
  • 118
  • 145
  • Out of interest, what if we do not pay attention to efficiency, are the other way without checking the length property or using any "normal" boolean operations? Are there a way to do that using only jQuery and function chaining? My curiosity organ is itching (-. – Audrius Oct 30 '09 at 10:55
  • Not that I'm aware of, other than the solution you posted (removing first whether it exists or not then re-adding). There's some discussion here though: http://stackoverflow.com/questions/31044/is-there-an-exists-function-for-jquery – Mark Bell Oct 30 '09 at 11:47
  • you'd think that jquery would have a util for whether or not an element exists instead of remembering to use the length of an element equating to zero. I keep forgetting about that trick :-| – sksallaj Sep 05 '12 at 20:50
  • ($('#myIframe').length == 0) can be shortened to (!$('#myIframe').length) – Fydo Sep 05 '13 at 19:32
1

I needed something similar and I always try to reduce the amount of code, so I wrote this little helper function (TypeScript).

$.fn.getOrAddChild = function(selector: string, html: string): JQuery {
  var $parent = <JQuery>this;
  if (!$parent.length)
    throw new Error("Parent is empty");
  var $child = $parent.children(selector);
  if (!$child.length)
    $child = $(html).appendTo($parent);
  return $child;
}

// Usage
$("div.myDiv").getOrAddChild("div.myChildDiv", "<div class='myChildDiv'/>");
Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93