Nie można zaktualizować wartości atrybutu danych

91

Chociaż istnieje kilka przykładów na ten temat w Internecie, wydaje się, że nie działa poprawnie. Nie mogę zrozumieć problemu.

Mam ten prosty html

         <div id="foo" data-num="0"></ div>
         <a href="#" id="changeData">change data value</a>

Za każdym razem, gdy klikam łącze „zmień wartość danych”, chcę zaktualizować wartość danych data-num. Na przykład potrzebuję 1,2,3,4, ... (plus 1 za każdym razem, gdy klikam link)

co mam to

            var num = $('#foo').data("num");
            console.log(num);
            num = num+1;               
            console.log(num);
            $('#foo').attr('data-num', num);   

Wartość zmienia się za każdym razem od 0 do 1. Nie mogę zrobić tego przyrostowo. Jakieś sugestie, co robię źle?

dev
źródło
5
data- jest tylko atrybutem podczas ładowania strony. Dane są ładowane do domeny i tam przetwarzane za pomocą .data(). Atrybut nie jest aktualizowany i nie powinien być używany do przechowywania ani pobierania danych, a jedynie do początkowego ustawienia danych.
Nigel Angel
1
@NigelAngel Wrong. Celem atrybutu data jest zapewnienie środków, za pomocą których użytkownicy mogą przechowywać (i modyfikować) dowolne dane, które nie mają innego prawidłowego miejsca do przeniesienia. Przykładem tego może być waluta obca, gdy separatorem dziesiętnym jest przecinek. Aby wykonać obliczenia numeryczne z tym, musisz gdzieś zapisać odpowiednią wartość z rzeczywistym punktem dziesiętnym. Jeśli jest to cena łączna i wymaga aktualizacji na podstawie zmian, to ponownie ta wartość danych musiałaby ulec zmianie i dlatego musisz mieć możliwość jej aktualizacji. W tym celu użyjesz pliku .attr ()
jezzipin

Odpowiedzi:

64

ODPOWIEDŹ PONIŻSZA JEST DOBRA

Nie używasz poprawnie metody danych . Prawidłowy kod do aktualizacji danych to:

$('#foo').data('num', num); 

Twój przykład byłby taki:

var num = $('#foo').data("num") + 1;       
console.log(num)       
$('#foo').data('num', num); 
console.log(num)
Lucas Willems
źródło
97
To jest złe, to jest zła metoda aktualizacji atrybutu
adeneo
2
Tak, zgadzam się z Tobą @adeneo, ale on nie używa poprawnie metody danych. Po co używać tego rodzaju atrybutu, jeśli chcesz go zaktualizować metodą attr?
Lucas Willems,
@dev zredagowałem odpowiedź i dodałem cały kod, którego musisz użyć.
Lucas Willems,
7
To jest interesujące. Widzę, że wartość zmienia się w konsoli. Ale kiedy patrzę na html za pomocą Chrome, jest to 0 (początkowe). Myślę, że będzie dobrze, jeśli później będę mógł pobrać ostatnią wartość (na przykład 5)
dev
6
Jak powiedział @dev, próbowałem i zauważyłem, że to się zmieniło w jQuery, ale nie wpływa na HTML w Chrome i Safari. Więc zdecydowałem się użyć attr () zamiast data ().
QMaster
118

Użyj tego zamiast tego, jeśli chcesz zmienić atrybut numer-danych elementu węzła, a nie obiektu danych :

PRÓBNY

$('#changeData').click(function (e) { 
    e.preventDefault();
    var num = +$('#foo').attr("data-num");
    console.log(num);
    num = num + 1;
    console.log(num);
    $('#foo').attr('data-num', num);
});

PS: ale powinieneś używać obiektu data () praktycznie we wszystkich przypadkach, ale nie we wszystkich ...

A. Wolff
źródło
7
Dane są ładowane do domeny i tam przetwarzane za pomocą .data (). Atrybut nie jest aktualizowany i nie powinien być używany do przechowywania ani pobierania danych, a jedynie do początkowego ustawienia danych. Chociaż jest to jeden ze sposobów zmiany atrybutu ( .prop()jest preferowany), nie jest to właściwy sposób korzystania z danych.
Nigel Angel
4
.prop()uzyska dostęp lub zmieni wartość dowolnej właściwości lub atrybutu w DOM, ale nie HTML. .attr()uzyska dostęp i przepisze kod HTML, co spowoduje, że będzie wolniejszy niż .prop(). Nie powinieneś używać .attr()zamiast .data(), nie tylko dlatego, że jest wolniejszy, ale dlatego, że nie tak to powinno działać. jsfiddle.net/eXA76/2
Nigel Angel
1
Myślę, że ta odpowiedź powinna zostać usunięta, ponieważ daje złą radę dotyczącą używania danych ().
Nigel Angel
2
Tak, jQuery dokumentuje, jak powinno być używane! Dane api.jquery.com/data są przechowywane w zmiennej globalnej podczas ładowania dokumentu. Odwołanie się do niego za pomocą atrybutu NIE DZIAŁA, jeśli inny programista, wtyczka lub skrypt poprawnie zaktualizuje dane za pomocą .data(). Ignorując poprawną metodę i używając atrybutu, zmierzasz do świadomego powodowania problemów.
Nigel Angel
4
@NigelAngel Chociaż doceniam twoją opinię na ten temat, dane nie zawsze są najlepszą opcją. Co zrobić, jeśli musisz zaktualizować wartość atrybutu danych i wyświetlić go w domenie, a także faktycznie zmienić wartość bazową, która jest następnie używana przez CSS lub nawet JavaScript? Najlepszym podejściem jest zwykle użycie .data (), jeśli nie aktualizujesz wartości w jakikolwiek sposób z JavaScript, ale jeśli tak, zawsze używaj .attr () zarówno do ustawiania, jak i pobierania wartości.
jezzipin
30

