Подтвердить что ты не робот

JQuery метод "получить или создать элемент"

У меня есть две функции, которые генерируют элементы DOM. Они оба пытаются создать один и тот же элемент контейнера. (Я бы предпочел не применять конкретный порядок выполнения для этих функций или плотно связать их с побочным эффектом создания этого элемента). Я пытался найти метод, который бы получил элемент, если он существует, или создать один его экземпляр, если это не так, и вернуть объект jQuery, содержащий этот элемент, или все согласованные элементы, если они уже существуют.

Я не нашел, что это существует при поиске в документации по jQuery, но я подумал, что попрошу здесь посмотреть, не сталкивался ли кто-либо с аналогичной проблемой и имеет предложения.

4b9b3361

Ответ 1

Вы можете использовать этот плохо написанный код:

var $element = $('#element').length ? $('#element') : $('<div id="element"></div>').appendTo('#containerToPutIt');

Или сделайте это немного чище:

var $element = $('#element');
if(!$element.length)
    $element = $('<div id="element"></div>').appendTo('#containerToPutIt');

Ответ 2

В jQuery действительно нет места, где у вас будет достаточно информации для создания элемента, если он не существует. Например, если вы выполняете $('#something'), и хотите, чтобы jQuery обеспечивал его существование, какой элемент вы ожидаете создать jQuery? Где вы хотите, чтобы он находился в DOM?

Это то, что вам нужно делать со вспомогательным методом:

function getContainer() {
    var container = $('.yourContainer');

    if (!container.length) {
        container = $('<div class="container" />').appendTo('#something');
    }

    return container;
}

И затем используйте его следующим образом:

getContainer().html('Foo Bar Baz');
getContainer().children().each(..);

Ответ 3

Вы можете просто выбрать элемент DOM в jQuery, а затем проверить его длину:

if ($('div.someclass').length > 0) {...}

НЕ проверяйте существование объекта jQuery, так как он всегда будет возвращать true, даже если в нем нет элементов DOM. Вы всегда должны проверять свою длину.

Если тест length завершился с ошибкой, вы можете создать элемент DOM, где бы вы ни захотели, используя какой-либо метод DOM insert.

Ответ 4

Хм... интересный вопрос... Вы можете попробовать что-то вроде.

function checkExists(selector) {
    var exists = $(selector).length;
    if(exists > 0) {
        return $(selector);
    } else {
        return createElement();
    }
}

Где createElement() будет вашей функцией, которая делает элемент DOM, который вы ищете. (Он вернет вновь созданный элемент). Затем вы можете вызвать его с помощью селектора jquery, например checkExists('.myClass');, например

Ответ 5

Положим удобство в методе удобства (в дополнение к сохранению разделения проблем! Здесь функция jQuery под названием upsert, которая либо найдет существующий элемент, либо создаст новый элемент, если не будет существуют.

Так просто включите этот jQuery где угодно:

$.fn.upsert = function(selector, htmlString) {
  // upsert - find or create new element
  // find based on css selector     https://api.jquery.com/category/selectors/
  // create based on jQuery()       http://api.jquery.com/jquery/#jQuery2
  var $el = $(this).find(".message");
  if ($el.length == 0) {
    // didn't exist, create and add to caller
    $el = $("<span class='message'></span>");
    $(this).append($el);
  }

  return $el;
}; 

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

$("input[name='choice']").click(function(){
  var $el = $(this).closest("form").upsert(".message", "<span class='message'></span>");
  // guaranteed to have element - update if we want
  $el.html("You've chosen "+this.value)
})

В идеале было бы неплохо просто перейти в селектор и создать jQuery элемент, который будет автоматически соответствовать этому селектору, но не кажется, что есть легкий автомобиль для создание элемента, основанного на синтаксисе CSS Selector (на основе Вопрос 1 и Вопрос 2).

Некоторые дополнительные улучшения могут обеспечить более точный контроль для вставки DOM вместо того, чтобы всегда использовать .append().

Демо в jsFiddle | Демо в фрагментах стека:

$.fn.upsert = function(selector, htmlString) {
  // upsert - find or create new element
  // find based on css selector   	https://api.jquery.com/category/selectors/
  // create based on jQuery()       http://api.jquery.com/jquery/#jQuery2
  var $el = $(this).find(".message");
  if ($el.length == 0) {
    // didn't exist, create and add to caller
    $el = $("<span class='message'></span>");
    $(this).append($el);
  }

  return $el;
}; 

$("input[name='choice']").click(function(){
  var $el = $(this).closest("form").upsert(".message", "<span class='message'></span>");
  // guaranteed to have element - update if we want
  $el.html("You've chosen "+this.value)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form action="">
  <div>
    <input type="radio" id="ca" name="choice" value="A" /><label for='ca'>A</label>
    <input type="radio" id="cb" name="choice" value="B" /><label for='cb'>B</label>
    <input type="radio" id="cc" name="choice" value="C" /><label for='cc'>C</label>
  </div>
</form>