javascript элемента Есть ли функция «существует» для jQuery?




проверка на существование переменной js (24)

Как я могу проверить существование элемента в jQuery?

Текущий код, который у меня есть, следующий:

if ($(selector).length > 0) {
    // Do something
}

Есть ли более элегантный способ приблизиться к этому? Возможно, плагин или функция?


У меня был случай, когда я хотел посмотреть, существует ли объект внутри другого, поэтому я добавил что-то к первому ответу, чтобы проверить селектор внутри селектора.

// 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;
};

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

// if element exists
if($('selector').length){ /* do something */ }
// if element does not exist
if(!$('selector').length){ /* do something */ }

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

jQuery.fn.extend({
    exists: function() { return this.length }
});

if($(selector).exists()){/*do something*/}

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

$.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

Как насчет:

function exists(selector) {
    return $(selector).length;
}

if (exists(selector)) {
    // do something
}

Это очень минимально и экономит ваше время, когда вы включаете селектор с помощью $() .


Нет необходимости в jQuery

if(document.querySelector('.a-class')) {
  // do something
}

Самый быстрый и наиболее семантически понятный способ проверить существование на самом деле, используя простой JavaScript:

if (document.getElementById('element_id')) {
    // Do something
}

Запись немного длиннее, чем альтернатива jQuery length, но выполняется быстрее, поскольку это собственный метод JS.

И это лучше, чем альтернатива написанию вашей собственной функции jQuery. Эта альтернатива медленнее, по причинам, указанным @snover. Но это также дало бы другим программистам впечатление, что функция exists () - это что-то, что присуще jQuery. JavaScript будет / должен быть понят другим, редактирующим ваш код, без увеличения объема задолженности.

NB: Обратите внимание на отсутствие «#» перед элементом element_id (поскольку это простой JS, а не jQuery).


$(selector).length && //Do something

Я вижу, что большинство ответов здесь не точны, как и должно быть, они проверяют длину элемента, во многих случаях это может быть хорошо, но не на 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: '', url: 'http://www..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 например 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);

jsFiddle

Вы можете указать один или два обратных вызова. Первый будет срабатывать, если элемент существует, второй будет срабатывать, если элемент не существует. Однако, если вы решите передать только одну функцию, она будет срабатывать только при наличии элемента. Таким образом, цепь будет умирать, если выбранный элемент не существует. Конечно, если он действительно существует, первая функция будет срабатывать, и цепочка будет продолжена.

Имейте в виду, что использование варианта обратного вызова помогает поддерживать цепочки - элемент возвращается, и вы можете продолжать команды цепочки, как с любым другим методом 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 ($(selector)[0]) { ... }

Это работает, потому что каждый объект jQuery также маскируется как массив, поэтому мы можем использовать оператор разыменования массива для получения первого элемента из массива . Он возвращает undefined если в указанном индексе нет элемента.


Вдохновленный ответом hiway, я придумал следующее:

$.fn.exists = function() {
    return $.contains( document.documentElement, this[0] );
}

$.contains() принимает два элемента DOM и проверяет, содержит ли первый первый.

Использование document.documentElement в качестве первого аргумента выполняет семантику метода exist, когда мы хотим применить его только для проверки существования элемента в текущем документе.

Ниже я собрал фрагмент, который сравнивает jQuery.exists() с jQuery.exists() $(sel)[0] и $(sel).length которые возвращают truthy значения для $(4) а $(4).exists() возвращает 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>


В JavaScript все «правдивое» или «ложное», а для чисел 0 (и NaN) означает « false , все остальное true . Поэтому вы можете написать:

if ($(selector).length)

Вам не нужна эта часть >0 .


На самом деле нет необходимости в jQuery. С простым JavaScript проще и семантически правильно проверять:

if(document.getElementById("myElement")) {
    //Do something...
}

Если по какой-либо причине вы не хотите вводить идентификатор элемента, вы все равно можете использовать любой другой метод JavaScript, предназначенный для доступа к 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

Попробовать тестирование для элемента DOM

if (!!$(selector)[0]) // do stuff

$("selector" ) дает объект с данными length . Если в селекторе есть элементы, которые вы определяете, вы получите их из объекта. Поэтому, если вы проверите длину, которую вы уже можете найти, существует ли какой-либо элемент. В javascript 0 == false также null == false . Если вы не получите 0 ваши коды будут работать.

if($("selector").length){
   //code in the case
} 

Ты можешь использовать:

if ($(selector).is('*')) {
  // Do something
}

Может быть, немного более элегантно.


$.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/



Мне просто нравится использовать простой ванильный javascript для этого.

function isExists(selector){
  return document.querySelectorAll(selector).length>0;
}

это очень похоже на все ответы, но почему бы не использовать ! дважды, чтобы вы могли получить логическое значение:

jQuery.fn.exists = function(){return !!this.length};

if ($(selector).exists()) {
    // the element exists, now what?...
}

Если вы использовали

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 */ }




jquery