Lekcja 4: Manipulacja DOM - Treść i Atrybuty
Po wybraniu elementów za pomocą selektorów, jQuery oferuje proste i potężne metody do odczytywania i modyfikowania ich treści oraz atrybutów. Pozwala to dynamicznie zmieniać wygląd i zawartość strony internetowej w odpowiedzi na działania użytkownika lub inne zdarzenia.
Odczytywanie i Ustawianie Treści HTML i Tekstowej
-
.html()
: Pobiera lub ustawia zawartość HTML pierwszego elementu w zbiorze. Bez argumentów zwraca aktualny HTML wewnętrzny. Z argumentem (stringiem HTML) zastępuje wewnętrzny HTML każdego elementu w zbiorze.// Odczytanie HTML let zawartoscDiv = $("#mojDiv").html(); console.log("Zawartość HTML diva:", zawartoscDiv); // Ustawienie HTML (nadpisuje istniejącą zawartość) $("#mojDiv").html("<h2>Nowy nagłówek</h2><p>Nowy paragraf.</p>"); // Ustawienie HTML dla wielu elementów $(".sekcja").html("<p>Treść zastępcza</p>");
Uwaga: Używanie
.html()
z danymi pochodzącymi od użytkownika bez odpowiedniego oczyszczenia może prowadzić do ataków XSS (Cross-Site Scripting). -
.text()
: Pobiera lub ustawia zawartość tekstową wszystkich elementów w zbiorze (połączoną) lub pierwszego elementu (przy ustawianiu). Bez argumentów zwraca połączony tekst wszystkich elementów. Z argumentem (stringiem tekstowym) zastępuje zawartość tekstową każdego elementu w zbiorze. Wszelkie znaczniki HTML w argumencie zostaną potraktowane jako zwykły tekst.// Odczytanie tekstu let tekstParagrafow = $("p").text(); // Łączy tekst ze wszystkich paragrafów console.log("Tekst paragrafów:", tekstParagrafow); // Ustawienie tekstu (bezpieczniejsze niż .html() dla danych od użytkownika) $("#naglowek").text("Nowy, bezpieczny tekst nagłówka"); // Ustawienie tekstu dla wielu elementów $("span.info").text("Aktualizacja!");
Praca z Wartościami Formularzy
-
.val()
: Pobiera lub ustawia wartość atrybutuvalue
elementów formularza (<input>
,<textarea>
,<select>
). Bez argumentów zwraca wartość pierwszego elementu w zbiorze. Z argumentem ustawia wartośćvalue
dla każdego elementu w zbiorze.// Odczytanie wartości pola input let imie = $("#input-imie").val(); console.log("Wprowadzone imię:", imie); // Ustawienie wartości pola input $("#input-email").val("przyklad@domena.com"); // Ustawienie wartości pola textarea $("#opis").val("Domyślny opis produktu."); // Wybranie opcji w select $("#kraj").val("PL"); // Zakładając, że istnieje <option value="PL"> // Odczytanie wartości zaznaczonego radio buttona w grupie let wybranaOpcja = $("input[name=\'opcja\']:checked").val(); // Odczytanie wartości wielu zaznaczonych opcji w select multiple let wybraneOwoce = $("#owoce").val(); // Zwraca tablicę wartości
Odczytywanie i Ustawianie Atrybutów i Właściwości
Istnieje subtelna różnica między atrybutami (attributes) a właściwościami (properties) elementów DOM:
- Atrybuty są zdefiniowane w kodzie HTML (np.
id="mojDiv"
,class="klasa"
,href="link"
,value="wartosc"
). Metoda.attr()
służy do pracy z nimi. - Właściwości to wartości w obiekcie DOM w pamięci przeglądarki (np.
element.id
,element.className
,element.href
,element.value
,element.checked
,element.disabled
). Metoda.prop()
służy do pracy z nimi.
W wielu przypadkach wartości atrybutów i właściwości są zsynchronizowane, ale nie zawsze. Szczególnie dla właściwości logicznych (boolean) jak checked
, selected
, disabled
, zaleca się używanie .prop()
.
-
.attr(nazwaAtrybutu)
: Pobiera wartość podanego atrybutu pierwszego elementu w zbiorze.let linkUrl = $("#mojLink").attr("href"); let obrazekSrc = $("img:first").attr("src"); let inputType = $("input:first").attr("type");
-
.attr(nazwaAtrybutu, wartosc)
: Ustawia wartość podanego atrybutu dla wszystkich elementów w zbiorze.// Zmiana linku $("#mojLink").attr("href", "https://nowy-adres.com"); // Zmiana źródła obrazka $("img.logo").attr("src", "nowe-logo.png"); // Dodanie atrybutu title $("a").attr("title", "Kliknij, aby przejść"); // Ustawienie wielu atrybutów naraz za pomocą obiektu $("img").attr({ src: "obrazek.jpg", alt: "Opis obrazka", title: "Tytuł obrazka" });
-
.removeAttr(nazwaAtrybutu)
: Usuwa podany atrybut ze wszystkich elementów w zbiorze.$("input").removeAttr("disabled"); // Usuwa atrybut disabled, włączając pole
-
.prop(nazwaWlasciwosci)
: Pobiera wartość podanej właściwości pierwszego elementu w zbiorze. Zalecane dla właściwości logicznych (boolean).let czyZaznaczony = $("#zgoda").prop("checked"); // Zwraca true lub false let czyWylaczony = $("#przycisk").prop("disabled"); // Zwraca true lub false let selectIndex = $("select").prop("selectedIndex"); // Zwraca indeks wybranej opcji
-
.prop(nazwaWlasciwosci, wartosc)
: Ustawia wartość podanej właściwości dla wszystkich elementów w zbiorze. Zalecane dla właściwości logicznych (boolean).// Zaznaczenie checkboxa $("#zgoda").prop("checked", true); // Odznaczenie checkboxa $("#zgoda").prop("checked", false); // Wyłączenie przycisku $("#przycisk").prop("disabled", true); // Ustawienie wielu właściwości naraz za pomocą obiektu $("input[type=\'checkbox\']").prop({ checked: true, disabled: false });
-
.removeProp(nazwaWlasciwosci)
: Usuwa podaną właściwość ze wszystkich elementów w zbiorze. Uwaga: Nie zaleca się usuwania wbudowanych właściwości (jakchecked
czydisabled
) za pomocą.removeProp()
. Zamiast tego ustawiaj ich wartość nafalse
za pomocą.prop()
..removeProp()
jest przeznaczone głównie dla właściwości dodanych niestandardowo przez.prop()
.
Kiedy używać .attr()
a kiedy .prop()
?
- Dla atrybutów, których wartość widzisz bezpośrednio w HTML (np.
id
,class
,src
,href
, niestandardowe atrybutydata-*
) - zazwyczaj.attr()
działa dobrze, choć.prop()
często też zadziała dla standardowych właściwości. - Dla właściwości, które reprezentują stan elementu i mogą się zmieniać bez odzwierciedlenia w atrybucie HTML (np.
checked
,selected
,disabled
,value
inputa po wpisaniu przez użytkownika) - zdecydowanie używaj.prop()
. - Reguła kciuka: Jeśli właściwość może być tylko
true
lubfalse
, użyj.prop()
.
Zadanie praktyczne
Stwórz plik HTML zawierający:
- Paragraf z ID "info":
<p id="info">To jest <strong>ważna</strong> informacja.</p>
- Pole input tekstowe z ID "nazwa":
<input type="text" id="nazwa" value="Domyślna wartość">
- Link z ID "link-zew" i atrybutem href:
<a id="link-zew" href="https://example.com">Stary link</a>
- Checkbox z ID "zgoda-marketingowa":
<input type="checkbox" id="zgoda-marketingowa"> Zgoda marketingowa
- Przycisk z ID "wyslij" i atrybutem disabled:
<button id="wyslij" disabled>Wyślij</button>
Używając jQuery:
- Odczytaj i wyświetl w konsoli zawartość HTML paragrafu "info".
- Odczytaj i wyświetl w konsoli zawartość tekstową paragrafu "info".
- Zmień tekst linku "link-zew" na "Odwiedź Google".
- Zmień atrybut
href
linku "link-zew" na "https://google.com". - Odczytaj i wyświetl w konsoli początkową wartość pola "nazwa".
- Zmień wartość pola "nazwa" na "Nowa wartość z jQuery".
- Sprawdź (zaznacz) checkbox "zgoda-marketingowa" używając
.prop()
. - Odczytaj i wyświetl w konsoli stan zaznaczenia checkboxa "zgoda-marketingowa" po zmianie.
- Usuń atrybut
disabled
z przycisku "wyslij" używając.removeAttr()
(lub ustaw.prop(\'disabled\', false)
).
Pokaż rozwiązanie
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test Manipulacji DOM</title>
</head>
<body>
<p id="info">To jest <strong>ważna</strong> informacja.</p>
<input type="text" id="nazwa" value="Domyślna wartość"><br>
<a id="link-zew" href="https://example.com">Stary link</a><br>
<input type="checkbox" id="zgoda-marketingowa"> Zgoda marketingowa<br>
<button id="wyslij" disabled>Wyślij</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>
$(function() {
// 1. Odczytaj HTML paragrafu
let infoHtml = $("#info").html();
console.log("1. HTML paragrafu:", infoHtml);
// 2. Odczytaj tekst paragrafu
let infoText = $("#info").text();
console.log("2. Tekst paragrafu:", infoText);
// 3. Zmień tekst linku
$("#link-zew").text("Odwiedź Google");
console.log("3. Zmieniono tekst linku.");
// 4. Zmień href linku
$("#link-zew").attr("href", "https://google.com");
console.log("4. Zmieniono href linku.");
// 5. Odczytaj wartość pola input
let nazwaVal = $("#nazwa").val();
console.log("5. Wartość pola \'nazwa\':", nazwaVal);
// 6. Zmień wartość pola input
$("#nazwa").val("Nowa wartość z jQuery");
console.log("6. Zmieniono wartość pola \'nazwa\'. Nowa wartość:", $("#nazwa").val());
// 7. Zaznacz checkbox
$("#zgoda-marketingowa").prop("checked", true);
console.log("7. Zaznaczono checkbox \'zgoda-marketingowa\'.");
// 8. Odczytaj stan checkboxa
let czyZgoda = $("#zgoda-marketingowa").prop("checked");
console.log("8. Stan checkboxa \'zgoda-marketingowa\':", czyZgoda);
// 9. Włącz przycisk
// Sposób 1: .removeAttr()
// $("#wyslij").removeAttr("disabled");
// Sposób 2: .prop() - zalecany dla właściwości boolean
$("#wyslij").prop("disabled", false);
console.log("9. Włączono przycisk \'wyslij\'. Stan disabled:", $("#wyslij").prop("disabled"));
});
</script>
</body>
</html>
Zadanie do samodzielnego wykonania
Dodaj do HTML obrazek <img id="logo" src="stare-logo.png" alt="Stare Logo">
oraz listę rozwijaną <select id="kolor"><option value="czerwony">Czerwony</option><option value="zielony">Zielony</option></select>
.
Używając jQuery:
- Zmień atrybut
src
obrazka na "nowe-logo.jpg". - Zmień atrybut
alt
obrazka na "Nowe Logo Firmy". - Odczytaj i wyświetl w konsoli wybraną wartość z listy rozwijanej "kolor".
- Ustaw programowo wybraną opcję w liście "kolor" na "zielony" (użyj
.val()
). - Dodaj obrazkowi niestandardowy atrybut
data-version="2.0"
używając.attr()
.
FAQ - Manipulacja Treścią i Atrybutami w jQuery
Czy mogę użyć .html()
lub .text()
do dodania treści, zamiast zastępowania?
Metody .html()
i .text()
zastępują istniejącą zawartość. Do dodawania treści służą inne metody, takie jak .append()
(dodaje na końcu), .prepend()
(dodaje na początku), .before()
(dodaje przed elementem) i .after()
(dodaje po elemencie), które zostaną omówione w kolejnej lekcji.
Jak odczytać wartość atrybutu `data-*`?
Możesz użyć standardowej metody .attr(\'data-nazwa\')
. jQuery oferuje również dedykowaną metodę .data(\'nazwa\')
, która jest bardziej elastyczna – potrafi automatycznie konwertować typy (np. JSON zapisany w atrybucie) i przechowuje dane w pamięci podręcznej jQuery, co może być wydajniejsze przy wielokrotnym dostępie.
Co się stanie, gdy ustawię atrybut, który już istnieje, używając .attr()
?
Istniejąca wartość atrybutu zostanie nadpisana nową wartością podaną w metodzie .attr(nazwa, nowaWartosc)
. Jeśli chcesz dodać wartość do istniejącego atrybutu (np. dodać klasę do atrybutu class
), lepiej użyć dedykowanych metod jak .addClass()
.
Czy .val()
działa dla wszystkich elementów formularza?
.val()
działa poprawnie dla większości elementów formularza: input
(różne typy), textarea
, select
. Dla checkboxów zwraca wartość atrybutu value
tylko jeśli są zaznaczone (lepiej używać .prop(\'checked\')
do sprawdzania stanu). Dla radio buttonów zwraca wartość zaznaczonego przycisku w grupie (trzeba użyć selektora :checked
).
Czy zmiana właściwości przez .prop()
zawsze aktualizuje atrybut w HTML?
Nie zawsze. Na przykład, zmiana właściwości value
pola input przez .prop(\'value\', \'nowa\')
lub przez wpisanie tekstu przez użytkownika zmieni wartość w obiekcie DOM, ale nie zaktualizuje atrybutu value
widocznego w źródle HTML. Podobnie, .prop(\'checked\', true)
zmieni stan zaznaczenia, ale niekoniecznie doda atrybut checked
do HTML.