You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/el/3-terrarium/3-intro-to-DOM-and-closures/README.md

23 KiB

Έργο Terrarium Μέρος 3: Χειρισμός DOM και Κλείσιμο

DOM και κλείσιμο

Σκίτσο από Tomomi Imura

Ερωτηματολόγιο πριν το μάθημα

Ερωτηματολόγιο πριν το μάθημα

Εισαγωγή

Ο χειρισμός του DOM, ή "Document Object Model", είναι ένα βασικό στοιχείο της ανάπτυξης ιστοσελίδων. Σύμφωνα με το MDN, "Το Document Object Model (DOM) είναι η αναπαράσταση δεδομένων των αντικειμένων που αποτελούν τη δομή και το περιεχόμενο ενός εγγράφου στον ιστό." Οι προκλήσεις γύρω από τον χειρισμό του DOM στον ιστό συχνά αποτέλεσαν την αιτία για τη χρήση JavaScript frameworks αντί για απλή JavaScript για τη διαχείριση του DOM, αλλά εμείς θα τα καταφέρουμε μόνοι μας!

Επιπλέον, αυτό το μάθημα θα εισαγάγει την ιδέα ενός κλεισίματος JavaScript, το οποίο μπορείτε να σκεφτείτε ως μια συνάρτηση που περικλείεται από μια άλλη συνάρτηση, ώστε η εσωτερική συνάρτηση να έχει πρόσβαση στο scope της εξωτερικής συνάρτησης.

Τα κλεισίματα JavaScript είναι ένα ευρύ και πολύπλοκο θέμα. Αυτό το μάθημα αγγίζει την πιο βασική ιδέα ότι στον κώδικα του terrarium, θα βρείτε ένα κλείσιμο: μια εσωτερική συνάρτηση και μια εξωτερική συνάρτηση κατασκευασμένες με τρόπο που επιτρέπει στην εσωτερική συνάρτηση να έχει πρόσβαση στο scope της εξωτερικής συνάρτησης. Για περισσότερες πληροφορίες σχετικά με το πώς λειτουργεί αυτό, επισκεφθείτε την εκτενή τεκμηρίωση.

Θα χρησιμοποιήσουμε ένα κλείσιμο για να χειριστούμε το DOM.

Σκεφτείτε το DOM ως ένα δέντρο, που αναπαριστά όλους τους τρόπους με τους οποίους μπορεί να χειριστεί ένα έγγραφο ιστοσελίδας. Διάφορα APIs (Διεπαφές Προγραμματισμού Εφαρμογών) έχουν γραφτεί ώστε οι προγραμματιστές, χρησιμοποιώντας τη γλώσσα προγραμματισμού της επιλογής τους, να μπορούν να έχουν πρόσβαση στο DOM και να το επεξεργάζονται, να το αλλάζουν, να το αναδιατάσσουν και να το διαχειρίζονται με άλλους τρόπους.

Αναπαράσταση δέντρου DOM

Μια αναπαράσταση του DOM και της HTML σήμανσης που το αναφέρεται. Από Olfa Nasraoui

Σε αυτό το μάθημα, θα ολοκληρώσουμε το διαδραστικό έργο terrarium δημιουργώντας τη JavaScript που θα επιτρέπει στον χρήστη να χειρίζεται τα φυτά στη σελίδα.

Προαπαιτούμενο

Θα πρέπει να έχετε δημιουργήσει το HTML και το CSS για το terrarium σας. Μέχρι το τέλος αυτού του μαθήματος θα μπορείτε να μετακινείτε τα φυτά μέσα και έξω από το terrarium με τη μέθοδο drag-and-drop.

Εργασία

Στον φάκελο του terrarium σας, δημιουργήστε ένα νέο αρχείο με όνομα script.js. Εισάγετε αυτό το αρχείο στην ενότητα <head>:

	<script src="./script.js" defer></script>

Σημείωση: χρησιμοποιήστε defer όταν εισάγετε ένα εξωτερικό αρχείο JavaScript στο αρχείο HTML, ώστε να επιτρέψετε στη JavaScript να εκτελεστεί μόνο αφού το αρχείο HTML έχει φορτωθεί πλήρως. Μπορείτε επίσης να χρησιμοποιήσετε το χαρακτηριστικό async, το οποίο επιτρέπει στο script να εκτελείται ενώ το αρχείο HTML αναλύεται, αλλά στη δική μας περίπτωση, είναι σημαντικό να είναι πλήρως διαθέσιμα τα στοιχεία HTML για το drag πριν εκτελεστεί το script drag.


