Есть ли способ, которым я могу проверить, существует ли атрибут данных?

190

Есть ли способ, которым я могу запустить следующее:

var data = $("#dataTable").data('timer');
var diffs = [];

for(var i = 0; i + 1 < data.length; i++) {
    diffs[i] = data[i + 1] - data[i];
}

alert(diffs.join(', '));

Только если в элементе есть атрибут data-timer с идентификатором #dataTable?

Angela
источник
Следует помнить, что иногда в data-атрибуте ничего не хранится, но в jQuery хранятся данные и наоборот.
Алекс W

Ответы:

296
if ($("#dataTable").data('timer')) {
  ...
}

Обратите внимание , это только возвращается , trueесли атрибут данных не является пустой строкой или «falsey» значение , например , 0или false.

Если вы хотите проверить наличие атрибута данных, даже если он пуст, сделайте следующее:

if (typeof $("#dataTable").data('timer') !== 'undefined') {
  ...
}
niiru
источник
35
Другой вариант для вас: if ($("#dataTable[data-timer]").length) { ... }.
VisioN
101
Быть осторожен! Это оценивается как true, только если data-timer имеет значение. Если он присутствует, но пустой, он вернет false.
Kong
15
Конг прав, если есть пустое значение, ваш код не работает. Используйте это вместо этого: if (typeof $ ("# dataTable"). Attr ('data-timer')! == "undefined") {...}
PierrickM
22
Еще одна версия , которая дает реальную булево для вашего условно: if ( $("#dataTable").is("[data-timer]") ) { ... }. Это также более полезно, если у вас уже есть ссылка на таблицу в другом объекте jQuery.
Noyo
10
Он вернет false, если значение существует и равно 0. Это странно.
Герман
112
if (typeof $("#dataTable").data('timer') !== 'undefined')
{
    // your code here
}
Пол Флеминг
источник
@VisioN отказоустойчивого сочетания вашего и PierrickM комментария пользователя на этом ответ: if (typeof $('#dataTable').data('timer') !== 'undefined') ....
WynandB
3
@Wynand. Обновлено, чтобы отразить ваши комментарии и комментарии VisioN.
Пол Флеминг
1
@flem Вы также должны добавить в typeofчек
Брендан Буллен
1
@flem, @VisioN, ваши подходы терпят неудачу в случае, когда нет атрибута данных, но данные все еще были установлены с помощью метода .data (), например $('#dataTable').data('timer', Date.now()). Похоже, что ОП хочет проверить наличие фактического атрибута данных. Решение @ niiru (или предложение, которое вы предлагаете в комментарии к этому решению) в этом случае лучше.
Noyo
1
@VisioN Для меня это проверка на undefinedпостоянной основе. Мы знаем , почему typeofиспользуются для проверки undefinedв некоторых случаях, но я нахожу это заблуждение , чтобы увидеть , что проверяется с typeof в одном месте и не в другом. Кроме того, это не то же самое, что использование typeofдобавляет намного более сложный код. Это может быть более явным, возможно, в большинстве случаев избыточным, но вряд ли слишком сложным. Хотя я понимаю вашу точку зрения, но я бы сказал, что не использовать это было бы упрощением. ;]
WynandB
38

В интересах предоставления ответа, отличного от приведенного выше; Вы можете проверить это Object.hasOwnProperty(...)следующим образом:

 if( $("#dataTable").data().hasOwnProperty("timer") ){
     // the data-time property exists, now do you business! .....
 }

альтернативно, если у вас есть несколько элементов данных, которые вы хотите перебрать, вы можете варьировать .data()объект и перебирать его следующим образом:

 var objData = $("#dataTable").data();
 for ( data in objData ){
      if( data == 'timer' ){
            //...do the do
      }
 }

Не сказать, что это решение лучше, чем любое другое здесь, но, по крайней мере, это другой подход ...

sadmicrowave
источник
9
Это интересно, но следует отметить, что если у вас есть атрибут, data-foo-barтогда ваш чек должен быть .data().hasOwnProperty("fooBar"), а не.data().hasOwnProperty("foo-bar")
dgmstuart
Интересно в этом случае с валидатором JavaScript. Тип возвращаемого значения не определен, но это сработало!
Ричард Хоусэм
12

Или в сочетании с ванильным JS

