Como posso verificar a existência de um elemento no jQuery?
O código atual que eu tenho é este:
if ($(selector).length > 0) {
// Do something
}
Existe uma maneira mais elegante de abordar isso? Talvez um plugin ou uma função?
Como posso verificar a existência de um elemento no jQuery?
O código atual que eu tenho é este:
if ($(selector).length > 0) {
// Do something
}
Existe uma maneira mais elegante de abordar isso? Talvez um plugin ou uma função?
Respostas:
No JavaScript, tudo é 'verdade' ou 'falsidade' e, para números 0
(e NaN) false
, significa tudo true
. Então você pode escrever:
if ($(selector).length)
Você não precisa dessa >0
parte.
NaN != false
.
[] + []
= ""
... ahh javascript I amor
[].toString() === [].join(',') === ""
e "" === ""
.
typeof NaN == 'number'
Sim!
jQuery.fn.exists = function(){ return this.length > 0; }
if ($(selector).exists()) {
// Do something
}
Em resposta a: Podcast Herding Code com Jeff Atwood
$.fn.exists
exemplo é substituir uma pesquisa de propriedade (barata!) Por duas chamadas de função, que são muito mais caras - e uma dessas chamadas de função recria um objeto jQuery que você já possui, o que é bobo.
.exists
lê claramente, enquanto .length
lê como algo semanticamente diferente, mesmo que a semântica coincida com um resultado idêntico.
Se você usou
jQuery.fn.exists = function(){return ($(this).length > 0);}
if ($(selector).exists()) { }
você implicaria que o encadeamento era possível quando não é.
Isso seria melhor:
jQuery.exists = function(selector) {return ($(selector).length > 0);}
if ($.exists(selector)) { }
Como alternativa, nas Perguntas frequentes :
if ( $('#myDiv').length ) { /* Do something */ }
Você também pode usar o seguinte. Se não houver valores na matriz de objetos jQuery, obter o primeiro item na matriz retornará indefinido.
if ( $('#myDiv')[0] ) { /* Do something */ }
$(".missing").css("color", "red")
já faz a coisa certa… (ou seja, nada) #
$.fn
métodos jQuery que retornam algo diferente de um novo objeto jQuery e, portanto, não são encadeados.
Você pode usar isto:
// if element exists
if($('selector').length){ /* do something */ }
// if element does not exist
if(!$('selector').length){ /* do something */ }
A maneira mais rápida e semanticamente auto-explicativa de verificar a existência é na verdade usando plain JavaScript
:
if (document.getElementById('element_id')) {
// Do something
}
É um pouco mais longo para escrever do que a alternativa de comprimento do jQuery, mas executa mais rapidamente, pois é um método JS nativo.
E é melhor do que a alternativa de escrever sua própria jQuery
função. Essa alternativa é mais lenta, pelas razões declaradas pela @snover. Mas também daria a outros programadores a impressão de que a exists()
função é algo inerente ao jQuery. JavaScript
deve / deve ser entendido por outras pessoas que estão editando seu código, sem aumentar a dívida de conhecimento.
Nota: Observe a falta de um '#' antes do element_id
(já que isso é JS simples, não jQuery
).
$('#foo a.special')
. E pode retornar mais de um elemento. getElementById
não pode começar a abordar isso.
if(document.querySelector("#foo a.special"))
funcionaria. Não é necessário jQuery.
Você pode salvar alguns bytes escrevendo:
if ($(selector)[0]) { ... }
Isso funciona porque cada objeto jQuery também se disfarça como uma matriz, para que possamos usar o operador de desreferenciação da matriz para obter o primeiro item da matriz . Retorna undefined
se não houver nenhum item no índice especificado.
jQuery.first()
ou jQuery.eq(0)
ambos retornam objetos, os objetos são verdadeiros, mesmo que sejam vazios. Este exemplo deve ilustrar por que essas funções não podem ser usadas como estão:if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists")
.eq(0)
retorna apenas outro objeto jQuery truncado para o comprimento 1 ou 0. .first()
é apenas um método conveniente para .eq(0)
. Mas .get(0)
retorna o primeiro elemento DOM ou undefined
e é o mesmo que [0]
. O primeiro elemento DOM em um objeto jQuery é armazenado na propriedade regulares objeto com o nome '0'
. Esse é um acesso simples à propriedade. O único tipo de conversão deriva da conversão implícita do número 0
na string '0'
. Portanto, se a conversão de tipos for um problema, você poderá usar $.find(selector)['0']
.
Você pode usar:
if ($(selector).is('*')) {
// Do something
}
Um pouco mais elegante, talvez.
666
provavelmente têm muitas outras razões pelas quais o código está quebrado. Embora seja um seletor inválido, $ (666) .length é um javascript válido : ele é avaliado como verdadeiro e, portanto, deve atender à condição.
$.find(666).length
funciona.
Este plugin pode ser usado em uma if
declaração comoif ($(ele).exist()) { /* DO WORK */ }
ou usando um retorno de chamada.
;;(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);
Você pode especificar um ou dois retornos de chamada. O primeiro disparará se o elemento existir, o segundo disparará se o elemento não existir. No entanto, se você optar por passar apenas uma função, ela será acionada apenas quando o elemento existir. Assim, a cadeia morrerá se o elemento selecionado não existir. Obviamente, se existir, a primeira função será acionada e a cadeia continuará.
Lembre-se de que o uso da variante de retorno de chamada ajuda a manter a capacidade de cadeia encadeamento - o elemento é retornado e você pode continuar encadeando comandos como em qualquer outro método 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
retorno de chamada não deveria realmente passar o objeto como argumento?
Vejo que a maioria das respostas aqui não são precisas como deveriam, verificam o comprimento do elemento, em muitos casos pode ser bom , mas não 100% , imagine se o número passar para a função, então protótipo de uma função que verifica todas condições e retorne a resposta como deve ser:
$.fn.exists = $.fn.exists || function() {
return !!(this.length && (this[0] instanceof HTMLDocument || this[0] instanceof HTMLElement));
}
Isso verificará o comprimento e o tipo. Agora você pode verificar desta maneira:
$(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
Não há realmente necessidade de jQuery. Com JavaScript simples, é mais fácil e semanticamente correto verificar:
if(document.getElementById("myElement")) {
//Do something...
}
Se, por algum motivo, você não quiser colocar um ID no elemento, ainda poderá usar qualquer outro método JavaScript projetado para acessar o DOM.
jQuery é muito legal, mas não deixe o JavaScript puro cair no esquecimento ...
:has()
?
O motivo de todas as respostas anteriores exigirem o .length
parâmetro é que elas estão usando o $()
seletor jquery, que tem querySelectorAll por trás das cortinas (ou estão usando diretamente). Esse método é bastante lento porque precisa analisar a árvore DOM inteira, procurando todas as correspondências nesse seletor e preenchendo uma matriz com elas.
O parâmetro ['length'] não é necessário nem é útil, e o código será muito mais rápido se você usar diretamente document.querySelector(selector)
, porque retorna o primeiro elemento correspondente ou null se não for encontrado.
function elementIfExists(selector){ //named this way on purpose, see below
return document.querySelector(selector);
}
/* usage: */
var myelement = elementIfExists("#myid") || myfallbackelement;
No entanto, esse método nos deixa com o objeto real sendo retornado; o que é bom se não for salvo como variável e usado repetidamente (mantendo assim a referência se esquecermos).
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 */
Em alguns casos, isso pode ser desejado. Pode ser usado em um loop for como este:
/* locally scoped myel gets garbage collected even with the break; */
for (var myel; myel = elementIfExist(sel); myel.getParentNode.removeChild(myel))
if (myel == myblacklistedel) break;
Se você realmente não precisa do elemento e deseja obter / armazenar apenas um verdadeiro / falso, apenas não o dobro !! Funciona para sapatos desamarrados, então por que dar um nó aqui?
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);
É o $.contains()
que você quer?
jQuery.contains( container, contained )
O
$.contains()
método retornará true se o elemento DOM fornecido pelo segundo argumento for um descendente do elemento DOM fornecido pelo primeiro argumento, seja um filho direto ou aninhado mais profundamente. Caso contrário, ele retornará false. Somente nós de elemento são suportados; se o segundo argumento for um nó de texto ou comentário,$.contains()
retornará false.Nota : O primeiro argumento deve ser um elemento DOM, não um objeto jQuery ou objeto JavaScript simples.
Eu achei if ($(selector).length) {}
insuficiente. Ele interromperá silenciosamente seu aplicativo quando selector
houver um objeto vazio {}
.
var $target = $({});
console.log($target, $target.length);
// Console output:
// -------------------------------------
// [▼ Object ] 1
// ► __proto__: Object
Minha única sugestão é realizar uma verificação adicional para {}
.
if ($.isEmptyObject(selector) || !$(selector).length) {
throw new Error('Unable to work with the given selector.');
}
Ainda estou procurando uma solução melhor, já que esta é um pouco pesada.
Edit: AVISO! Isso não funciona no IE quando selector
é uma string.
$.isEmptyObject('hello') // FALSE in Chrome and TRUE in IE
$()
com um objeto vazio como argumento?
{}
para $()
?
Você pode verificar se o elemento está presente ou não está usando o comprimento no script java. Se o comprimento for maior que zero, o elemento estará presente. Se o comprimento for zero, o elemento não estará presente.
// 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
}
A verificação da existência de um elemento está documentada ordenadamente no próprio site oficial do jQuery!
Use a propriedade .length da coleção jQuery retornada pelo seu seletor:
if ($("#myDiv").length) { $("#myDiv").show(); }
Observe que nem sempre é necessário testar se um elemento existe. O código a seguir mostrará o elemento, se ele existir, e não fará nada (sem erros), se não existir:
$("#myDiv").show();
isso é muito semelhante a todas as respostas, mas por que não usar o !
operador duas vezes para obter um booleano:
jQuery.fn.exists = function(){return !!this.length};
if ($(selector).exists()) {
// the element exists, now what?...
}
$(selector).length && //Do something
if
onde um if
melhoraria a legibilidade ao custo de 2 bytes.
Tente testar o DOM
elemento
if (!!$(selector)[0]) // do stuff
Inspirado pela resposta da hiway, vim com o seguinte:
$.fn.exists = function() {
return $.contains( document.documentElement, this[0] );
}
O jQuery.contains pega dois elementos DOM e verifica se o primeiro contém o segundo.
Usar document.documentElement
como primeiro argumento preenche a semântica do exists
método quando queremos aplicá-lo apenas para verificar a existência de um elemento no documento atual.
Abaixo, reuni um trecho que se compara jQuery.exists()
às abordagens $(sel)[0]
e e $(sel).length
que retornam truthy
valores para $(4)
enquanto $(4).exists()
retornam false
. No contexto de verificação da existência de um elemento no DOM, este parece ser o resultado desejado .
Não há necessidade de jQuery (solução básica)
if(document.querySelector('.a-class')) {
// do something
}
Opção com muito mais desempenho abaixo (observe a falta de um ponto antes da aula).
if(document.getElementsByClassName('a-class')[0]) {
// do something
}
O querySelector usa um mecanismo de correspondência adequado, como $ () (sizzle) no jQuery, e usa mais poder de computação, mas em 99% dos casos funciona bem. A segunda opção é mais explícita e informa ao código exatamente o que fazer. É muito mais rápido, de acordo com jsperf https://jsperf.com/getelementsbyclassname-vs-queryselectorall/25
Eu só gosto de usar javascript simples de baunilha para fazer isso.
function isExists(selector){
return document.querySelectorAll(selector).length>0;
}
Eu me deparei com essa pergunta e gostaria de compartilhar um trecho de código que atualmente uso:
$.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;
}
E agora eu posso escrever código assim -
$("#elem").exists(function(){
alert ("it exists");
}).otherwise(function(){
alert ("it doesn't exist");
});
Pode parecer muito código, mas quando escrito em CoffeeScript é bem pequeno:
$.fn.exists = (callback) ->
exists = @length
callback.call() if exists
new class
otherwise: (fallback) ->
fallback.call() if not exists
Eu tinha um caso em que queria ver se um objeto existe dentro de outro, então adicionei algo à primeira resposta para verificar se havia um seletor dentro dele.
// 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;
};
E se:
function exists(selector) {
return $(selector).length;
}
if (exists(selector)) {
// do something
}
É muito mínimo e economiza a necessidade de incluir o seletor $()
sempre.
if($("#thing").exists(){}
lê. Além disso, não é o caminho do jQuery.
Eu estou usando isso:
$.fn.ifExists = function(fn) {
if (this.length) {
$(fn(this));
}
};
$("#element").ifExists(
function($this){
$this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});
}
);
Execute a cadeia apenas se existir um elemento jQuery - http://jsfiddle.net/andres_314/vbNM3/2/
Aqui está o meu exist
método favorito no jQuery
$.fn.exist = function(callback) {
return $(this).each(function () {
var target = $(this);
if (this.length > 0 && typeof callback === 'function') {
callback.call(target);
}
});
};
e outra versão que suporta retorno de chamada quando o seletor não existe
$.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);
}
}
});
};
Exemplo:
$('#foo .bar').exist(
function () {
// Stuff when '#foo .bar' exists
},
function () {
// Stuff when '#foo .bar' does not exist
}
);
$("selector"
) retorna um objeto que possui a length
propriedade Se o seletor encontrar algum elemento, ele será incluído no objeto. Portanto, se você verificar seu comprimento, poderá ver se existem elementos. Em JavaScript 0 == false
, se você não obtiver 0
seu código, ele será executado.
if($("selector").length){
//code in the case
}
Aqui está o exemplo completo de diferentes situações e a maneira de verificar se o elemento existe usando direct if if no seletor jQuery pode ou não funcionar, pois retorna matriz ou elementos.
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
SOLUÇÃO FINAL
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
Você não precisa verificar se é maior do que o 0
desejado $(selector).length > 0
, $(selector).length
é o suficiente e uma maneira elegante de verificar a existência de elementos. Eu não acho que vale a pena escrever uma função apenas para isso, se você quiser fazer mais coisas extras, sim.
if($(selector).length){
// true if length is not 0
} else {
// false if length is 0
}