Τα στοιχεία του DOM

Το πρώτο πράγμα που πρέπει να κάνετε είναι να δημιουργήσετε αναφορές στα στοιχεία που θέλετε να χειριστείτε στο DOM. Στην περίπτωσή μας, είναι τα 14 φυτά που περιμένουν στις πλευρικές μπάρες.

Εργασία

dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));

Τι συμβαίνει εδώ; Αναφέρεστε στο έγγραφο και ψάχνετε στο DOM του για να βρείτε ένα στοιχείο με συγκεκριμένο Id. Θυμηθείτε στο πρώτο μάθημα για το HTML ότι δώσατε μοναδικά Ids σε κάθε εικόνα φυτού (id="plant1"); Τώρα θα αξιοποιήσετε αυτή την προσπάθεια. Αφού εντοπίσετε κάθε στοιχείο, το περνάτε σε μια συνάρτηση που ονομάζεται dragElement, την οποία θα δημιουργήσετε σε λίγο. Έτσι, το στοιχείο στο HTML είναι πλέον έτοιμο για drag, ή θα είναι σύντομα.

Γιατί αναφερόμαστε στα στοιχεία με Id; Γιατί όχι με την CSS class τους; Μπορείτε να ανατρέξετε στο προηγούμενο μάθημα για το CSS για να απαντήσετε σε αυτή την ερώτηση.


Το Κλείσιμο

Τώρα είστε έτοιμοι να δημιουργήσετε το κλείσιμο dragElement, το οποίο είναι μια εξωτερική συνάρτηση που περικλείει μια εσωτερική συνάρτηση ή συναρτήσεις (στην περίπτωσή μας, θα έχουμε τρεις).

Τα κλεισίματα είναι χρήσιμα όταν μία ή περισσότερες συναρτήσεις χρειάζονται πρόσβαση στο scope της εξωτερικής συνάρτησης. Δείτε ένα παράδειγμα:

function displayCandy(){
	let candy = ['jellybeans'];
	function addCandy(candyType) {
		candy.push(candyType)
	}
	addCandy('gumdrops');
}
displayCandy();
console.log(candy)

Σε αυτό το παράδειγμα, η συνάρτηση displayCandy περιβάλλει μια συνάρτηση που προσθέτει έναν νέο τύπο καραμέλας σε έναν πίνακα που ήδη υπάρχει στη συνάρτηση. Αν εκτελέσετε αυτόν τον κώδικα, ο πίνακας candy θα είναι undefined, καθώς είναι μια τοπική μεταβλητή (τοπική στο κλείσιμο).

Πώς μπορείτε να κάνετε τον πίνακα candy προσβάσιμο; Δοκιμάστε να τον μετακινήσετε έξω από το κλείσιμο. Με αυτόν τον τρόπο, ο πίνακας γίνεται global, αντί να παραμένει διαθέσιμος μόνο στο τοπικό scope του κλεισίματος.

Εργασία

Κάτω από τις δηλώσεις στοιχείων στο script.js, δημιουργήστε μια συνάρτηση:

function dragElement(terrariumElement) {
	//set 4 positions for positioning on the screen
	let pos1 = 0,
		pos2 = 0,
		pos3 = 0,
		pos4 = 0;
	terrariumElement.onpointerdown = pointerDrag;
}

Η dragElement λαμβάνει το αντικείμενο terrariumElement από τις δηλώσεις στην κορυφή του script. Στη συνέχεια, ορίζετε κάποιες τοπικές θέσεις στο 0 για το αντικείμενο που περνάτε στη συνάρτηση. Αυτές είναι οι τοπικές μεταβλητές που θα χειριστούν για κάθε στοιχείο καθώς προσθέτετε λειτουργικότητα drag-and-drop σε κάθε στοιχείο μέσα στο κλείσιμο. Το terrarium θα γεμίσει από αυτά τα στοιχεία που σύρονται, οπότε η εφαρμογή πρέπει να παρακολουθεί πού τοποθετούνται.

Επιπλέον, το terrariumElement που περνάτε σε αυτή τη συνάρτηση ανατίθεται σε ένα γεγονός pointerdown, το οποίο είναι μέρος των web APIs που έχουν σχεδιαστεί για να βοηθούν στη διαχείριση του DOM. Το onpointerdown ενεργοποιείται όταν πατηθεί ένα κουμπί ή, στην περίπτωσή μας, όταν αγγιχθεί ένα στοιχείο που μπορεί να σύρεται. Αυτός ο χειριστής γεγονότων λειτουργεί τόσο σε web όσο και σε mobile browsers, με λίγες εξαιρέσεις.