Jeśli chcieliśmy pobrać lub zaktualizować te atrybuty przy użyciu istniejącego, natywnego języka JavaScript , możemy to zrobić za pomocą getAttributeisetAttribute metod , jak pokazano poniżej:

JavaScript

<script>
// 'Getting' data-attributes using getAttribute
var plant = document.getElementById('strawberry-plant');
var fruitCount = plant.getAttribute('data-fruit'); // fruitCount = '12'

// 'Setting' data-attributes using setAttribute
plant.setAttribute('data-fruit','7'); // Pesky birds
</script>

Poprzez jQuery

// Fetching data
var fruitCount = $(this).data('fruit');

// Above does not work in firefox. So use below to get attribute value.
var fruitCount = $(this).attr('data-fruit');

// Assigning data
$(this).data('fruit','7');

// But when you get the value again, it will return old value. 
// You have to set it as below to update value. Then you will get updated value.
$(this).attr('data-fruit','7'); 

Przeczytaj tę dokumentację dla vanilla js lub tę dokumentację dla jquery

Lalit Kumar Maurya
źródło
@Nigel Angel, czy przetestowałeś to w przeglądarce Firefox? $ (this) .data ('fruit') nie działa w przeglądarce Firefox.
Lalit Kumar Maurya
Bardzo dziękuję za ostatnią radę "Aby zaktualizować wartość, musisz ustawić to jak poniżej. Wtedy otrzymasz zaktualizowaną wartość" rly dziwne zachowanie w jquery ..
jgr
12

Dla siebie, używając Jquery lib 2.1.1, następujące rzeczy NIE działały tak, jak się spodziewałem:

Ustaw wartość atrybutu danych elementu:

$('.my-class').data('num', 'myValue');
console.log($('#myElem').data('num'));// as expected = 'myValue'

ALE sam element pozostaje bez atrybutu:

<div class="my-class"></div>

Potrzebowałem zaktualizować DOM, aby później móc wykonać $ ('. My-class [data-num = "myValue"]') // aktualna długość to 0

Więc musiałem to zrobić

$('.my-class').attr('data-num', 'myValue');

Aby zaktualizować DOM:

<div class="my-class" data-num="myValue"></div>

Czy atrybut istnieje, czy nie, $ .attr nadpisze.

Brian Ogden
źródło
1
Mam ten sam problem z jquery 2.1.1!
phlegx
8

Miałem podobny problem i ostatecznie musiałem ustawić oba

obj.attr('data-myvar','myval')

i

obj.data('myvar','myval')

A potem

obj.data('myvar') == obj.attr('data-myvar')

Mam nadzieję że to pomoże.

Krist0K
źródło
6

Zasadniczo istnieją dwa sposoby ustawiania / aktualizowania wartości atrybutu danych, w zależności od potrzeb. Różnica polega tylko na tym, gdzie zapisane dane,

Jeśli użyjesz .data(), zostanie zapisana w zmiennej lokalnej o nazwie data_user, a nie będzie widoczna po sprawdzeniu elementu, jeśli użyjesz.attr() będzie publicznie widoczna.

Znacznie jaśniejsze wyjaśnienie tego komentarza

Andang Rian Dimas
źródło
2

Ta odpowiedź jest dla tych, którzy chcą po prostu zmienić wartość atrybutu danych

Sugerowane nie zmieni poprawnie wartości atr danych Jquery, jak stwierdził @adeneo. Jednak z jakiegoś powodu nie widzę, aby on (ani inni) publikowali poprawną metodę dla tych, którzy chcą zaktualizować swój atrybut danych. Odpowiedź, którą opublikował @Lucas Willems, może być odpowiedzią na problem Briana Tompsetta - 汤 莱恩, ale nie jest to odpowiedź na pytanie, które może przyciągać tutaj innych użytkowników.

Szybka odpowiedź na oryginalne zapytanie ofertowe

-Aby zaktualizować atrybut data-attr

$('#ElementId').attr('data-attributeTitle',newAttributeValue);

Łatwe pomyłki * - na początku atrybutu, którego wartość chcesz zmienić, musi znajdować się „data-”.

MattOlivos
źródło
2

Miałem podobny problem, proponuję to rozwiązanie, chociaż nie jest obsługiwane w IE 10 i poniżej.

Dany

<div id='example' data-example-update='1'></div>

Standard Javascript definiuje właściwość o nazwie dataset, która aktualizuje przykładową aktualizację danych.

document.getElementById('example').dataset.exampleUpdate = 2;

Uwaga: użyj notacji wielbłąda, aby uzyskać dostęp do prawidłowego atrybutu danych.

Źródło: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

Giovanni Romio
źródło
1

Miałem ten sam problem z nieaktualizowaniem się znacznika danych html, gdy korzystałem z jquery, ale zmiana kodu, który wykonuje rzeczywistą pracę z jquery na javascript, działała.

Spróbuj użyć tego po kliknięciu przycisku: (Zauważ, że głównym kodem jest funkcja setAttribute () JavaScript .)

function increment(q) {

    //increment current num by adding with 1
    q = q+1;

    //change data attribute using JS setAttribute function
    div.setAttribute('data-num',q);

    //refresh data-num value (get data-num value again using JS getAttribute function)
    num = parseInt(div.getAttribute('data-num'));

    //show values
    console.log("(After Increment) Current Num: "+num);

}

//get variables, set as global vars
var div = document.getElementById('foo');
var num = parseInt(div.getAttribute('data-num'));

//increment values using click
$("#changeData").on('click',function(){

    //pass current data-num as parameter
    increment(num);

});
Blizna
źródło