Skip to content

Commit e301f63

Browse files
committed
Prototypes
1 parent 5d087ff commit e301f63

File tree

5 files changed

+346
-1
lines changed

5 files changed

+346
-1
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
function Gallery(gallery) {
2+
if (!gallery) {
3+
throw new Error('No Gallery Found!');
4+
}
5+
this.gallery = gallery;
6+
// select the elements we need
7+
this.images = Array.from(gallery.querySelectorAll('img'));
8+
this.modal = document.querySelector('.modal');
9+
this.prevButton = this.modal.querySelector('.prev');
10+
this.nextButton = this.modal.querySelector('.next');
11+
12+
// bind our methods to the instance when we need them
13+
this.showNextImage = this.showNextImage.bind(this);
14+
this.showPrevImage = this.showPrevImage.bind(this);
15+
this.handleKeyUp = this.handleKeyUp.bind(this);
16+
this.handleClickOutside = this.handleClickOutside.bind(this);
17+
18+
// These are our Event Listeners!
19+
this.images.forEach(image =>
20+
image.addEventListener('click', e => this.showImage(e.currentTarget))
21+
);
22+
23+
// loop over each image
24+
this.images.forEach(image => {
25+
// attach an event listener for each image
26+
image.addEventListener('keyup', e => {
27+
// when that is keyup'd, check if it was enter
28+
if (e.key === 'Enter') {
29+
// if it was, show that image
30+
this.showImage(e.currentTarget);
31+
}
32+
});
33+
});
34+
35+
this.modal.addEventListener('click', this.handleClickOutside);
36+
}
37+
38+
Gallery.prototype.openModal = function() {
39+
console.info('Opening Modal...');
40+
// First check if the modal is already open
41+
if (this.modal.matches('.open')) {
42+
console.info('Madal already open');
43+
return; // stop the function from running
44+
}
45+
this.modal.classList.add('open');
46+
47+
// Event listeners to be bound when we open the modal:
48+
window.addEventListener('keyup', this.handleKeyUp);
49+
this.nextButton.addEventListener('click', this.showNextImage);
50+
this.prevButton.addEventListener('click', this.showPrevImage);
51+
};
52+
53+
Gallery.prototype.closeModal = function() {
54+
this.modal.classList.remove('open');
55+
// TODO: add event listeners for clicks and keyboard..
56+
window.removeEventListener('keyup', this.handleKeyUp);
57+
this.nextButton.removeEventListener('click', this.showNextImage);
58+
this.prevButton.removeEventListener('click', this.showPrevImage);
59+
};
60+
61+
Gallery.prototype.handleClickOutside = function(e) {
62+
if (e.target === e.currentTarget) {
63+
this.closeModal();
64+
}
65+
};
66+
67+
Gallery.prototype.handleKeyUp = function(event) {
68+
if (event.key === 'Escape') return this.closeModal();
69+
if (event.key === 'ArrowRight') return this.showNextImage();
70+
if (event.key === 'ArrowLeft') return this.showPrevImage();
71+
};
72+
73+
Gallery.prototype.showNextImage = function() {
74+
console.log('SHOWING NEXT IMAGE!!!');
75+
this.showImage(
76+
this.currentImage.nextElementSibling || this.gallery.firstElementChild
77+
);
78+
};
79+
Gallery.prototype.showPrevImage = function() {
80+
this.showImage(
81+
this.currentImage.previousElementSibling || this.gallery.lastElementChild
82+
);
83+
};
84+
85+
Gallery.prototype.showImage = function(el) {
86+
if (!el) {
87+
console.info('no image to show');
88+
return;
89+
}
90+
// update the modal with this info
91+
console.log(el);
92+
this.modal.querySelector('img').src = el.src;
93+
this.modal.querySelector('h2').textContent = el.title;
94+
this.modal.querySelector('figure p').textContent = el.dataset.description;
95+
this.currentImage = el;
96+
this.openModal();
97+
};
98+
99+
// Use it on the page
100+
101+
const gallery1 = new Gallery(document.querySelector('.gallery1'));
102+
const gallery2 = new Gallery(document.querySelector('.gallery2'));
103+
104+
console.log(gallery1, gallery2);