Το event handler onclick έχει πολύ μεγαλύτερη υποστήριξη σε διάφορους browsers. Γιατί δεν το χρησιμοποιείτε εδώ; Σκεφτείτε τον ακριβή τύπο αλληλεπίδρασης που προσπαθείτε να δημιουργήσετε εδώ.


Η συνάρτηση Pointerdrag

Το terrariumElement είναι έτοιμο να σύρεται γύρω. Όταν ενεργοποιηθεί το γεγονός onpointerdown, καλείται η συνάρτηση pointerDrag. Προσθέστε αυτή τη συνάρτηση ακριβώς κάτω από αυτή τη γραμμή: terrariumElement.onpointerdown = pointerDrag;:

Εργασία

function pointerDrag(e) {
	e.preventDefault();
	console.log(e);
	pos3 = e.clientX;
	pos4 = e.clientY;
}

Συμβαίνουν αρκετά πράγματα. Πρώτον, αποτρέπετε τα προεπιλεγμένα γεγονότα που συμβαίνουν συνήθως στο pointerdown χρησιμοποιώντας e.preventDefault();. Με αυτόν τον τρόπο έχετε μεγαλύτερο έλεγχο στη συμπεριφορά της διεπαφής.

Επιστρέψτε σε αυτή τη γραμμή όταν έχετε ολοκληρώσει το αρχείο script και δοκιμάστε το χωρίς το e.preventDefault() - τι συμβαίνει;

Δεύτερον, ανοίξτε το index.html σε ένα παράθυρο browser και επιθεωρήστε τη διεπαφή. Όταν κάνετε κλικ σε ένα φυτό, μπορείτε να δείτε πώς καταγράφεται το γεγονός 'e'. Εξετάστε το γεγονός για να δείτε πόσες πληροφορίες συλλέγονται από ένα pointer down γεγονός!

Στη συνέχεια, σημειώστε πώς οι τοπικές μεταβλητές pos3 και pos4 ορίζονται στο e.clientX. Μπορείτε να βρείτε τις τιμές e στο παράθυρο επιθεώρησης. Αυτές οι τιμές καταγράφουν τις συντεταγμένες x και y του φυτού τη στιγμή που κάνετε κλικ ή το αγγίζετε. Θα χρειαστείτε λεπτομερή έλεγχο της συμπεριφοράς των φυτών καθώς τα κάνετε κλικ και τα σύρετε, οπότε παρακολουθείτε τις συντεταγμένες τους.

Γίνεται πιο σαφές γιατί όλη αυτή η εφαρμογή είναι χτισμένη με ένα μεγάλο κλείσιμο; Αν δεν ήταν, πώς θα διατηρούσατε το scope για καθένα από τα 14 φυτά που μπορούν να σύρονται;

Ολοκληρώστε την αρχική συνάρτηση προσθέτοντας δύο ακόμη χειρισμούς γεγονότων pointer κάτω από το pos4 = e.clientY:

document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;

Τώρα υποδεικνύετε ότι θέλετε το φυτό να σύρεται μαζί με τον δείκτη καθώς το μετακινείτε, και η χειρονομία σύρσης να σταματά όταν αποεπιλέγετε το φυτό. Τα onpointermove και onpointerup είναι όλα μέρη του ίδιου API όπως το onpointerdown. Η διεπαφή θα εμφανίσει σφάλματα τώρα καθώς δεν έχετε ακόμη ορίσει τις συναρτήσεις elementDrag και stopElementDrag, οπότε δημιουργήστε τις στη συνέχεια.

Οι συναρτήσεις elementDrag και stopElementDrag

Θα ολοκληρώσετε το κλείσιμό σας προσθέτοντας δύο ακόμη εσωτερικές συναρτήσεις που θα χειρίζονται τι συμβαίνει όταν σύρετε ένα φυτό και όταν σταματάτε να το σύρετε. Η συμπεριφορά που θέλετε είναι να μπορείτε να σύρετε οποιοδήποτε φυτό οποιαδήποτε στιγμή και να το τοποθετείτε οπουδήποτε στην οθόνη. Αυτή η διεπαφή είναι αρκετά ευέλικτη (δεν υπάρχει ζώνη πτώσης, για παράδειγμα) ώστε να σας επιτρέπει να σχεδιάσετε το terrarium σας ακριβώς όπως θέλετε προσθέτοντας, αφαιρώντας και επανατοποθετώντας φυτά.

Εργασία

