DOM கையாளுதல் (DOM Manipulation)
window உலாவியைக் குறிக்கும் போது, DOM 자체가 document உலகளாவிய பொருளால் (global object) குறிக்கப்படுகிறது—document என்பது DOM (உலாவியில் காட்டப்படும் தற்போதைய HTML). உலாவியில் காட்டப்படும் உள்ளடக்கத்தைக் கையாளுவதற்காக இந்தப் பொருளின் பண்புகளை (properties) அணுகி, முறைகளை (methods) அழைக்கிறீர்கள்!
HTML கூறுகளைக் குறிப்பிடுதல் (Referencing HTML Elements)
ஒரு பக்கத்தில் உள்ள DOM கூறுகளைக் கையாள, நீங்கள் மாற்ற விரும்பும் உறுப்பிற்கான ஒரு குறிப்பை (reference) முதலில் பெற வேண்டும்—அதாவது, அந்த உறுப்பைக் குறிக்கும் ஒரு மாறி (variable) உங்களுக்குத் தேவை. document "தேர்வி (selector)" செயல்பாடுகளில் ஒன்றைப் பயன்படுத்துவதன் மூலம் இந்த மாறி குறிப்புகளைப் பெறலாம்:
// id="foo" கொண்ட உறுப்பு
let fooElem = document.getElementById("foo");
// class="row" கொண்ட உறுப்புகள்
let rowElems = document.getElementsByClassName("row"); //பன்மை (plural) என்பதைக் கவனியுங்கள்!
// <li> கூறுகள்
let liElems = document.getElementsByTagName("li"); //பன்மை என்பதைக் கவனியுங்கள்!
/* CSS தேர்வாளர்களை மீண்டும் பயன்படுத்துவதன் மூலம் தேர்ந்தெடுப்பது எளிது! */
let cssSelector = "header p, .title > p"; //ஒரு CSS தேர்வியின் சரம்
// css தேர்வியுடன் பொருந்தும் முதல் உறுப்பைத் தேர்ந்தெடுக்கிறது
let elem = document.querySelector(cssSelector);
// css தேர்வியுடன் பொருந்தும் அனைத்து உறுப்புகளையும் பொருத்துகிறது
let elems = document.querySelectorAll(cssSelector);
document.querySelector()என்பது இந்த முறைகளில் பயன்படுத்த மிகவும் நெகிழ்வானதும் எளிமையானதுமாகும்: இது மற்ற அனைத்து முறைகளையும் போலவே எளிதாக செய்ய முடியும் (ஒரு id, class அல்லது element தேர்வியை உள்ளிடவும்). நீங்கள் எப்போதும்querySelector()ஐப் பயன்படுத்த வேண்டும்.பல கணுக்களைத் (e.g.,
querySelectorAll) திரும்பப் பெறும் முறைகள்NodeListபொருளைத் திரும்பப் பெறுகின்றன என்பதை நினைவில் கொள்க. இது ஒரு வரிசையைப் போல (array) இருந்தாலும் (bracket notation மூலம் குறியீட்டு வழியாக நீங்கள் கூறுகளை அணுகலாம் மற்றும் இது ஒரு.lengthபண்பைக் கொண்டுள்ளது), இது ஒரு வரிசை அல்ல: அதாவது இது அனைத்து உலாவிகளிலும்forEach()மற்றும்map()போன்ற முறைகளை ஆதரிக்காது. நீங்கள் ஒருNodeListமூலம் மீள்திருப்ப (iterate) வேண்டும் என்றால், நீங்கள் வழக்கமானforசுழற்சியைப் பயன்படுத்த வேண்டும். ஆனால் நடைமுறையில், நீங்கள் ஒரே நேரத்தில் ஒற்றை கூறுகளுடன் வேலை செய்ய அதிக வாய்ப்புள்ளது.
HTML கூறுகளை மாற்றுதல் (Modifying HTML Elements)
உங்களிடம் ஒரு உறுப்பிற்கான குறிப்பு கிடைத்ததும், DOM இல் அதன் நிலையை மாற்ற அந்தப் பொருளின் பண்புகளை அணுகி முறைகளை அழைக்கிறீர்கள் - இது பக்கத்தில் அது தற்போது எவ்வாறு காட்டப்படுகிறது என்பதை மாற்றும். இவ்வாறு இந்தப் பொருள்களை மாற்றுவதன் மூலம், வலைப்பக்கத்தின் உள்ளடக்கத்தை நீங்கள் டைனமிக் ஆக மாற்றுகிறீர்கள்!
**முக்கியமானது**: இந்தப் பண்புகளை அமைப்பது `.html` மூலக் குறியீடு கோப்பை (source code file) மாற்றாது! மாறாக, அவை _காட்டப்படும் DOM கூறுகளை_ மட்டுமே மாற்றுகின்றன (நினைத்துப் பாருங்கள்: உள்ளடக்கங்கள் கோப்பில் இல்லாமல் கணினியின் நினைவகத்தில் சேமிக்கப்படுகின்றன). நீங்கள் பக்கத்தைப் புதுப்பித்தால் (refresh), DOM ஐ மாற்றும் ஸ்கிரிப்ட் ஏற்றப்படாவிட்டால் தவிர, உள்ளடக்கம் `.html` மூலக் குறியீடு கோப்பு குறிப்பிடும் விதத்திற்குத் திரும்பும். பக்கத்தில் காட்டப்படுவது ஜாவாஸ்கிரிப்ட் மாற்றங்கள் சேர்க்கப்பட்ட HTML ஆகும்.
உள்ளடக்கத்தை மாற்றுதல் (Changing Content)
DOM உறுப்பின் (எ.கா., தொடக்க மற்றும் இறுதி குறிச்சொற்களுக்கு இடையே உள்ள விஷயங்கள்) உள்ளடக்கத்தை அணுகவும் மாற்றவும் நீங்கள் ஜாவாஸ்கிரிப்டைப் பயன்படுத்தலாம்:
// முதல் <p> உறுப்பிற்கான குறிப்பைப் பெறவும்
let elem = document.querySelector("p");
console.log(elem); //விளக்குவதற்கு
let text = elem.textContent; //உறுப்பின் உரை உள்ளடக்கம்
elem.textContent = "இது வேறுபட்ட உள்ளடக்கம்!"; //உள்ளடக்கத்தை மாற்று
let html = elem.innerHTML; //HTML உள்ளிட்ட உள்ளடக்கம்
elem.innerHTML = "இது <em>வேறுபட்ட</em> உள்ளடக்கம்!"; //HTML ஆக விளக்கப்படுகிறது
உறுப்பின் textContent பண்பு அனைத்து உள்ளடக்கத்தையும் குறிக்கிறது, ஆனால் "வெற்று உரை" என்று கருதப்படுவது இது ஒரு "பாதுகாப்பான" பண்பு என்று பொருள்படும்: HTML குறியீட்டைக் கொண்ட சரங்களை நீங்கள் ஒதுக்கலாம் (எ.கா., <em>Hello</em>), ஆனால் அந்தக் குறியீடு தப்பிக்கப்பட்டு (escaped) HTML ஆக விளக்கப்படாது (மாறாக < மற்றும் > ஆகியவை நீங்கள் HTML entities ஐப் பயன்படுத்தியது போல் எழுதப்படும்). மறுபுறம், .innerHTML பண்பு "பாதுகாப்பற்றது": நீங்கள் ஒதுக்கும் சரத்தில் சேர்க்கப்பட்டுள்ள எந்த HTML உம் DOM கூறுகளாக மாற்றப்படும். உள்ளடக்கம் நம்பகமான மூலத்திலிருந்து வந்ததா என்பதை நீங்கள் உறுதியாக நம்பாவிட்டால் தவிர, இது பயன்படுத்த சிறந்த பண்பு அல்ல.
<em>அல்லது<strong>போன்ற உள்ளமை (inline) கூறுகளைச் சேர்க்கinnerHTMLபண்பு முதன்மையாகப் பயன்படுத்தப்பட வேண்டும். மிகவும் சிக்கலான HTML உள்ளடக்கத்திற்கு, வெளிப்படையாக புதிய கூறுகளை உருவாக்குவது தூய்மையான குறியீடாகும் (கவலைகளின் பிரிப்பு!) - விவரங்களுக்கு கீழே காண்க.ஒரு உறுப்பின் உள்ளடக்கத்தை வெற்றுச் சரமாக (
'') அமைப்பதன் மூலம் அதை "அழிக்கலாம் (clear)":let alertElem = document.querySelector(".alert"); alertElem.textContent = ""; //இனி எச்சரிக்கை இல்லை!
பண்புக்கூறுகளை மாற்றுதல் (Changing Attributes)
நீங்கள் தனிப்பட்ட கூறுகளின் பண்புக்கூறுகளையும் (attributes) மாற்றலாம். HTML விவரக்குறிப்பில் வரையறுக்கப்பட்ட ஒவ்வொரு பண்புக்கூறும் பொதுவாக உறுப்பு பொருளின் ஒரு பண்பாக (property) வெளிப்படுத்தப்படுகிறது:
// `#picture` உறுப்பிற்கான குறிப்பைப் பெறவும்
let imgElem = document.querySelector("#picture");
// பண்புக்கூறை அணுகவும்
console.log(imgElem.src); //படத்தின் மூலத்தைப் பதிவு செய்கிறது
// பண்புக்கூறை மாற்றவும்
imgElem.src = "my-picture.png";
நீங்கள் `element.class` அல்லது `element.style` பண்புக்கூறுகளை நேரடியாக இந்த வழியில் அணுக **முடியாது**; உறுப்பின் CSS ஐ மாற்றுவது பற்றிய விவரங்களுக்கு கீழே காண்க.
getAttribute() (எந்த பண்புக்கூறை அணுக வேண்டும் என்பதை அனுப்புதல்) மற்றும் setAttribute() (எந்த பண்புக்கூறை மாற்ற வேண்டும் மற்றும் அந்த பண்புக்கூறுக்கு என்ன மதிப்பை ஒதுக்க வேண்டும் என்பதை அனுப்புதல்) முறைகளைப் பயன்படுத்தி உறுப்பு பண்புக்கூறுகளை மாற்றியமைக்கலாம்:
let imgElem = document.querySelector("#picture");
imgElement.setAttribute("src", "my-other-picture.png"); //src ஐ அமைக்கவும்
console.log(imgElem.getAttribute("src")); //=> 'my-other-picture.png'
// `hasAttribute()` முறை ஒரு பூலியனைத் திரும்பப் பெறுகிறது.
let isThick = document.querySelector("svg rect").hasAttribute("stroke-width"); //சங்கிலியால் பிணைக்கப்பட்ட அநாமதேய மாறிகள்
இந்த முறைகள் data- பண்புக்கூறு போன்ற HTML விவரக்குறிப்பால் வரையறுக்கப்படாத பண்புக்கூறுகளுடன் தொடர்பு கொள்ள உங்களை அனுமதிக்கும். இருப்பினும், அவை சில உறுப்பு பண்புக்கூறுகளுடன் (உள்ளீடு (<input>) உறுப்பின் value பண்புக்கூறு போன்றவை) வேலை செய்யாது. பிற கூறுகள் அவற்றின் சொந்த சிறப்பு DOM பண்புகளைக் கொண்டிருக்கலாம்: HTML இடைமுகங்களின் பட்டியலுக்கு DOM ஆவணப் பக்கத்தைப் பார்க்கவும்.
உறுப்பு CSS ஐ மாற்றுதல் (Changing Element CSS)
ஒரு உறுப்பின் CSS வகுப்புகள் (மற்றும் உள்ளமை ஸ்டைலிங் கூட) மாற்றுவது சாத்தியமாகும். ஆனால் மற்ற பண்புக்கூறுகளைப் போல class பண்பைப் பயன்படுத்துவதற்குப் பதிலாக, நீங்கள் classList பண்பை அணுகுகிறீர்கள். நவீன உலாவிகளில் (IE 10 அல்லது அதற்குப் பிந்தைய), இந்தப் பண்பு பட்டியலில் இருந்து வகுப்புகளைச் சேர்ப்பதற்கும் அகற்றுவதற்கும் .add() மற்றும் .remove() முறைகளை ஆதரிக்கிறது:
// வகுப்புகளின் பட்டியலை அணுகவும்
let classList = elem.classList;
// ஒரு வகுப்பைச் சேர்க்கவும்
elem.classList.add("small"); //ஒற்றை வகுப்பைச் சேர்க்கவும்
elem.classList.add("alert", "alert-warning"); //பல வகுப்புகளைச் சேர்க்கவும் (IE இல் இல்லை)
// ஒரு வகுப்பை அகற்றவும்
elem.classList.remove("small");
//"toggle" (இல்லையென்றால் சேர்க்கவும், இருந்தால் அகற்றவும்)
elem.classList.toggle("small");
IE 10+ இந்த முறைகளை ஆதரிக்கிறது என்றாலும், அது அவற்றுக்கான பல வாதங்களை (multiple arguments) ஆதரிக்காது (எனவே நீங்கள் ஒரு முறை அழைப்பில் பல வகுப்புகளைச் சேர்க்க முடியாது). பழைய உலாவிகளை (எந்த IE பதிப்பும் உட்பட) நீங்கள் ஆதரிக்க வேண்டும் என்றால்,
.classNameபண்பை ஒரு சரமாக (String) பாவித்து மாற்றலாம்:// IE க்கான மாற்று (அனைத்தும்) var classes = elem.className; classes += " " + "sweet sour"; //சரத்தை மாற்றவும் (சேர்க்கவும்!) elem.className = classes; //மீண்டும் ஒதுக்கவும்classListமுறைகள் மைக்ரோசாப்ட் எட்ஜ் இல் சரியாக வேலை செய்கின்றன.
DOM உறுப்பின் style பண்பு மூலம் உறுப்புகளின் தனிப்பட்ட CSS பண்புகளை அணுகவும் மாற்றவும் முடியும். .style என்பது ஒரு பொருளைக் குறிக்கிறது, அதன் விசைகள் CSS பண்புப் பெயர்கள் (ஆனால் kabob-case க்குப் பதிலாக camelCase இல் எழுதப்பட்டவை)
let h1 = document.querySelector("h1");
h1.style.color = "green";
h1.style.backgroundColor = "black"; //`.background-color` அல்ல
பொதுவாக, குறிப்பிட்ட நடை (style) பண்புகளை மாற்றுவதற்குப் பதிலாக, உறுப்பின் வகுப்பை (class) மாற்றுவதன் மூலம் உறுப்பு CSS ஐ மாற்ற வேண்டும்.
DOM மரத்தை மாற்றுதல் (Modifying the DOM Tree)
தனிப்பட்ட DOM உறுப்புகளை மாற்றுவதோடு கூடுதலாக, DOM மரத்தையே அணுகி மாற்றுவதும் சாத்தியமாகும்! அதாவது, நீங்கள் புதிய உறுப்புகளை உருவாக்கி அவற்றை மரத்தில் (படிக்கவும்: வலைப்பக்கம்) சேர்க்கலாம், மரத்திலிருந்து உறுப்புகளை அகற்றலாம், அல்லது மரத்திலிருந்து அவற்றைப் பறித்து வேறு எங்காவது செருகலாம்!
முதலில், ஒவ்வொரு ஜாவாஸ்கிரிப்ட் DOM உறுப்புக்கும் அதன் பெற்றோர், குழந்தைகள் மற்றும் உடன்பிறப்பு (sibling) உறுப்புகளைக் குறிக்கும் படிக்க-மட்டும் பண்புகள் (read-only properties) இருப்பதைக் கவனியுங்கள்:
<main>
<section id="first-section">
<p>First paragraph</p>
<p>Second paragraph</p>
</section>
<section id="second-section"></section>
<main></main>
</main>
// முதல் பிரிவிற்கான குறிப்பைப் பெறவும்
let firstSection = document.querySelector("#first-section");
// "பெற்றோர் (parent)" கணுக்கான குறிப்பைப் பெறவும்
let main = firstSection.parentElement;
console.log(main); //<main>...</main>
// "குழந்தை (child)" கூறுகளுக்கான குறிப்பைப் பெறவும் (2 பத்திகள்)
let paragraphs = firstSection.children;
console.log(paragraphs.length); //2
console.log(paragraphs[0]); //<p>First paragraph</p>
// அடுத்த உடன்பிறப்பிற்கான (next sibling) குறிப்பைப் பெறவும்
let sectionSection = firstSection.nextElementSibling;
console.log(secondSection); //<section id="second-section"></section>
இந்தப் பண்புகள் HTML கூறுகளுடன் மட்டுமே செயல்படுகின்றன என்பதை நினைவில் கொள்க - உரை உள்ளடக்கக் கணுக்கள் (text content nodes) புறக்கணிக்கப்படுகின்றன. உரை உள்ளடக்கக் கணுக்களையும் கருத்தில் கொள்ள, நீங்கள் சமமான
parentNodeமற்றும்childNodesபண்புகளைப் பயன்படுத்தலாம்.SVG உள்ளடக்கம்
parentElementஐ ஆதரிக்காது, ஆனால்parentNodeஐ ஆதரிக்கிறது.
புதிய HTML DOM உறுப்புகளை உருவாக்கி மரத்தில் சேர்க்க முறைகளையும் அழைக்கலாம். ஒரு புதிய HTML உறுப்பை உருவாக்க document.createElement() செயல்பாடு பயன்படுத்தப்படுகிறது. இருப்பினும் இந்த உறுப்பு மரத்தின் ஒரு பகுதியாக உருவாக்கப்படவில்லை (எல்லாவற்றிற்கும் மேலாக, அது பக்கத்தில் எங்கே வைக்கப்படும் என்று நீங்கள் குறிப்பிடவில்லை)! எனவே புதிய உறுப்பை வேறொரு உறுப்பின் குழந்தையாகச் சேர்க்க appendChild போன்ற முறையையும் பயன்படுத்த வேண்டும்:
// ஒரு புதிய <p> ஐ உருவாக்கவும் (இன்னும் மரத்தில் இல்லை)
let newP = document.createElement("p");
newP.textContent = "நான் புதியவன்!";
// உரை உள்ளடக்கத்தின் கணுவை மட்டும் உருவாக்கவும் (HTML உறுப்பு அல்ல, உரை மட்டுமே)
let newText = document.createTextNode("நான் வெற்று");
let main = document.querySelector("main");
main.appendChild(newP); //உறுப்பை உள்ளே சேர்க்கவும் (முடிவில்)
main.appendChild(newText); //உரையை உள்ளே சேர்க்கவும், <p> க்குப் பிறகு
// உறுப்புக்கு முன் அநாமதேய புதிய கணுவைச் சேர்க்கவும். அளவுருக்கள்: (புதியது, பழையது)
main.insertBefore(document.createTextNode("First!"), newP);
// கணுவை மாற்றவும். அளவுருக்கள்: (புதியது, பழையது)
main.replaceChild(document.createTextNode("boo"), newText);
// கணுவை அகற்றவும்
main.removeChild(main.querySelector("p"));
innerHTML பண்பை மாற்றுவதை விட appendChild() முறை ஒரு தூய்மையான அணுகுமுறையாகக் கருதப்படுகிறது, ஏனெனில் இது முன்பு இருந்ததை அழிக்காமல் DOM மரத்தை சரிசெய்ய உங்களை அனுமதிக்கிறது. ஒரு தொகுதி (block) உறுப்பை உருவாக்க document.createElement() ஐப் பயன்படுத்துவது ஒரு பொதுவான நடைமுறையாகும், பின்னர் அந்த உறுப்பின் innerHTML ஐ அதன் உள்ளடக்கத்திற்கு (இது உள்ளமை (inline) உறுப்புகளை உள்ளடக்கியிருக்கலாம்) அமைத்து, பின்னர் புதிய தொகுதி உறுப்பை மரத்தின் விரும்பிய இடத்தில் சேர்க்க appendChild ஐப் பயன்படுத்தவும்.
அணுகல்தன்மை (Accessibility)
எப்போதெல்லாம் நீங்கள் ஒரு புதிய தொழில்நுட்பத்தைக் கற்றுக்கொள்கிறீர்களோ, அப்போது நீங்கள் கேட்க வேண்டும்: இது அணுகல்தன்மையை எவ்வாறு பாதிக்கிறது? ஜாவாஸ்கிரிப்ட் குறியீடு காட்டப்படும் DOM ஐ மாற்றுவதன் மூலம், ஒரு பக்கத்தின் உள்ளடக்கம் ஸ்கிரீன் ரீடரால் படிக்கப்பட்ட பிறகு மாற வாய்ப்புள்ளது. மற்றும் பார்வை கொண்ட ஒரு பயனர் மாற்றத்தை பார்வை மூலம் காண முடியும் என்றாலும், நீங்கள் சொல்லாத வரை பக்கத்தில் ஏதோ வித்தியாசமாக இருப்பதை அறிய ஸ்கிரீன் ரீடருக்கு எந்த வழியும் இல்லை.
ஒரு உறுப்பை ARIA லைவ் பிராந்தியமாக (ARIA Live Region) மாற்றுவதன் மூலம், ஒரு பக்கத்தில் உள்ள ஒரு உறுப்பு எதிர்காலத்தில் அதன் உள்ளடக்கத்தை மாற்றக்கூடும் என்பதை ஸ்கிரீன் ரீடர்களுக்கு நீங்கள் தெரிவிக்கலாம். லைவ் பிராந்தியங்கள் உதவி தொழில்நுட்பங்களால் "கண்காணிக்கப்படுகின்றன", மேலும் உள்ளடக்கம் மாறும்போதெல்லாம் அவை புதிய உள்ளடக்கத்தை முதல் முறையாகப் படிப்பது போல வாசகரிடம் பேசும்.
aria-live பண்புக்கூறை வழங்குவதன் மூலம் ஒரு உறுப்பை லைவ் பிராந்தியமாக மாற்றுகிறீர்கள்:
<div aria-live="polite">இந்த உள்ளடக்கம் மாறலாம்!</div>
aria-live பண்புக்கூறுக்கு ஒதுக்கப்பட்ட மதிப்பு "கண்ணிய நிலை (politeness level)" ஆகும், இது ஸ்கிரீன் ரீடர் எந்த முன்னுரிமையுடன் மாற்றத்தைப் படிக்க வேண்டும் என்பதைக் குறிப்பிடுகிறது. மிகவும் பொதுவான விருப்பம் (நீங்கள் எப்போதும் பயன்படுத்த வேண்டியது) "polite", இது பயனர் தற்போது படிக்கும் எதையும் இடைநிறுத்திய (paused) பின்னரே மாற்றப்பட்ட உரை படிக்கப்படும் என்பதைக் குறிக்கிறது. ஒரு "polite" எச்சரிக்கையானது தற்போது படித்துக்கொண்டிருக்கும் உரை அல்லது விளக்கத்திற்கு இடையூறு விளைவிக்காது, ஆனால் ஒரு இடைவெளி ஏற்படும் போது உட்செலுத்தப்படும் (தற்போதைய வாசிப்பு அதிக நேரம் தொடர்ந்தால், புதிய உள்ளடக்கம் பேசப்படாது).
- மற்றொரு விருப்பம்
"assertive"ஆகும், இது புதிய உள்ளடக்கம் மாறியவுடன் பேசப்பட வேண்டும் என்பதைக் குறிக்கிறது, இது மற்ற உள்ளடக்கத்திற்கு இடையூறு விளைவிக்கலாம். முக்கியமான தகவல்களுக்கு (எச்சரிக்கைகள், விழிப்பூட்டல்கள் அல்லது பிழைகள் போன்றவை) மட்டுமே இது பயன்படுத்தப்பட வேண்டும், ஏனெனில் இது பயனரின் ஓட்டத்திற்கு மிகவும் திசைதிருப்பக்கூடிய வகையில் இடையூறு விளைவிக்கும். சுருக்கமாக: எப்பொழுதும் கண்ணியமாக இருங்கள்!