exercises/56 - Gallery/gallery.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
function Gallery(gallery) {
2+
if (!gallery) {
3+
throw new Error('No Gallery Found!');
4+
}
5+
// select the elements we need
6+
const images = Array.from(gallery.querySelectorAll('img'));
7+
const modal = document.querySelector('.modal');
8+
const prevButton = modal.querySelector('.prev');
9+
const nextButton = modal.querySelector('.next');
10+
let currentImage;
11+
12+
function openModal() {
13+
console.info('Opening Modal...');
14+
// First check if the modal is already open
15+
if (modal.matches('.open')) {
16+
console.info('Madal already open');
17+
return; // stop the function from running
18+
}
19+
modal.classList.add('open');
20+
21+
// Event listeners to be bound when we open the modal:
22+
window.addEventListener('keyup', handleKeyUp);
23+
nextButton.addEventListener('click', showNextImage);
24+
prevButton.addEventListener('click', showPrevImage);
25+
}
26+
27+
function closeModal() {
28+
modal.classList.remove('open');
29+
// TODO: add event listeners for clicks and keyboard..
30+
window.removeEventListener('keyup', handleKeyUp);
31+
nextButton.removeEventListener('click', showNextImage);
32+
prevButton.removeEventListener('click', showPrevImage);
33+
}
34+
35+
function handleClickOutside(e) {
36+
if (e.target === e.currentTarget) {
37+
closeModal();
38+
}
39+
}
40+
41+
function handleKeyUp(event) {
42+
if (event.key === 'Escape') return closeModal();
43+
if (event.key === 'ArrowRight') return showNextImage();
44+
if (event.key === 'ArrowLeft') return showPrevImage();
45+
}
46+
47+
function showNextImage() {
48+
showImage(currentImage.nextElementSibling || gallery.firstElementChild);
49+
}
50+
function showPrevImage() {
51+
showImage(currentImage.previousElementSibling || gallery.lastElementChild);
52+
}
53+
54+
function showImage(el) {
55+
if (!el) {
56+
console.info('no image to show');
57+
return;
58+
}
59+
// update the modal with this info
60+
console.log(el);
61+
modal.querySelector('img').src = el.src;
62+
modal.querySelector('h2').textContent = el.title;
63+
modal.querySelector('figure p').textContent = el.dataset.description;
64+
currentImage = el;
65+
openModal();
66+
}
67+
68+
// These are our Event Listeners!
69+
images.forEach(image =>
70+
image.addEventListener('click', e => showImage(e.currentTarget))
71+
);
72+
73+
// loop over each image
74+
images.forEach(image => {
75+
// attach an event listener for each image
76+
image.addEventListener('keyup', e => {
77+
// when that is keyup'd, check if it was enter
78+
if (e.key === 'Enter') {
79+
// if it was, show that image
80+
showImage(e.currentTarget);
81+
}
82+
});
83+
});
84+
85+
modal.addEventListener('click', handleClickOutside);
86+
}
87+
88+
// Use it on the page
89+
90+
const gallery1 = Gallery(document.querySelector('.gallery1'));
91+
const gallery2 = Gallery(document.querySelector('.gallery2'));

exercises/56 - Gallery/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ <h2>Test Title</h2>
107107
</div>
108108
</div>
109109

110-
<script src="./gallery.js"></script>
110+
<script src="./gallery-prototype.js"></script>
111111

112112
</body>
113113

