Вернуть "True" в пустой массив селектора jQuery?

Я работаю над созданием более семантического способа проверки элементов с помощью jQuery. Использование $("#element").length > 0 просто не очень хорошо написано для меня, поэтому я делаю свое собственное селекторное дополнение для использования в .is:

if($("#element").is(":present")) {
  console.log("It aliiiveeee!!");
}

Эта часть была простой, например:

$.extend($.expr[':'],{
    present: function(a) {
        return $(a).length > 0;
    }
});

Я хочу сделать еще один шаг и упростить, если элемент не существует, используя аналогичный синтаксис:

$.extend($.expr[':'],{
    present: function(a) {
        return $(a).length > 0;
    },
    absent: function(a) {
        return $(a).length === 0;
    }
});

$(function() {
  if($("#element").is(":absent")) {
    console.log("He dead, Jim.");
  }
});

Но эта часть удивительно трудно сделать. Я думаю, это потому, что я обрабатываю возвращаемые элементы, чтобы получить результат, а синтаксический выбор селектора на .length === 0 - это то же самое, что и просить никаких элементов: он возвращает false независимо от того, что.

Я пробовал много разных способов отменить вещи и заставить это возвращать true, когда элемент не существует, и false, если он делает:

return $(a).length === 0;

return !($(a).length > 0);

if(!($(a).length > 0)) { 
  return true;
} 

if($(a).length > 0) { 
  return false;
} else {
  return true;
}

return !!($(a).length === 0);

// etc...

Есть ли простой способ заставить это просто вернуть true, если элемент не существует, а false, если он делает?

Ответы

Ответ 1

Определение is:

Проверьте текущий согласованный набор элементов на объект селектора, элемента или jQuery и верните true, если хотя бы один из этих элементов соответствует заданным аргументам.

Проблема в том, что, поскольку у вас нет элементов, невозможно, чтобы один из ваших элементов соответствовал некоторому условию. jQuery даже не вызывает ваш код, потому что нет элементов.

РЕДАКТ.: Чтобы немного уточнить, ваш код вызывается один раз для каждого элемента вашего объекта (по крайней мере, до тех пор, пока не вернется true). Никакие элементы не означают, что код никогда не вызывается. a в вашем коде всегда один элемент.

EDIT2. Имея это в виду, это будет более эффективная реализация present:

$.extend($.expr[':'],{
    present: function(a) {
        return true;
    }
});

Ответ 2

Вы можете просто использовать

if(​$('element').length) // 1 or 0 will be returned

или

$.extend($.expr[':'],{
    present: function(a) {
        return $(a).length;
    }
});

if($('#element').is(':present'))
{
    // code for existence
}
else
{
    // code for non-existence
}

Пример.

Ответ 3

Учитывая, что $().is() даже не запускается, когда коллекция пуста, селектор :present является излишним. Поэтому вместо того, чтобы играть с $.expr[':'], я бы продолжил расширение $.fn, чтобы содержать соответствующую функцию, например:

$.fn.extend({
    hasAny: function() {
        return this.length > 0;
    },
});

или

$.fn.extend({
    isEmpty: function() {
        return this.length == 0;
    },
});

Причина, по которой я лично пойду с этим подходом, заключается в том, что селектора обычно используются для проверки конкретных свойств элементов (сравните :checked, :enabled, :selected, :hover и т.д.), не свойства элемента jQuery, установленные как целое (например, .size(), .index()).

Использование, конечно, будет похоже на следующее:

if ($('#element').isEmpty())
    console.log("He dead, Jim.");

Ответ 4

0 является "ложным" в JavaScript.

Вы можете просто вернуть !$(a).length.

Ответ 5

Как насчет:

if ( !$(a)[0] ) {
    // $(a) is empty
}

Итак, $(a)[0] извлекает первый элемент в объекте jQuery. Если этот элемент имеет значение null/ undefined, это означает, что объект jQuery пуст.