vikramlc / Javascript

0 stars 0 forks source link

Creating, Inserting and Removing Elements #5

Open vikramlc opened 4 years ago

vikramlc commented 4 years ago

image

vikramlc commented 4 years ago

Adding elements via Html in code: innerHTML -> Re-renders the entire html code insertAdjacentHTML -> Just adds the new element in the html and does not re-render image

vikramlc commented 4 years ago

Adding elements via createElement():

const ul = document.querySelector('ul');
undefined
ul.children
HTMLCollection(3) [li.list-item, li.list-item, li.list-item]0: li.list-itemaccessKey: ""ariaAtomic: nullariaAutoComplete: nullariaBusy: nullariaChecked: nullariaColCount: nullariaColIndex: nullariaColSpan: nullariaCurrent: nullariaDescription: nullariaDisabled: nullariaExpanded: nullariaHasPopup: nullariaHidden: nullariaKeyShortcuts: nullariaLabel: nullariaLevel: nullariaLive: nullariaModal: nullariaMultiLine: nullariaMultiSelectable: nullariaOrientation: nullariaPlaceholder: nullariaPosInSet: nullariaPressed: nullariaReadOnly: nullariaRelevant: nullariaRequired: nullariaRoleDescription: nullariaRowCount: nullariaRowIndex: nullariaRowSpan: nullariaSelected: nullariaSort: nullariaValueMax: nullariaValueMin: nullariaValueNow: nullariaValueText: nullassignedSlot: nullattributeStyleMap: StylePropertyMap {size: 0}attributes: NamedNodeMap {0: class, class: class, length: 1}autocapitalize: ""autofocus: falsebaseURI: "file:///C:/Users/1994/Documents/Workspace/Javascript/dom-02-basic-selection-code/index.html"childElementCount: 0childNodes: NodeList [text]children: HTMLCollection []classList: DOMTokenList ["list-item", value: "list-item"]className: "list-item"clientHeight: 18clientLeft: 0clientTop: 0clientWidth: 1224contentEditable: "inherit"dataset: DOMStringMap {}dir: ""draggable: falseelementTiming: ""enterKeyHint: ""firstChild: textfirstElementChild: nullhidden: falseid: ""innerHTML: "Item 1"innerText: "Item 1"inputMode: ""isConnected: trueisContentEditable: falselang: ""lastChild: textlastElementChild: nulllocalName: "li"namespaceURI: "http://www.w3.org/1999/xhtml"nextElementSibling: li.list-itemnextSibling: textnodeName: "LI"nodeType: 1nodeValue: nullnonce: ""offsetHeight: 18offsetLeft: 48offsetParent: bodyoffsetTop: 79offsetWidth: 1224onabort: nullonanimationend: nullonanimationiteration: nullonanimationstart: nullonauxclick: nullonbeforecopy: nullonbeforecut: nullonbeforepaste: nullonbeforexrselect: nullonblur: nulloncancel: nulloncanplay: nulloncanplaythrough: nullonchange: nullonclick: nullonclose: nulloncontextmenu: nulloncopy: nulloncuechange: nulloncut: nullondblclick: nullondrag: nullondragend: nullondragenter: nullondragleave: nullondragover: nullondragstart: nullondrop: nullondurationchange: nullonemptied: nullonended: nullonerror: nullonfocus: nullonformdata: nullonfullscreenchange: nullonfullscreenerror: nullongotpointercapture: nulloninput: nulloninvalid: nullonkeydown: nullonkeypress: nullonkeyup: nullonload: nullonloadeddata: nullonloadedmetadata: nullonloadstart: nullonlostpointercapture: nullonmousedown: nullonmouseenter: nullonmouseleave: nullonmousemove: nullonmouseout: nullonmouseover: nullonmouseup: nullonmousewheel: nullonpaste: nullonpause: nullonplay: nullonplaying: nullonpointercancel: nullonpointerdown: nullonpointerenter: nullonpointerleave: nullonpointermove: nullonpointerout: nullonpointerover: nullonpointerrawupdate: nullonpointerup: nullonprogress: nullonratechange: nullonreset: nullonresize: nullonscroll: nullonsearch: nullonseeked: nullonseeking: nullonselect: nullonselectionchange: nullonselectstart: nullonstalled: nullonsubmit: nullonsuspend: nullontimeupdate: nullontoggle: nullontransitionend: nullonvolumechange: nullonwaiting: nullonwebkitanimationend: nullonwebkitanimationiteration: nullonwebkitanimationstart: nullonwebkitfullscreenchange: nullonwebkitfullscreenerror: nullonwebkittransitionend: nullonwheel: nullouterHTML: "<li class="list-item">Item 1</li>"outerText: "Item 1"ownerDocument: documentparentElement: ulparentNode: ulpart: DOMTokenList [value: ""]prefix: nullpreviousElementSibling: nullpreviousSibling: textscrollHeight: 18scrollLeft: 0scrollTop: 0scrollWidth: 1224shadowRoot: nullslot: ""spellcheck: truestyle: CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}tabIndex: -1tagName: "LI"textContent: "Item 1"title: ""translate: truetype: ""value: 0__proto__: HTMLLIElement1: li.list-item2: li.list-itemlength: 3__proto__: HTMLCollection
ul.children[1]
<li class=​"list-item">​Item 2​</li>​
const newLi = document.createElement('li');
undefined
newLi
<li>​</li>​
ul.appendChild(newLi);
<li>​</li>​
newLi.textContent = 'Item 4';
"Item 4"
vikramlc commented 4 years ago