if ($("#dataTable").get(0).hasAttribute("data-timer")) {
  ...
}
Максимум
источник
Мне нравится этот. Тем не менее, вы создаете данные, используя data()вместо этого jQuery attr(), он не найдет атрибут :(
Сэм
10

Вы можете использовать метод hasData в jQuery.

http://api.jquery.com/jQuery.hasData/

Основное преимущество jQuery.hasData (element) состоит в том, что он не создает и не связывает объект данных с элементом, если в данный момент его не существует. Напротив, jQuery.data (element) всегда возвращает объект данных вызывающей стороне, создавая его, если ранее никакого объекта данных не существовало.

Это будет только проверять наличие каких-либо объектов данных (или событий) в вашем элементе, оно не сможет подтвердить, есть ли у него объект «таймер».

BZink
источник
10

Если вы хотите различать пустые значения и пропущенные значения, вы можете использовать jQuery для проверки следующим образом.

<div id="element" data-foo="bar" data-empty=""></div>

<script>
"foo" in $('#element').data(); // true
"empty" in $('#element').data(); // true
"other" in $('#element').data(); // false
</script>

Исходя из исходного вопроса, вы бы это сделали.

if("timer" in $("#dataTable").data()) {
  // code
}
Райан
источник
7

Вы можете создать чрезвычайно простой jQuery-плагин для запроса элемента:

$.fn.hasData = function(key) {
  return (typeof $(this).data(key) != 'undefined');
};

Тогда вы можете просто использовать $("#dataTable").hasData('timer')

Gotchas:

  • Вернет falseтолько если значение не существует (есть undefined); если он установлен в false/ nullон hasData()все равно вернется true.
  • Он отличается от встроенного, $.hasData()который только проверяет, установлены ли какие-либо данные для элемента.
Alex
источник
3

Я обнаружил, что это работает лучше с динамически установленными элементами данных:

if ($("#myelement").data('myfield')) {
  ...
}
JerSchneid
источник
3

Все ответы здесь используют библиотеку jQuery.

Но ванильный JavaScript очень прост.

Если вы хотите запустить сценарий только в том случае, если элемент с параметром idof #dataTable также имеет data-timerатрибут, выполните следующие шаги:

// Locate the element

const myElement = document.getElementById('dataTable');

// Run conditional code

if (myElement.dataset.hasOwnProperty('timer')) {

  [... CODE HERE...]

}
Rounin
источник
2

По моему мнению, это самое простое решение - выбрать все элементы, которые имеют определенный атрибут данных:

var data = $("#dataTable[data-timer]");
var diffs = [];

for(var i = 0; i + 1 < data.length; i++) {
    diffs[i] = data[i + 1] - data[i];
}

alert(diffs.join(', '));

Вот скриншот того, как это работает.

консольный журнал селектора jquery

Анимеш Сингх
источник
1

Неправильный ответ - см. РЕДАКТИРОВАТЬ в конце

Позвольте мне опираться на ответ Алекса.

Чтобы предотвратить создание объекта данных, если он не существует, я бы лучше сделал:

$.fn.hasData = function(key) {
    var $this = $(this);
    return $.hasData($this) && typeof $this.data(key) !== 'undefined';
};

Затем, где $thisне создан объект данных, $.hasDataвозвращается, falseи он не будет выполняться $this.data(key).

РЕДАКТИРОВАТЬ: функция $.hasData(element)работает, только если данные были установлены с использованием $.data(element, key, value), а не element.data(key, value). Из-за этого мой ответ не верен.

nestorrente
источник
1

Мне нужно было простое логическое значение для работы с. Поскольку он не определен как не присутствует и не имеет значения false, я использую его !!для преобразования в логическое значение:

var hasTimer = !!$("#dataTable").data('timer');
if( hasTimer ){ /* ....... */ }

Альтернативное решение будет использовать фильтр:

if( $("#dataTable").filter('[data-timer]').length!==0) { /* ....... */ }
Мартейн
источник
0
var data = $("#dataTable").data('timer');
var diffs = [];

if( data.length > 0 ) {
for(var i = 0; i + 1 < data.length; i++) {
    diffs[i] = data[i + 1] - data[i];
}

alert(diffs.join(', '));
}
Luceos
источник
Если значение .data('timer')не определено, вы получите ошибку TypeError: $ (...). Data (...) при проверке не определяетсяdata.length . Скорее всего, это основа вопроса ОП, то есть обеспечение того, чтобы можно было безопасно проверить в data.lengthдругом месте. Кроме того, вы не обязательно сможете точно сказать, dataявляется ли строка, массив или объект, который последний может содержать или не содержать lengthв качестве определенного свойства.
WynandB
Да, мой ответ нуждается в пересмотре. Написано в 2012 году. Но переписывать его было бы бесполезно, так как ответ уже дан.
Luceos
0

Вы можете проверить выбор атрибута css с помощью

if ($('#dataTable').is('[data-timer]')) {
   // data-timer attribute exists
}
кульминация
источник
3
Значения данных не всегда сохраняются как атрибуты DOM. Когда вы изменяете значения данных с помощью jQuery, используя $ .data, он устанавливает его как свойство элемента.
qwerty
0

И что насчет:

if ($('#dataTable[data-timer]').length > 0) {
    // logic here
}
dani24
источник