Как я могу проверить существование элемента в jQuery?
Текущий код, который у меня есть, это:
if ($(selector).length > 0) {
// Do something
}
Есть ли более элегантный способ подойти к этому? Возможно, плагин или функция?
Как я могу проверить существование элемента в jQuery?
Текущий код, который у меня есть, это:
if ($(selector).length > 0) {
// Do something
}
Есть ли более элегантный способ подойти к этому? Возможно, плагин или функция?
Ответы:
В JavaScript все «правдиво» или «ложно», а для чисел 0
(и NaN) означает false
все остальное true
. Чтобы вы могли написать:
if ($(selector).length)
Вам не нужна эта >0
часть.
NaN != false
.
[] + []
= ""
... ааа, я люблю javascript
[].toString() === [].join(',') === ""
и "" === ""
.
typeof NaN == 'number'
Да!
jQuery.fn.exists = function(){ return this.length > 0; }
if ($(selector).exists()) {
// Do something
}
Это в ответ на: подкаст Herding Code с Джеффом Этвудом
$.fn.exists
пример заменяет поиск свойства (дешево!) Двумя вызовами функций, которые намного дороже, и один из этих вызовов функций воссоздает объект jQuery, который у вас уже есть, что просто глупо.
.exists
читается чисто, тогда как .length
читается как что-то семантически другое, даже если семантика совпадает с идентичным результатом.
Если вы использовали
jQuery.fn.exists = function(){return ($(this).length > 0);}
if ($(selector).exists()) { }
Вы подразумеваете, что цепочка была возможна, когда это не так.
Это было бы лучше:
jQuery.exists = function(selector) {return ($(selector).length > 0);}
if ($.exists(selector)) { }
В качестве альтернативы из FAQ :
if ( $('#myDiv').length ) { /* Do something */ }
Вы также можете использовать следующее. Если в массиве объектов jQuery нет значений, то получение первого элемента в массиве вернет undefined.
if ( $('#myDiv')[0] ) { /* Do something */ }
$(".missing").css("color", "red")
уже делает правильные вещи ... (т.е. ничего)
$.fn
методов jQuery, которые возвращают что-то отличное от нового объекта jQuery и, следовательно, не связываются.
Вы можете использовать это:
// if element exists
if($('selector').length){ /* do something */ }
// if element does not exist
if(!$('selector').length){ /* do something */ }
Самый быстрый и наиболее семантически понятный способ проверки существования на самом деле - это использование обычного JavaScript
:
if (document.getElementById('element_id')) {
// Do something
}
Это немного длиннее для записи, чем альтернатива длины jQuery, но выполняется быстрее, поскольку это нативный метод JS.
И это лучше, чем альтернатива написания собственной jQuery
функции. Эта альтернатива медленнее, по причинам, указанным @snover. Но это также создало бы у других программистов впечатление, что эта exists()
функция присуща jQuery. JavaScript
будут / должны быть поняты другими, редактирующими ваш код, без увеличения долга знаний.
NB: обратите внимание на отсутствие знака «#» перед element_id
(поскольку это обычный JS, а не jQuery
).
$('#foo a.special')
. И он может вернуть более одного элемента. getElementById
не могу начать приближаться к этому.
if(document.querySelector("#foo a.special"))
будет работать. Нет необходимости JQuery.
Вы можете сохранить несколько байтов, написав:
if ($(selector)[0]) { ... }
Это работает, потому что каждый объект jQuery также маскируется как массив, поэтому мы можем использовать оператор разыменования массива, чтобы получить первый элемент из массива . Возвращается, undefined
если в указанном индексе нет элемента.
jQuery.first()
или jQuery.eq(0)
оба возвращают объекты, объекты являются правдивыми, даже если они пустые. Этот пример должен проиллюстрировать, почему эти функции нельзя использовать как есть:if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists")
.eq(0)
возвращает просто еще один объект jQuery, усеченный до длины 1 или 0. .first()
Это просто удобный метод для .eq(0)
. Но .get(0)
возвращает первый элемент DOM или undefined
и так же, как [0]
. Первый элемент DOM в объекте jQuery хранится в свойстве обычного объекта с именем '0'
. Это простой доступ к свойству. Единственное приведение типов происходит от неявного преобразования числа 0
в строку '0'
. Так что, если приведение типов является проблемой, вы можете использовать $.find(selector)['0']
вместо этого.
Ты можешь использовать:
if ($(selector).is('*')) {
// Do something
}
Чуть более элегантно, возможно.
666
вероятно, имеют множество других причин, по которым их код не работает. Хотя это недопустимый селектор, $ (666) .length является допустимым javascript : он оценивается как правдивый и поэтому должен удовлетворять условию.
$.find(666).length
работает.
Этот плагин можно использовать в if
выражении типа if ($(ele).exist()) { /* DO WORK */ }
или с помощью обратного вызова.
;;(function($) {
if (!$.exist) {
$.extend({
exist: function() {
var ele, cbmExist, cbmNotExist;
if (arguments.length) {
for (x in arguments) {
switch (typeof arguments[x]) {
case 'function':
if (typeof cbmExist == "undefined") cbmExist = arguments[x];
else cbmNotExist = arguments[x];
break;
case 'object':
if (arguments[x] instanceof jQuery) ele = arguments[x];
else {
var obj = arguments[x];
for (y in obj) {
if (typeof obj[y] == 'function') {
if (typeof cbmExist == "undefined") cbmExist = obj[y];
else cbmNotExist = obj[y];
}
if (typeof obj[y] == 'object' && obj[y] instanceof jQuery) ele = obj[y];
if (typeof obj[y] == 'string') ele = $(obj[y]);
}
}
break;
case 'string':
ele = $(arguments[x]);
break;
}
}
}
if (typeof cbmExist == 'function') {
var exist = ele.length > 0 ? true : false;
if (exist) {
return ele.each(function(i) { cbmExist.apply(this, [exist, ele, i]); });
}
else if (typeof cbmNotExist == 'function') {
cbmNotExist.apply(ele, [exist, ele]);
return ele;
}
else {
if (ele.length <= 1) return ele.length > 0 ? true : false;
else return ele.length;
}
}
else {
if (ele.length <= 1) return ele.length > 0 ? true : false;
else return ele.length;
}
return false;
}
});
$.fn.extend({
exist: function() {
var args = [$(this)];
if (arguments.length) for (x in arguments) args.push(arguments[x]);
return $.exist.apply($, args);
}
});
}
})(jQuery);
Вы можете указать один или два обратных вызова. Первый будет срабатывать, если элемент существует, второй будет срабатывать, если элемент не существует. Однако, если вы решите передать только одну функцию, она будет срабатывать только тогда, когда элемент существует. Таким образом, цепь умрет, если выбранный элемент не существует. Конечно, если она существует, первая функция сработает и цепочка продолжится.
Имейте в виду, что использование варианта обратного вызова помогает поддерживать цепочечность - элемент возвращается, и вы можете продолжить цепочку команд, как и с любым другим методом jQuery!
if ($.exist('#eleID')) { /* DO WORK */ } // param as STRING
if ($.exist($('#eleID'))) { /* DO WORK */ } // param as jQuery OBJECT
if ($('#eleID').exist()) { /* DO WORK */ } // enduced on jQuery OBJECT
$.exist('#eleID', function() { // param is STRING && CALLBACK METHOD
/* DO WORK */
/* This will ONLY fire if the element EXIST */
}, function() { // param is STRING && CALLBACK METHOD
/* DO WORK */
/* This will ONLY fire if the element DOES NOT EXIST */
})
$('#eleID').exist(function() { // enduced on jQuery OBJECT with CALLBACK METHOD
/* DO WORK */
/* This will ONLY fire if the element EXIST */
})
$.exist({ // param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
element: '#eleID',
callback: function() {
/* DO WORK */
/* This will ONLY fire if the element EXIST */
}
})
Has Items
обратный вызов фактически передать объект в качестве аргумента?
Я вижу, что большинство ответов здесь не являются точными, как они должны быть, они проверяют длину элемента, во многих случаях это может быть нормально , но не на 100% , представьте, что вместо функции передается число, поэтому я создаю прототип функции, которая проверяет все условия и вернуть ответ так, как должно быть:
$.fn.exists = $.fn.exists || function() {
return !!(this.length && (this[0] instanceof HTMLDocument || this[0] instanceof HTMLElement));
}
Это проверит длину и тип, теперь вы можете проверить это следующим образом:
$(1980).exists(); //return false
$([1,2,3]).exists(); //return false
$({name: 'stackoverflow', url: 'http://www.stackoverflow.com'}).exists(); //return false
$([{nodeName: 'foo'}]).exists() // returns false
$('div').exists(); //return true
$('.header').exists(); //return true
$(document).exists(); //return true
$('body').exists(); //return true
На самом деле нет необходимости в jQuery. С простым JavaScript легче и семантически правильно проверить:
if(document.getElementById("myElement")) {
//Do something...
}
Если по какой-либо причине вы не хотите добавлять идентификатор к элементу, вы все равно можете использовать любой другой метод JavaScript, предназначенный для доступа к DOM.
JQuery действительно крутой, но не позволяйте чистому JavaScript забыться ...
:has()
?
Причина, по которой все предыдущие ответы требуют этот .length
параметр, заключается в том, что они в основном используют $()
селектор jquery, у которого querySelectorAll находится за занавесом (или они используют его напрямую). Этот метод довольно медленный, потому что ему нужно проанализировать все дерево DOM, найти все совпадения с этим селектором и заполнить им массив.
Параметр ['length'] не нужен и не полезен, и код будет намного быстрее, если document.querySelector(selector)
вместо этого использовать его напрямую , поскольку он возвращает первый соответствующий элемент или ноль, если не найден.
function elementIfExists(selector){ //named this way on purpose, see below
return document.querySelector(selector);
}
/* usage: */
var myelement = elementIfExists("#myid") || myfallbackelement;
Однако этот метод оставляет нас с фактическим возвращаемым объектом; что хорошо, если он не будет сохраняться как переменная и использоваться повторно (таким образом, сохраняя ссылку, если мы забудем).
var myel=elementIfExists("#myid");
// now we are using a reference to the element which will linger after removal
myel.getParentNode.removeChild(myel);
console.log(elementIfExists("#myid")); /* null */
console.log(myel); /* giant table lingering around detached from document */
myel=null; /* now it can be garbage collected */
В некоторых случаях это может быть желательно. Его можно использовать в цикле for следующим образом:
/* locally scoped myel gets garbage collected even with the break; */
for (var myel; myel = elementIfExist(sel); myel.getParentNode.removeChild(myel))
if (myel == myblacklistedel) break;
Если вам на самом деле не нужен элемент и вы хотите получить / сохранить только значение true / false, просто удвойте его! Это работает для обуви, которая развязана, так почему узел здесь?
function elementExists(selector){
return !!document.querySelector(selector);
}
/* usage: */
var hastables = elementExists("table"); /* will be true or false */
if (hastables){
/* insert css style sheet for our pretty tables */
}
setTimeOut(function (){if (hastables && !elementExists("#mytablecss"))
alert("bad table layouts");},3000);
Это $.contains()
то, что вы хотите?
jQuery.contains( container, contained )
$.contains()
Метод возвращает истину , если DOM элемент , предусмотренный вторым аргументом является потомком элемента DOM , предоставленного первым аргументом, является ли это прямым потомком или более глубоко вложенным. В противном случае возвращается false. Поддерживаются только узлы элементов; если второй аргумент является узлом текста или комментария,$.contains()
вернет false.Примечание . Первый аргумент должен быть элементом DOM, а не объектом jQuery или обычным объектом JavaScript.
Я обнаружил, if ($(selector).length) {}
что недостаточно. Это будет молча сломать ваше приложение, когда selector
пустой объект {}
.
var $target = $({});
console.log($target, $target.length);
// Console output:
// -------------------------------------
// [▼ Object ] 1
// ► __proto__: Object
Мое единственное предложение - выполнить дополнительную проверку {}
.
if ($.isEmptyObject(selector) || !$(selector).length) {
throw new Error('Unable to work with the given selector.');
}
Я все еще ищу лучшее решение, хотя это немного тяжело.
Редактировать: ВНИМАНИЕ! Это не работает в IE, когда selector
это строка.
$.isEmptyObject('hello') // FALSE in Chrome and TRUE in IE
$()
пустой объект в качестве аргумента?
{}
в $()
?
Вы можете проверить наличие или отсутствие элемента в java-скрипте. Если длина больше нуля, то элемент присутствует, если длина равна нулю, то элемент отсутствует
// These by Id
if ($("#elementid").length > 0) {
// Element is Present
} else {
// Element is not Present
}
// These by Class
if ($(".elementClass").length > 0) {
// Element is Present
} else {
// Element is not Present
}
Проверка существования элемента четко документирована на самом официальном сайте jQuery!
Используйте свойство .length коллекции jQuery, возвращаемой вашим селектором:
if ($("#myDiv").length) { $("#myDiv").show(); }
Обратите внимание, что не всегда необходимо проверять, существует ли элемент. Следующий код покажет элемент, если он существует, и ничего не сделает (без ошибок), если он не существует:
$("#myDiv").show();
это очень похоже на все ответы, но почему бы не использовать !
оператор дважды, чтобы вы могли получить логическое значение:
jQuery.fn.exists = function(){return !!this.length};
if ($(selector).exists()) {
// the element exists, now what?...
}
$(selector).length && //Do something
if
где if
они улучшат читабельность за счет 2 байтов.
Попробуйте проверить DOM
элемент
if (!!$(selector)[0]) // do stuff
Вдохновленный ответом хайвея, я придумал следующее:
$.fn.exists = function() {
return $.contains( document.documentElement, this[0] );
}
jQuery.contains принимает два элемента DOM и проверяет, содержит ли первый элемент второй.
Использование document.documentElement
в качестве первого аргумента удовлетворяет семантике exists
метода, когда мы хотим применить его исключительно для проверки существования элемента в текущем документе.
Ниже я соединил фрагмент , который сравнивает jQuery.exists()
против $(sel)[0]
и $(sel).length
подходов , которые возвращают truthy
значения в $(4)
то время $(4).exists()
возвращается false
. В контексте проверки существования элемента в DOM это, кажется, желаемый результат .
Нет необходимости в jQuery (базовое решение)
if(document.querySelector('.a-class')) {
// do something
}
Гораздо более производительный вариант ниже (обратите внимание на отсутствие точки перед классом).
if(document.getElementsByClassName('a-class')[0]) {
// do something
}
querySelector использует правильный механизм сопоставления, такой как $ () (sizzle) в jQuery, и использует больше вычислительной мощности, но в 99% случаев все будет в порядке. Второй вариант более явный и сообщает коду, что именно делать. Это намного быстрее, согласно jsperf https://jsperf.com/getelementsbyclassname-vs-queryselectorall/25
Мне просто нравится использовать простой ванильный JavaScript для этого.
function isExists(selector){
return document.querySelectorAll(selector).length>0;
}
Я наткнулся на этот вопрос, и я хотел бы поделиться фрагментом кода, который я сейчас использую:
$.fn.exists = function(callback) {
var self = this;
var wrapper = (function(){
function notExists () {}
notExists.prototype.otherwise = function(fallback){
if (!self.length) {
fallback.call();
}
};
return new notExists;
})();
if(self.length) {
callback.call();
}
return wrapper;
}
И теперь я могу написать такой код -
$("#elem").exists(function(){
alert ("it exists");
}).otherwise(function(){
alert ("it doesn't exist");
});
Может показаться, что кода много, но когда он написан на CoffeeScript, он довольно маленький:
$.fn.exists = (callback) ->
exists = @length
callback.call() if exists
new class
otherwise: (fallback) ->
fallback.call() if not exists
У меня был случай, когда я хотел посмотреть, существует ли объект внутри другого, поэтому я добавил что-то в первый ответ, чтобы проверить селектор внутри селектора.
// Checks if an object exists.
// Usage:
//
// $(selector).exists()
//
// Or:
//
// $(selector).exists(anotherSelector);
jQuery.fn.exists = function(selector) {
return selector ? this.find(selector).length : this.length;
};
Как насчет:
function exists(selector) {
return $(selector).length;
}
if (exists(selector)) {
// do something
}
Это очень минимально и избавляет вас от необходимости включать селектор с $()
каждым разом.
if($("#thing").exists(){}
читается как. Кроме того, это не способ JQuery.
Я использую это:
$.fn.ifExists = function(fn) {
if (this.length) {
$(fn(this));
}
};
$("#element").ifExists(
function($this){
$this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});
}
);
Выполнять цепочку, только если существует элемент jQuery - http://jsfiddle.net/andres_314/vbNM3/2/
Вот мой любимый exist
метод в jQuery
$.fn.exist = function(callback) {
return $(this).each(function () {
var target = $(this);
if (this.length > 0 && typeof callback === 'function') {
callback.call(target);
}
});
};
и другая версия, которая поддерживает обратный вызов, когда селектор не существует
$.fn.exist = function(onExist, onNotExist) {
return $(this).each(function() {
var target = $(this);
if (this.length > 0) {
if (typeof onExist === 'function') {
onExist.call(target);
}
} else {
if (typeof onNotExist === 'function') {
onNotExist.call(target);
}
}
});
};
Пример:
$('#foo .bar').exist(
function () {
// Stuff when '#foo .bar' exists
},
function () {
// Stuff when '#foo .bar' does not exist
}
);
$("selector"
) возвращает объект, который имеет length
свойство. Если селектор найдет какие-либо элементы, они будут включены в объект. Поэтому, если вы проверите его длину, вы увидите, существуют ли какие-либо элементы. В JavaScript 0 == false
, так что если вы не получите 0
ваш код будет работать.
if($("selector").length){
//code in the case
}
Вот полный пример различных ситуаций и способ проверить, существует ли элемент, используя direct, если на jQuery селектор может или не может работать, потому что он возвращает массив или элементы.
var a = null;
var b = []
var c = undefined ;
if(a) { console.log(" a exist")} else { console.log("a doesn't exit")}
// output: a doesn't exit
if(b) { console.log(" b exist")} else { console.log("b doesn't exit")}
// output: b exist
if(c) { console.log(" c exist")} else { console.log("c doesn't exit")}
// output: c doesn't exit
ОКОНЧАТЕЛЬНОЕ РЕШЕНИЕ
if($("#xysyxxs").length){ console.log("xusyxxs exist")} else { console.log("xusyxxs doesnn't exist") }
//output : xusyxxs doesnn't exist
if($(".xysyxxs").length){ console.log("xusyxxs exist")} else { console.log("xusyxxs doesnn't exist") }
//output : xusyxxs doesnn't exist
Вам не нужно проверять, больше ли оно, чем 0
нравится $(selector).length > 0
, $(selector).length
достаточно и элегантного способа проверить наличие элементов. Я не думаю, что стоит написать функцию только для этого, если вы хотите сделать больше лишних вещей, да.
if($(selector).length){
// true if length is not 0
} else {
// false if length is 0
}