Как я могу проверить существование элемента в jQuery?
Текущий код, который у меня есть, это:
if ($(selector).length > 0) {
// Do something
}
Есть ли более элегантный способ подойти к этому? Возможно, плагин или функция?
30 ответов
В JavaScript все «правдиво» или «ложно», а для чисел 0
(и NaN) означает false
, все остальное true
. Чтобы вы могли написать:
if ($(selector).length)
Вам не нужна эта >0
часть.
Вдохновленный ответом hiway, я придумал следующее:
$.fn.exists = function() {
return $.contains( document.documentElement, this[0] );
}
jQuery.contains берет два элемента DOM и проверяет, содержит ли первый элемент второй.
Использование document.documentElement
в качестве первого аргумента удовлетворяет семантике метода exists
, когда мы хотим применить его исключительно для проверки существования элемента в текущем документе.
Ниже я собрал фрагмент, который сравнивает jQuery.exists()
с подходами $(sel)[0]
и $(sel).length
, которые оба возвращают truthy
значения для $(4)
, а {{X5} } возвращает false
. В контексте проверки наличия элемента в DOM это, кажется, желаемый результат .
$.fn.exists = function() {
return $.contains(document.documentElement, this[0]);
}
var testFuncs = [
function(jq) { return !!jq[0]; },
function(jq) { return !!jq.length; },
function(jq) { return jq.exists(); },
];
var inputs = [
["$()",$()],
["$(4)",$(4)],
["$('#idoexist')",$('#idoexist')],
["$('#idontexist')",$('#idontexist')]
];
for( var i = 0, l = inputs.length, tr, input; i < l; i++ ) {
input = inputs[i][1];
tr = "<tr><td>" + inputs[i][0] + "</td><td>"
+ testFuncs[0](input) + "</td><td>"
+ testFuncs[1](input) + "</td><td>"
+ testFuncs[2](input) + "</td></tr>";
$("table").append(tr);
}
td { border: 1px solid black }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="idoexist">#idoexist</div>
<table style>
<tr>
<td>Input</td><td>!!$(sel)[0]</td><td>!!$(sel).length</td><td>$(sel).exists()</td>
</tr>
</table>
<script>
$.fn.exists = function() {
return $.contains(document.documentElement, this[0]);
}
</script>
Вот полный пример различных ситуаций и способ проверить, существует ли элемент, используя 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
Нет необходимости в 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 а>
Я вижу, что большинство ответов здесь не точны , как и должно быть, они проверяют длину элемента, во многих случаях это может быть ОК , но не 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
Вы можете использовать:
if ($(selector).is('*')) {
// Do something
}
Возможно, немного более элегантный.
Проверка существования элемент аккуратно задокументирован на официальном сайте jQuery!
Используйте .length коллекцию jQuery, возвращенную вашим селектор:
if ($("#myDiv").length) { $("#myDiv").show(); }
Обратите внимание, что не всегда необходимо проверять, существует ли элемент. Следующий код покажет элемент, если он существует, и ничего не сделает (без ошибок), если он не существует:
$("#myDiv").show();
Этот плагин можно использовать в выражении if
, например if ($(ele).exist()) { /* DO WORK */ }
, или с помощью обратного вызова.
Plugin
;;(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 */
}
})
Вы можете использовать это:
// if element exists
if($('selector').length){ /* do something */ }
// if element does not exist
if(!$('selector').length){ /* do something */ }
Вот мой любимый метод 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
}
);
Вы можете использовать это:
jQuery.fn.extend({
exists: function() { return this.length }
});
if($(selector).exists()){/*do something*/}
На самом деле нет необходимости в jQuery. С простым JavaScript легче и семантически правильно проверить:
if(document.getElementById("myElement")) {
//Do something...
}
Если по какой-либо причине вы не хотите добавлять идентификатор к элементу, вы все равно можете использовать любой другой метод JavaScript, предназначенный для доступа к DOM.
JQuery действительно крутой, но не позволяйте чистому JavaScript забыться ...
Это очень похоже на все ответы, но почему бы не использовать оператор !
дважды, чтобы получить логическое значение:
jQuery.fn.exists = function(){return !!this.length};
if ($(selector).exists()) {
// the element exists, now what?...
}
У меня был случай, когда я хотел посмотреть, существует ли объект внутри другого, поэтому я добавил что-то в первый ответ, чтобы проверить селектор внутри селектора.
// 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;
};
Мне просто нравится использовать простой ванильный JavaScript для этого.
function isExists(selector){
return document.querySelectorAll(selector).length>0;
}
Я обнаружил, что 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
Я наткнулся на этот вопрос, и я хотел бы поделиться фрагментом кода, который я сейчас использую:
$.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
$("selector"
) возвращает объект, обладающий свойством length
. Если селектор найдет какие-либо элементы, они будут включены в объект. Поэтому, если вы проверите его длину, вы увидите, существуют ли какие-либо элементы. В JavaScript 0 == false
, поэтому, если вы не получите 0
, ваш код будет работать.
if($("selector").length){
//code in the case
}
Если вы использовали
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 */ }
Вы можете сохранить несколько байтов, написав:
if ($(selector)[0]) { ... }
Это работает, потому что каждый объект jQuery также маскируется как массив, поэтому мы можем использовать оператор разыменования массива, чтобы получить первый элемент из array . Возвращает undefined
, если по указанному индексу нет элемента.
Является ли $.contains()
тем, что вы хотите?
jQuery.contains( container, contained )
Метод
$.contains()
возвращает значение true, если элемент DOM, предоставленный вторым аргументом, является потомком элемента DOM, предоставленного первым аргументом, является ли он прямым дочерним элементом или вложенным более глубоко. В противном случае возвращается false. Поддерживаются только узлы элементов; если второй аргумент является узлом текста или комментария,$.contains()
вернет false.Примечание . Первый аргумент должен быть элементом DOM, а не объектом jQuery или простым объектом JavaScript.
Я использую это:
$.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/
Да!
jQuery.fn.exists = function(){ return this.length > 0; }
if ($(selector).exists()) {
// Do something
}
Это ответ на подкаст «Стадный код» с Джеффом Этвудом
Как насчет:
function exists(selector) {
return $(selector).length;
}
if (exists(selector)) {
// do something
}
Он очень минимален и избавляет вас от необходимости заключать селектор в $()
каждый раз.
Попробуйте проверить элемент DOM
if (!!$(selector)[0]) // do stuff
Самый быстрый и наиболее семантически понятный способ проверки существования - это использование простого JavaScript
:
if (document.getElementById('element_id')) {
// Do something
}
Это немного длиннее для записи, чем альтернатива длины jQuery, но выполняется быстрее, поскольку это нативный метод JS.
И это лучше, чем альтернатива написания собственной функции jQuery
. Эта альтернатива медленнее, по причинам, указанным @snover. Но это также создало бы у других программистов впечатление, что функция exists()
является чем-то присущим jQuery. JavaScript
будут / должны быть поняты другими, редактирующими ваш код, без увеличения долга знаний.
Примечание: обратите внимание на отсутствие знака "#" перед element_id
(поскольку это обычный JS, а не jQuery
).
Причина, по которой все предыдущие ответы требуют параметра .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);
Вы можете проверить наличие или отсутствие элемента в 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
}
$(selector).length && //Do something
Вам не нужно проверять, больше ли оно 0
, например $(selector).length > 0
, $(selector).length
, достаточно и элегантного способа проверить наличие элементов. Я не думаю, что стоит написать функцию только для этого, если вы хотите сделать больше лишних вещей, да.
if($(selector).length){
// true if length is not 0
} else {
// false if length is 0
}
Похожие вопросы
Связанные вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Обратите внимание, что JavaScript — это НЕ Java. Включите все теги, относящиеся к вашему вопросу: например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [стройный] и т. д.