# DOM manipulation

  • A jQuery statement always consists of two or more parts
    • The first part is always a selector
    • The following (chained) part(s) describe the action(s) you perform on the selector
  • For example:
    • $('p.foo'): select all p-tags with the class .foo
    • .addClass('bar'): add class .bar to the selection
    • .show('slow');: make the section visible
$('p.foo').addClass('bar').show('slow');
Copied!
1
  • Making a good selection is crucial to executing a powerful script!

# Select elements

# CSS3 selectors

  • A jQuery selector always starts with the dollar sign, followed by a CSS3 selector between parentheses
  • jQuery has only one type of selector $() which replaces all the possible vanilla JavaScript selectors like
    document.getElementById(), document.querySelector() and document.querySelectorAll()

TIP

You can test your CSS selector knowledge using $() and compare it with document.querySelectorAll() on this page: https://itf-es6.netlify.app/es6/dom/querySelector.html (opens new window)

# jQuery specific selectors

jQuery description
:has(<selector>) (opens new window) select elements which contain at least one element that matches the specified <selector>
:hidden (opens new window) select all elements that are hidden
:visible (opens new window) select all elements that are visible
:parent (opens new window) select all elements that have at least one child node (either an element or text)
:selected (opens new window) select the selected option(s) from select lists
:checked (opens new window) select the checked item(s) of checkboxes or radio buttons, as well as the selected option(s) of select lists

# Loop over jQuery objects

  • Where document.querySelectorAll() results in a nodeList, a jQuery selector $() always returns a jQuery object, even if there is only one element selected
  • Use the jQuery each() (opens new window) method to loop over a jQuery object
  • Open jQuery/dom/loopObjects.html and jQuery/dom/loopObjects.js, where we have a list of buttons and want some information about every button:

 
 
 


<div id="buttongroup">
    <button class="primary">primary button</button>
    <button class="secondary">secondary button</button>
    <button class="tertiary">tertiary button</button>
</div>
Copied!
1
2
3
4
5

# Modify content