Inserting DOM Nodes:

The Node.insertBefore() method inserts a node before a reference node as a child of a specified parent node.
<div id="parentElement">
   <span id="childElement">foo bar</span>
</div>

<script>
// Create the new node to insert
let newNode = document.createElement("span")

// Get a reference to the parent node
let parentDiv = document.getElementById("childElement").parentNode

// Begin test case [ 1 ] : Existing childElement (all works correctly)
let sp2 = document.getElementById("childElement")
parentDiv.insertBefore(newNode, sp2)
// End test case [ 1 ]

// Begin test case [ 2 ] : childElement is of Type undefined 
let sp2 = undefined // Non-existent node of id "childElement"
parentDiv.insertBefore(newNode, sp2) // Implicit dynamic cast to type Node
// End test case [ 2 ]

// Begin test case [ 3 ] : childElement is of Type "undefined" ( string )
let sp2 = "undefined" // Non-existent node of id "childElement"
parentDiv.insertBefore(newNode, sp2) // Generates "Type Error: Invalid Argument" 
// End test case [ 3 ]
</script>
vikramlc commented 4 years ago

Cloning DOM elements:

The Node.cloneNode([deep]) method returns a duplicate of the node on which this method was called.

deep -> optional If true, then node and its whole subtree—including text that may be in child Text nodes—is also copied.

If false, only node will be cloned. Any text that node contains is not cloned, either (since text is contained by one or more child Text nodes).

deep has no effect on empty elements (such as the and elements).

vikramlc commented 4 years ago

Removing DOM elements:

const list = document.querySelector('ul');
list.parentElement.removeChild();
vikramlc commented 4 years ago

image

vikramlc commented 4 years ago

Summary: Insert, Replace, Remove

There are many ways of creating, inserting, replacing and removing DOM elements - here's a summary of the options you have.

For browser support, check the provided links and also the "Browser Support" module you find later in the course.

Create & Insert You got two main options: Provide an HTML snippet (e.g. via innerHTML) to a valid HTML snippet and let the browser render it OR create a DOM object in JS code and append/ insert it manually. The latter approach has the advantage of giving you direct access to the DOM object (useful for setting its properties or adding event listeners). The downside is that you have to write more code.

Adding HTML Code:

const root = document.getElementById('root-el'); // selects something like <div id="root-el">
root.innerHTML = `
    <div>
        <h2>Welcome!</h2>
        <p>This is all create & rendered automatically!</p>
    </div>
`;

Important: Any existing content in root is completely replaced when using innerHTML. If you want to append/ insert HTML code, you can use insertAdjacentHTML instead: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

const root = document.getElementById('root-el'); // selects something like <div id="root-el">
root.insertAdjacentHTML('afterbegin', `
    <div>
        <h2>Welcome!</h2>
        <p>This is all create & rendered automatically!</p>
    </div>
`);

Creating & Inserting DOM Objects Manually:

const someParagraph = document.createElement('p'); // creates a "p" element (i.e. a <p> element)
const root = document.getElementById('root-el'); // selects something like <div id="root-el">
root.append(someParagraph);

In this example, we create a paragraph and append it to root - append means that it's inserted at the end of root (i.e. inside of it but AFTER all other child nodes it holds).

Insertion Methods:

append() => https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append

Browser support is decent but for IE, appendChild() could be preferred => https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild

prepend() => https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/prepend

Browser support is decent but for IE, insertBefore() could be preferred => https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore

before(), after() => https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/before & https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/after

Browser support is okay but IE and Safari don't support it. Consider insertBefore() (https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore) or insertAdjacentElement() (https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement) as substitutes.

Important (no matter how you insert elements): Whenever you insert elements, you MOVE the element to that new place if you already inserted it before. It's NOT copied (you can copy an element via someElement.cloneNode(true) though).

Replace You can replace elements in the DOM with two main methods:

replaceWith() => https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith

replaceChild() => https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild

replaceWith() is a bit easier to use and has decent browser support - with IE being the exception. To support that as well, consider using replaceChild().

Remove You can remove elements with three main methods:

someElement.innerHTML = '' => Clears all HTML content of someElement and hence removes any objects rendered in there.

someElement.remove() => Removes a single element (someElement) from the DOM (https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove). Browser support is good, IE again doesn't like it though. Use removeChild (see below) instead.

someElement.parentNode.removeChild(someElement) =>  Removes the provided child element (NOT the element on which you call it). Provides broad browser support but of course requires a bit more code (https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild).

What about Text Nodes? You can easily create & insert text nodes in one go:

someElement.textContent = 'Hi there!';
This creates and inserts the text node with a content of 'Hi there!'.

Want to append to existing text?

Just use:

someElement.textContent = someElement.textContent + 'More text!';