playground/classes.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
7+
<title>Classes</title>
8+
<link rel="stylesheet" href="../base.css">
9+
</head>
10+
11+
<body>
12+
<script>
13+
class Pizza {
14+
15+
// constructor
16+
constructor(toppings = [], customer) {
17+
// computer instance property
18+
this.toppings = toppings;
19+
this.customer = customer;
20+
}
21+
22+
// static property
23+
static toppings = ['pepperoni', 'cheese'];
24+
25+
// static method
26+
static randomPizza() {
27+
return new Pizza()
28+
}
29+
30+
// prototype method (almost always this)
31+
eat() {
32+
console.log('CHOMP');
33+
console.log(this.toppings);
34+
console.log(this.slices);
35+
}
36+
37+
// instance property
38+
slices = 10;
39+
40+
// instance method
41+
hi = () => {
42+
console.log('Hiiii');
43+
console.log(this);
44+
}
45+
46+
// Getter Property
47+
get length() {
48+
return this.slices;
49+
}
50+
51+
// Private Fields can only be modified inside a class
52+
#bankBalance = 10000;
53+
}
54+
55+
const myPizza = new Pizza(['onions'], 'Wes Bos');
56+
57+
console.log(myPizza);
58+
</script>
59+
</body>
60+
61+
</html>

playground/new-this.html

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
7+
<title>New, This, Prototypes and Classes</title>
8+
<link rel="stylesheet" href="../base.css">
9+
</head>
10+
11+
<body>
12+
<button class="one">Button 1</button>
13+
<button class="two">Button 2</button>
14+
<script>
15+
const myDate = new Date('August 11, 2025');
16+
console.dir(myDate);
17+
console.log(myDate.getFullYear());
18+
19+
const names = new Array('wes', 'kait');
20+
const wes = new Object({ name: 'wes' });
21+
const span = document.createElement('span');
22+
23+
String.prototype.sarcastic = function () {
24+
// make sarcastic
25+
return [...this].map((char, i) => char[`to${i % 2 ? 'Upper' : 'Lower'}Case`]()).join('');
26+
const sarcastic = this.split('').map((char, i) => {
27+
if (i % 2) {
28+
return char.toUpperCase();
29+
} else {
30+
return char.toLowerCase();
31+
}
32+
}).join('');
33+
return sarcastic;
34+
}
35+
function Pizza(toppings = [], customer) {
36+
console.log('Making a pizza');
37+
// save the toppings that were passed in, to this instance of pizza
38+
this.toppings = toppings;
39+
this.customer = customer;
40+
this.id = Math.floor(Math.random() * 16777215).toString(16);
41+
this.slices = 10;
42+
// this.eat = function () {
43+
// if (this.slices > 0) {
44+
// this.slices = this.slices - 1;
45+
// console.log(`CHOMP you now have ${this.slices} left!`);
46+
// } else {
47+
// console.log(`Sorry! No slices left!`);
48+
// }
49+
// }
50+
}
51+
52+
Pizza.prototype.eat = function () {
53+
if (this.slices > 0) {
54+
this.slices = this.slices - 1;
55+
console.log(`CHOMP you now have ${this.slices} left!`);
56+
} else {
57+
console.log(`Sorry! No slices left!`);
58+
}
59+
}
60+
61+
Pizza.prototype.describe = function () {
62+
return `This pizza is for ${this.customer} with the toppings ${this.toppings.join(',')} and there are ${this.slices} left!`;
63+
}
64+
65+
const pepperoniPizza = new Pizza(['pepperoni'], 'Wes Bos');
66+
const canadianPizza = new Pizza(['pepperoni', 'mushrooms', 'onion'], 'Kait Bos');
67+
68+
69+
// const button1 = document.querySelector('.one');
70+
// const button2 = document.querySelector('.two');
71+
72+
// function tellMeAboutTheButton() {
73+
// console.log('outside', this);
74+
// setTimeout(() => {
75+
// console.log('inside', this);
76+
// this.textContent = 'You Clicked Me';
77+
// }, 1000);
78+
// }
79+
80+
// button1.addEventListener('click', tellMeAboutTheButton);
81+
// button2.addEventListener('click', tellMeAboutTheButton);
82+
83+
84+
85+
86+
</script>
87+
</body>
88+
89+
</html>

0 commit comments

Comments
 (0)