jQuery vanilla JS description
<element>.text() (opens new window) <element>.textContent get or set ALL text inside the <element> (including spaces and hidden text)
<element>.html() (opens new window) <element>.innerHTML get or set the HTML content inside <element>
  • Open jQuery/dom/content.html and jQuery/dom/content.js
  • The HTML contains some text (p#quote) and an unordered list (ul)
  • Inside p#quote there is some hidden text


 

 

 







<main class="container">
    <h1>Modifying content</h1>
    <p id="quote">
        Lorem ipsum dolor sit amet, <b>consectetur adipisicing elit</b>.<br />
        Adipisci dolores <span style="display: none">with invisible text</span>?
    </p>
    <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
    </ul>
    ....
</main>
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13

REMARK: jQuery methods acting on multiple elements

  • In the overview tables on this (and the following) page(s), we use the notation <element>.method() which makes it "easy" to compare the introduced methods with their vanilla JavaScript counterparts (where we used a similar notation)
  • However, this is not entirely correct, as in jQuery some methods can be applied to multiple elements without looping over them (a process known as implicit iteration)
    • Example: if you uncomment line 8 ($('main li').text('Same text for all list items');) in the script jQuery/dom/content.js, the same text will be set for all elements (list items) matching the selection $('main li') (without using an each() loop)
  • When needed, consult the official jQuery API documentation (opens new window) for the detailed information regarding a specific method!

# Modify attributes

jQuery vanilla JS description
<element>.attr(<attribute>) (opens new window) <element>.getAttribute(<attribute>)
<element>.<attribute>
get the <attribute> of the <element>
<element>.attr(<attribute>, <value>) (opens new window) <element>.setAttribute(<attribute>, <value>)
<element>.<attribute> = <value>
set the <attribute> of the <element> to <value>
<element>.removeAttr(<attribute>) (opens new window) <element>.removeAttribute(<attribute>) remove the <attribute> on the <element>
  • Open jquery/dom/attributes.html and jquery/dom/attributes.js



 
 
 
 




<main class="container">
    <h1>Modifying attributes</h1>
    <div id="fotoFrame">
        <img src="https://picsum.photos/id/623/200/200" alt="Image 1" />
        <img src="https://picsum.photos/id/626/200/200" alt="Image 2" />
        <img src="https://picsum.photos/id/641/200/200" alt="Image 3" />
        <img src="https://picsum.photos/id/744/200/200" alt="Image 4" />
    </div>
    ....
</main>
Copied!
1
2
3
4
5
6
7
8
9
10

Attributes before

# Modify form attributes

  • Certain form attributes (also called properties) should be treated differently in jQuery
  • For example, checked, disabled and selected should be retrieved and set with the prop() method instead of the attr() method!
jQuery description
<element>.prop(<property>) (opens new window) get the <property> of the <element>
<element>.prop(<property>, <value>) (opens new window) set the <property> of the <element> to <value>
<element>.removeProp(<property>) (opens new window) remove the <property> on the <element>
  • Open jquery/dom/properties.html and jquery/dom/properties.js
 


 



 




<pre></pre>
<form>
    <div class="row responsive-label">
        <input type="checkbox" id="check1" value="I'm checkbox one" />
        <label for="check1">Checkbox 1</label>
    </div>
    <div class="row responsive-label">
        <input type="checkbox" id="check2" value="I'm checkbox two" checked disabled />
        <label for="check2">Checkbox 2</label><br />
    </div>
</form>
Copied!
1
2
3
4
5
6
7
8
9
10
11

WARNING

Aways use the val() (opens new window) method to get/set the value of an input/form element, and not the attr() or prop() methods (as the use of the latter methods may lead to unexpected results)!

# The data-* attribute

jQuery vanilla JS description
<element>.data('*') (opens new window) <element>.dataset.* get the data-* attribute of the <element>
<element>.attr('data-*', <value>) <element>.dataset.* = <value> set the data-* attribute of the <element> to <value>
  • Open jquery/dom/data_attributes.html and jquery/dom/data_attributes.js


 
 

 


<figure>
    <img src="https://picsum.photos/id/855/600/400" alt="" id="img1"
        data-photographer="Rodion Kutsaev"
        data-unsplash-url="https://unsplash.com/photos/IJ25m7fXqtk"
        />
    <figcaption></figcaption>
</figure>
Copied!
1
2
3
4
5
6
7

Attributes before

# Modify classes

jQuery vanilla JS description
<element>.addClass(<c1>, ...) (opens new window) <element>.classList.add(<c1>, ...) add class(es) to the <element>
<element>.removeClass(<c1>, ...) (opens new window) <element>.classList.remove(<c1>, ...) remove class(es) from the <element>
<element>.toggleClass(<c>) (opens new window) <element>.classList.toggle(<c>) toggle the class <c> on the <element>:
- add the class if it doesn't exist
- remove the class if it exists
<element>.hasClass(<c>) (opens new window) <element>.classList.contains(<c>) check if the class <c> exists on the <element>:
returns true or false
  • Open jquery/dom/classes.html and jquery/dom/classes.js




 
 
 
 
 
 





 
 
 
 





<html lang="en">
    <head>
        ...
        <style>
            .border { border: 1px solid #000;  padding: 0.3rem; margin: 0.5rem; }
            .sepia { filter: sepia(1); }
            .grayscale { filter: grayscale(80%); }
            .red { background-color: indianred; }
            .green { background-color: yellowgreen; }
            .shadow { box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3); }
        </style>
    </head>
    <body>
        ...
        <div id="fotoFrame">
            <img src="https://picsum.photos/id/623/200/200" alt="Image 1" class="border" />
            <img src="https://picsum.photos/id/626/200/200" alt="Image 2" class="border red" />
            <img src="https://picsum.photos/id/641/200/200" alt="Image 3" class="border" />
            <img src="https://picsum.photos/id/744/200/200" alt="Image 4" class="border green" />
        </div>
        ...
    </body>
</html>
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Classes before

# Modify inline styles

jQuery vanilla JS description
<element>.css(<property>) (opens new window) <element>.style.<property> get the inline style <property> on the <element>
<element>.css(<property>, <value>) (opens new window) <element>.style.<property> = <value> set the inline style <property> on the <element> to <value>
<element>.width() (opens new window) <element>.style.width get/set the width of the <element>
<element>.innerWidth() (opens new window) get/set the width (including padding but not border) of the <element>
<element>.outerWidth() (opens new window) get/set the width (including padding, border, and optionally margin) of the <element>
<element>.height() (opens new window) <element>.style.height get/set the height of the <element>
<element>.innerHeight() (opens new window) get/set the height (including padding but not border) of the <element>
<element>.outerHeight() (opens new window) get/set the height (including padding, border, and optionally margin) of the <element>

TIP

  • Setting multiple styles can be done by chaining multiple css() methods:
<element>.css('border','solid 3px #50a551').css('background-color', 'rgba(80, 165, 81, 0.1)');
Copied!
1

or with one css() method with an object of properties:

<element>.css({
    border: 'solid 3px #50a551',
    backgroundColor: 'rgba(80, 165, 81, 0.1)',
});
Copied!
1
2
3
4
  • Open jquery/dom/styles.html and jquery/dom/styles.js


 


<figure>
    <img src="https://picsum.photos/id/76/600/400" alt="" id="img1" 
        style="padding: 1rem" />
</figure>
Copied!
1
2
3
4

Style before

# Modify elements

jQuery vanilla description
<element>.empty() (opens new window) <element>.innerHTML = '' remove all child nodes inside the <element>
<element>.remove() (opens new window) <element>.remove() remove <element> from the DOM
<element>.replaceWith(<content>) (opens new window) <element>.replaceWith() replace the selected <element> with <content>
<element>.append(<content>) (opens new window) <element>.append() insert <content> at the end of the selected <element>
<element>.prepend(<content>) (opens new window) <element>.prepend() insert <content> at the beginning of the selected <element>
<element>.before(<content>) (opens new window) <element>.before() insert <content> before the selected <element>
<element>.after(<content>) (opens new window) <element>.after() insert <content> after the selected <element>
  • Open jQuery/dom/elements.html and jQuery/dom/elements.js

 
 
 
 
 
 



<main class="container">
    <h1>Modifying elements</h1>
    <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
    </ul>
    ...
</main>
Copied!
1
2
3
4
5
6
7
8
9

Elements before

# Example

# Contact hours

  • Open jQuery/dom/contactHours.html and jQuery/dom/contactHours.js
  • The page contains two tables in which we mark today's opening hours
  • Each weekday corresponds to one row within the tbody tag
    • Note that we start the table with Sunday. This is a deliberate choice because it allows us to easily link the row number to the weekday of the Date object.
  • Every td also needs a data-label attribute to render the table correctly on small screens (see https://minicss.org/docs#tables (opens new window))
<table>
    <thead>...</thead>
    <tbody>
        <tr>
            <td><b>sunday</b></td>
            <td>Closed</td>
            <td>Closed</td>
            <td>Closed</td>
        </tr>
        <tr>
            <td><b>monday</b></td>
            <td>9:00 – 12:00</td>
            <td>13:30 – 16:00</td>
            <td>Closed</td>
        </tr>
        ...
    </tbody>
</table>
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Last Updated: 5/17/2021, 6:47:29 AM