Näita sildipilve

Kas DOM’is midagi muutus?

How to detect changes in the DOM?

Kirjutas ,

Viimasel ajal on ringlema hakanud väga huvitav meetod, kuidas tuvastada, kas veebilehel midagi Javascriptiga lisati või eemaldati. Ehk kuidas tuvastada DOM-is muudatusi?

Hetkel on kõige levinumad kaks meetodit:

  • kontrollime teatud intervalli tagant, kas mõnes meile huvi pakkuvas elemendis midagi muutus (näiteks kas selle tütarelementide arv muutus),
  • lisame näiteks klikk sündmusele täiendava skripti, mis käivitab omakorda mõne teise skripti (näiteks kuvab teate, et lisamine õnnestus vmt).

Esimene nimetatuist on üks ressursinõudlikumaid (eriti veel, kui selliseid intervalle on palju). Intervall on püsiv ja suurema osa ajast ta töötab niisama.

Aga mis on siis parem meetod?

Levima on hakanud meetod, kus kasutatakse CSS3 ja Javascripti kombinatsiooni. Nimelt defineeritakse animatsioon ja animatsioon määratakse elemendile, mille lisamist või eemaldamist me soovime tuvastada. Javascripti on lisatud sündmused, mille abil me saame teada, et mingi animatsioon käivitus. Kuna igale animatsioonile antakse nimi, siis saamegi tekitada nn globaalse tuvastaja, mis jälgib, et kui animatsioon X käivitub, siis käivitatakse skript Y.

Nagu eelpool juba nimetatud, siis see meetod eeldab: CSS3 ja Javascripti.

CSS

@-moz-keyframes dom {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}
@-webkit-keyframes dom {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}
@-ms-keyframes dom {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }
}
@keyframes dom {  
	from { clip: rect(1px, auto, auto, auto); }
	to { clip: rect(0px, auto, auto, auto); }  
}
#test .item {
	-moz-animation-duration: 0.001s;
	-webkit-animation-duration: 0.001s;
	-ms-animation-duration: 0.001s;
	animation-duration: 0.001s;     
	-moz-animation-name: dom;
	-webkit-animation-name: dom;
	-ms-animation-name: dom;
	animation-name: dom;
}

Javascript

jQuery(function($) {
	var dom = function(e){
		if (e.animationName == "dom") {
			console.log("DOM muutus");
		}
	};

	document.addEventListener("MSAnimationStart", dom, false);
	document.addEventListener("webkitAnimationStart", dom, false);
	document.addEventListener("animationstart", dom, false);

	$(document).click(function() {
		$('#test').append(
			$('<li class="item">' + ( Math.random() * 100 ) + '</li>')
				.click(function() {
					$(this).remove();
				})
			);
		});
	});

HTML

<ul id="test">
	<li class="item">test</li>
</ul>

Kui kõik õnnestus, siis peaks juhtuma järgmist. Iga kord kui lisatakse või eemaldatakse .item element, kuvatakse console aknasse teade “DOM muutus”.

Miks see meetod on nii võluv?

Selle meetodi võlu seisneb selles, et rakendatud javascripti sündmust “animationstart” ja CSS3 reeglit “keyframes“. Nende kahe kombineerimisel tekib olukord, kus iga keyframe rakendamisel käivitub sündmus animationstart. See võimaldab globaalselt jälgida, kas midagi toimus ja mis täpsemalt toimus (ehk käivita skript ainult siis, kui tõesti midagi eemaldati või lisati). Kaob ära vajadus ressursinõudlike meetodite järele. Muidugi tuleb siinkohas ära märkida, et see meetod töötab vaid uuemates veebilehitsejates. Ehk nendes, mis sisaldavad CSS3 Animations moodulit ja DOM AnimationEvent objekti.

Allikas