Προσθέστε τη συνάρτηση elementDrag ακριβώς μετά την κλείσιμο της αγκύλης του pointerDrag:

function elementDrag(e) {
	pos1 = pos3 - e.clientX;
	pos2 = pos4 - e.clientY;
	pos3 = e.clientX;
	pos4 = e.clientY;
	console.log(pos1, pos2, pos3, pos4);
	terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
	terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}

Σε αυτή τη συνάρτηση, κάνετε πολλές επεξεργασίες των αρχικών θέσεων 1-4 που ορίσατε ως τοπικές μεταβλητές στην εξωτερική συνάρτηση. Τι συμβαίνει εδώ;

Καθώς σύρετε, επαναπροσδιορίζετε το pos1 κάνοντάς το ίσο με το pos3 (το οποίο ορίσατε νωρίτερα ως e.clientX) μείον την τρέχουσα τιμή e.clientX. Κάνετε μια παρόμοια λειτουργία στο pos2. Στη συνέχεια, επαναπροσδιορίζετε το pos3 και το pos4 στις νέες συντεταγμένες X και Y του στοιχείου. Μπορείτε να παρακολουθήσετε αυτές τις αλλαγές στην κονσόλα καθώς σύρετε. Στη συνέχεια, χειρίζεστε το css style του φυτού για να ορίσετε τη νέα του θέση βάσει των νέων θέσεων του pos1 και pos2, υπολογίζοντας τις συντεταγμένες X και Y του φυτού βάσει της σύγκρισης της μετατόπισής του με αυτές τις νέες θέσεις.

Τα offsetTop και offsetLeft είναι ιδιότητες CSS που ορίζουν τη θέση ενός στοιχείου βάσει αυτής του γονέα του. Ο γονέας του μπορεί να είναι οποιοδήποτε στοιχείο που δεν έχει θέση static.

Όλη αυτή η επαναπροσδιορισμός θέσης σας επιτρέπει να ρυθμίσετε τη συμπεριφορά του terrarium και των φυτών του.

Εργασία

Η τελική εργασία για την ολοκλήρωση της διεπαφής είναι να προσθέσετε τη συνάρτηση stopElementDrag μετά την κλείσιμο της αγκύλης του elementDrag:

function stopElementDrag() {
	document.onpointerup = null;
	document.onpointermove = null;
}

Αυτή η μικρή συνάρτηση επαναφέρει τα γεγονότα onpointerup και onpointermove, ώστε να μπορείτε είτε να επανεκκινήσετε την πρόοδο του φυτού σας ξεκινώντας να το σύρετε ξανά, είτε να ξεκινήσετε να σύρετε ένα νέο φυτό.

Τι συμβαίνει αν δεν ορίσετε αυτά τα γεγονότα σε null;

Τώρα έχετε ολοκληρώσει το έργο σας!

🥇Συγχαρητήρια! Ολοκληρώσατε το όμορφο terrarium σας. τελικό terrarium


🚀Πρόκληση

Προσθέστε έναν νέο χειριστή γεγονότων στο κλείσιμό σας για να κάνετε κάτι επιπλέον στα φυτά. Για παράδειγμα, κάντε διπλό κλικ σε ένα φυτό για να το φέρετε μπροστά. Γίνετε δημιουργικοί!

Ερωτηματολόγιο μετά το μάθημα

Ερωτηματολόγιο μετά το μάθημα

Ανασκόπηση & Αυτομελέτη

Ενώ η μετακίνηση στοιχείων γύρω από την οθόνη φαίνεται απλή, υπάρχουν πολλοί τρόποι να το κάνετε και πολλές παγίδες, ανάλογα με το αποτέλεσμα που επιδιώκετε. Στην πραγματικότητα, υπάρχει ένα ολόκληρο drag and drop API που μπορείτε να δοκιμάσετε. Δεν το χρησιμοποιήσαμε σε αυτή τη μονάδα επειδή το αποτέλεσμα που θέλαμε ήταν κάπως διαφορετικό, αλλά δοκιμάστε αυτό το API στο δικό σας έργο και δείτε τι μπορείτε να πετύχετε.

Βρείτε περισσότερες πληροφορίες για τα pointer events στα έγγραφα W3C και στα έγγραφα MDN web.

Πάντα να ελέγχετε τις δυνατότητες των browsers χρησιμοποιώντας το CanIUse.com.

Εργασία

Δουλέψτε λίγο περισσότερο με το DOM


Αποποίηση ευθύνης:
Αυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης Co-op Translator. Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν σφάλματα ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.