rhughes
rhughes

Reputation: 9583

A more efficient version of jQuery contains

I have the following JavaScript and jQuery, which works perfectly:

function updateTaskTypes(taskTypes) {

    $.each(taskTypes, function (idx, e) {

        var contains = $("#async_TaskTypes").find("a:contains('" + e + "')").length > 0;

        if (!contains) {

            var html = "<li><a href=\"#tab" + idx + "\">" + e + "</a></li>";

            $("#async_TaskTypes").append(html);
        }
    });
}

The above code takes an array of strings. The aim is to add an <li> to #async_TaskTypes if it doesn't already contain one.

The format of the HTML is:

<ul id="async_TaskTypes" class="tabs">
    <li><a href="#tab0">Preview Blog Comment</a></li>
    <li><a href="#tab1">Respond To Contact Us</a></li>
</ul>

My problem is the jQuery doesn't seem as efficient as it could be. Is there a way to make the above code more efficient?

By 'efficient', I mean perhaps there is a more direct jQuery function I could use, or a cleaner algorithm etc... Basically more elegant code.

Upvotes: 0

Views: 102

Answers (4)

Zoltan.Tamasi
Zoltan.Tamasi

Reputation: 1391

Another idea:

var async_TaskTypes = $("#async_TaskTypes");
async_TaskTypes.append(
    $.map(taskTypes, function (idx, e) {
        if (!async_TaskTypes.has("a:contains('" + e + "')")) {
            return $("<li>").append(
                $("<href>", {id: "tab" + idx}).text(e)
            );
        }
    })
);

Upvotes: 0

Bergi
Bergi

Reputation: 665030

A search in the DOM is always inefficient. You should have a model where you store which tasks are already on the shown list, so that you can simply search trough that with array methods (and if sorted, even possible in O(n)). This could do it, for example:

function updateTaskTypes(taskTypes) {
    var $ul = $("#async_TaskTypes"),
        texts = $ul.find("a").map(function(){
            return $(this).text();
        }).get();
    $.each(taskTypes, function (idx, e) {
        if ($.inArray(texts, e) == -1)
            $ul.append("<li><a href=\"#tab" + idx + "\">" + e + "</a></li>");
    });
}

Or you just remove all list items and reappend the whole task list, which is much simpler and might be even faster for short lists:

function updateTaskTypes(taskTypes) {
    var $ul = $("#async_TaskTypes").empty();
    $.each(taskTypes, function (idx, e) {
        $ul.append("<li><a href=\"#tab" + idx + "\">" + e + "</a></li>");
    });
}

Upvotes: 2

Zoltan.Tamasi
Zoltan.Tamasi

Reputation: 1391

Updating Bergi's answer:

function updateTaskTypes(taskTypes) {
    var $ul = $("#async_TaskTypes").empty();
    $.each(taskTypes, function (idx, e) { 
        $ul.append(
            $("<li>").append(
                $("<href>", {id: "tab" + idx}).text(e)
            );
        );
    });
}

Maybe a little bit more elegant.

Upvotes: 0

Jeffpowrs
Jeffpowrs

Reputation: 4550

Or you can actually just use a regular expression:

var a = $("#async_TaskTypes").html();
if( /Whatever/g.test(a) ) {
  //this string is present in your html
}

Upvotes: 0

Related Questions