diff --git a/script.js b/script.js
index e929226..be04ea0 100644
--- a/script.js
+++ b/script.js
@@ -39,18 +39,18 @@ document.addEventListener("keydown", function (e) {
///////////////////////////////////////
// Button scrolling
btnScrollTo.addEventListener("click", function (e) {
- // const s1coords = section1.getBoundingClientRect();
- // console.log(s1coords);
+ const s1coords = section1.getBoundingClientRect();
+ console.log(s1coords);
- // console.log(e.target.getBoundingClientRect());
+ console.log(e.target.getBoundingClientRect());
- // console.log("Current scroll (X/Y)", window.pageXOffset, window.pageYOffset);
+ console.log("Current scroll (X/Y)", window.pageXOffset, window.pageYOffset);
- // console.log(
- // "height/width viewport",
- // document.documentElement.clientHeight,
- // document.documentElement.clientWidth
- // );
+ console.log(
+ "height/width viewport",
+ document.documentElement.clientHeight,
+ document.documentElement.clientWidth
+ );
// Scrolling
// window.scrollTo(
@@ -64,6 +64,446 @@ btnScrollTo.addEventListener("click", function (e) {
// behavior: 'smooth',
// });
- // Use this way only.
section1.scrollIntoView({ behavior: "smooth" });
});
+
+///////////////////////////////////////
+// Page navigation
+
+// document.querySelectorAll('.nav__link').forEach(function (el) {
+// el.addEventListener('click', function (e) {
+// e.preventDefault();
+// const id = this.getAttribute('href');
+// console.log(id);
+// document.querySelector(id).scrollIntoView({ behavior: 'smooth' });
+// });
+// });
+
+// 1. Add event listener to common parent element
+// 2. Determine what element originated the event
+
+document.querySelector(".nav__links").addEventListener("click", function (e) {
+ e.preventDefault();
+
+ // Matching strategy
+ if (e.target.classList.contains("nav__link")) {
+ const id = e.target.getAttribute("href");
+ document.querySelector(id).scrollIntoView({ behavior: "smooth" });
+ }
+});
+
+///////////////////////////////////////
+// Tabbed component
+
+tabsContainer.addEventListener("click", function (e) {
+ const clicked = e.target.closest(".operations__tab");
+
+ // Guard clause
+ if (!clicked) return;
+
+ // Remove active classes
+ tabs.forEach((t) => t.classList.remove("operations__tab--active"));
+ tabsContent.forEach((c) => c.classList.remove("operations__content--active"));
+
+ // Activate tab
+ clicked.classList.add("operations__tab--active");
+
+ // Activate content area
+ document
+ .querySelector(`.operations__content--${clicked.dataset.tab}`)
+ .classList.add("operations__content--active");
+});
+
+///////////////////////////////////////
+// Menu fade animation
+const handleHover = function (e) {
+ if (e.target.classList.contains("nav__link")) {
+ const link = e.target;
+ const siblings = link.closest(".nav").querySelectorAll(".nav__link");
+ const logo = link.closest(".nav").querySelector("img");
+
+ siblings.forEach((el) => {
+ if (el !== link) el.style.opacity = this;
+ });
+ logo.style.opacity = this;
+ }
+};
+
+// Passing "argument" into handler
+nav.addEventListener("mouseover", handleHover.bind(0.5));
+nav.addEventListener("mouseout", handleHover.bind(1));
+
+///////////////////////////////////////
+// Sticky navigation: Intersection Observer API
+
+const header = document.querySelector(".header");
+const navHeight = nav.getBoundingClientRect().height;
+
+const stickyNav = function (entries) {
+ const [entry] = entries;
+ // console.log(entry);
+
+ if (!entry.isIntersecting) nav.classList.add("sticky");
+ else nav.classList.remove("sticky");
+};
+
+const headerObserver = new IntersectionObserver(stickyNav, {
+ root: null,
+ threshold: 0,
+ rootMargin: `-${navHeight}px`,
+});
+
+headerObserver.observe(header);
+
+///////////////////////////////////////
+// Reveal sections
+const allSections = document.querySelectorAll(".section");
+
+const revealSection = function (entries, observer) {
+ const [entry] = entries;
+
+ if (!entry.isIntersecting) return;
+
+ entry.target.classList.remove("section--hidden");
+ observer.unobserve(entry.target);
+};
+
+const sectionObserver = new IntersectionObserver(revealSection, {
+ root: null,
+ threshold: 0.15,
+});
+
+allSections.forEach(function (section) {
+ sectionObserver.observe(section);
+ section.classList.add("section--hidden");
+});
+
+// Lazy loading images
+const imgTargets = document.querySelectorAll("img[data-src]");
+
+const loadImg = function (entries, observer) {
+ const [entry] = entries;
+
+ if (!entry.isIntersecting) return;
+
+ // Replace src with data-src
+ entry.target.src = entry.target.dataset.src;
+
+ entry.target.addEventListener("load", function () {
+ entry.target.classList.remove("lazy-img");
+ });
+
+ observer.unobserve(entry.target);
+};
+
+const imgObserver = new IntersectionObserver(loadImg, {
+ root: null,
+ threshold: 0,
+ rootMargin: "200px",
+});
+
+imgTargets.forEach((img) => imgObserver.observe(img));
+
+///////////////////////////////////////
+// Slider
+const slider = function () {
+ const slides = document.querySelectorAll(".slide");
+ const btnLeft = document.querySelector(".slider__btn--left");
+ const btnRight = document.querySelector(".slider__btn--right");
+ const dotContainer = document.querySelector(".dots");
+
+ let curSlide = 0;
+ const maxSlide = slides.length;
+
+ // Functions
+ const createDots = function () {
+ slides.forEach(function (_, i) {
+ dotContainer.insertAdjacentHTML(
+ "beforeend",
+ ``
+ );
+ });
+ };
+
+ const activateDot = function (slide) {
+ document
+ .querySelectorAll(".dots__dot")
+ .forEach((dot) => dot.classList.remove("dots__dot--active"));
+
+ document
+ .querySelector(`.dots__dot[data-slide="${slide}"]`)
+ .classList.add("dots__dot--active");
+ };
+
+ const goToSlide = function (slide) {
+ slides.forEach(
+ (s, i) => (s.style.transform = `translateX(${100 * (i - slide)}%)`)
+ );
+ };
+
+ // Next slide
+ const nextSlide = function () {
+ if (curSlide === maxSlide - 1) {
+ curSlide = 0;
+ } else {
+ curSlide++;
+ }
+
+ goToSlide(curSlide);
+ activateDot(curSlide);
+ };
+
+ const prevSlide = function () {
+ if (curSlide === 0) {
+ curSlide = maxSlide - 1;
+ } else {
+ curSlide--;
+ }
+ goToSlide(curSlide);
+ activateDot(curSlide);
+ };
+
+ const init = function () {
+ goToSlide(0);
+ createDots();
+
+ activateDot(0);
+ };
+ init();
+
+ // Event handlers
+ btnRight.addEventListener("click", nextSlide);
+ btnLeft.addEventListener("click", prevSlide);
+
+ document.addEventListener("keydown", function (e) {
+ if (e.key === "ArrowLeft") prevSlide();
+ e.key === "ArrowRight" && nextSlide();
+ });
+
+ dotContainer.addEventListener("click", function (e) {
+ if (e.target.classList.contains("dots__dot")) {
+ const { slide } = e.target.dataset;
+ goToSlide(slide);
+ activateDot(slide);
+ }
+ });
+};
+slider();
+
+///////////////////////////////////////
+///////////////////////////////////////
+///////////////////////////////////////
+
+/*
+///////////////////////////////////////
+// Selecting, Creating, and Deleting Elements
+
+// Selecting elements
+console.log(document.documentElement);
+console.log(document.head);
+console.log(document.body);
+
+const header = document.querySelector('.header');
+const allSections = document.querySelectorAll('.section');
+console.log(allSections);
+
+document.getElementById('section--1');
+const allButtons = document.getElementsByTagName('button');
+console.log(allButtons);
+
+console.log(document.getElementsByClassName('btn'));
+
+// Creating and inserting elements
+const message = document.createElement('div');
+message.classList.add('cookie-message');
+// message.textContent = 'We use cookied for improved functionality and analytics.';
+message.innerHTML =
+ 'We use cookied for improved functionality and analytics. ';
+
+// header.prepend(message);
+header.append(message);
+// header.append(message.cloneNode(true));
+
+// header.before(message);
+// header.after(message);
+
+// Delete elements
+document
+ .querySelector('.btn--close-cookie')
+ .addEventListener('click', function () {
+ // message.remove();
+ message.parentElement.removeChild(message);
+ });
+
+
+///////////////////////////////////////
+// Styles, Attributes and Classes
+
+// Styles
+message.style.backgroundColor = '#37383d';
+message.style.width = '120%';
+
+console.log(message.style.color);
+console.log(message.style.backgroundColor);
+
+console.log(getComputedStyle(message).color);
+console.log(getComputedStyle(message).height);
+
+message.style.height =
+ Number.parseFloat(getComputedStyle(message).height, 10) + 30 + 'px';
+
+document.documentElement.style.setProperty('--color-primary', 'orangered');
+
+// Attributes
+const logo = document.querySelector('.nav__logo');
+console.log(logo.alt);
+console.log(logo.className);
+
+logo.alt = 'Beautiful minimalist logo';
+
+// Non-standard
+console.log(logo.designer);
+console.log(logo.getAttribute('designer'));
+logo.setAttribute('company', 'Bankist');
+
+console.log(logo.src);
+console.log(logo.getAttribute('src'));
+
+const link = document.querySelector('.nav__link--btn');
+console.log(link.href);
+console.log(link.getAttribute('href'));
+
+// Data attributes
+console.log(logo.dataset.versionNumber);
+
+// Classes
+logo.classList.add('c', 'j');
+logo.classList.remove('c', 'j');
+logo.classList.toggle('c');
+logo.classList.contains('c'); // not includes
+
+// Don't use
+logo.clasName = 'jonas';
+
+
+///////////////////////////////////////
+// Types of Events and Event Handlers
+const h1 = document.querySelector('h1');
+
+const alertH1 = function (e) {
+ alert('addEventListener: Great! You are reading the heading :D');
+};
+
+h1.addEventListener('mouseenter', alertH1);
+
+setTimeout(() => h1.removeEventListener('mouseenter', alertH1), 3000);
+
+// h1.onmouseenter = function (e) {
+// alert('onmouseenter: Great! You are reading the heading :D');
+// };
+
+
+///////////////////////////////////////
+// Event Propagation in Practice
+const randomInt = (min, max) =>
+ Math.floor(Math.random() * (max - min + 1) + min);
+const randomColor = () =>
+ `rgb(${randomInt(0, 255)},${randomInt(0, 255)},${randomInt(0, 255)})`;
+
+document.querySelector('.nav__link').addEventListener('click', function (e) {
+ this.style.backgroundColor = randomColor();
+ console.log('LINK', e.target, e.currentTarget);
+ console.log(e.currentTarget === this);
+
+ // Stop propagation
+ // e.stopPropagation();
+});
+
+document.querySelector('.nav__links').addEventListener('click', function (e) {
+ this.style.backgroundColor = randomColor();
+ console.log('CONTAINER', e.target, e.currentTarget);
+});
+
+document.querySelector('.nav').addEventListener('click', function (e) {
+ this.style.backgroundColor = randomColor();
+ console.log('NAV', e.target, e.currentTarget);
+});
+
+
+///////////////////////////////////////
+// DOM Traversing
+const h1 = document.querySelector('h1');
+
+// Going downwards: child
+console.log(h1.querySelectorAll('.highlight'));
+console.log(h1.childNodes);
+console.log(h1.children);
+h1.firstElementChild.style.color = 'white';
+h1.lastElementChild.style.color = 'orangered';
+
+// Going upwards: parents
+console.log(h1.parentNode);
+console.log(h1.parentElement);
+
+h1.closest('.header').style.background = 'var(--gradient-secondary)';
+
+h1.closest('h1').style.background = 'var(--gradient-primary)';
+
+// Going sideways: siblings
+console.log(h1.previousElementSibling);
+console.log(h1.nextElementSibling);
+
+console.log(h1.previousSibling);
+console.log(h1.nextSibling);
+
+console.log(h1.parentElement.children);
+[...h1.parentElement.children].forEach(function (el) {
+ if (el !== h1) el.style.transform = 'scale(0.5)';
+});
+
+///////////////////////////////////////
+// Sticky navigation
+const initialCoords = section1.getBoundingClientRect();
+console.log(initialCoords);
+
+window.addEventListener('scroll', function () {
+ console.log(window.scrollY);
+
+ if (window.scrollY > initialCoords.top) nav.classList.add('sticky');
+ else nav.classList.remove('sticky');
+});
+
+///////////////////////////////////////
+// Sticky navigation: Intersection Observer API
+
+const obsCallback = function (entries, observer) {
+ entries.forEach(entry => {
+ console.log(entry);
+ });
+};
+
+const obsOptions = {
+ root: null,
+ threshold: [0, 0.2],
+};
+
+const observer = new IntersectionObserver(obsCallback, obsOptions);
+observer.observe(section1);
+
+
+///////////////////////////////////////
+// Lifecycle DOM Events
+document.addEventListener('DOMContentLoaded', function (e) {
+ console.log('HTML parsed and DOM tree built!', e);
+});
+
+window.addEventListener('load', function (e) {
+ console.log('Page fully loaded', e);
+});
+
+window.addEventListener('beforeunload', function (e) {
+ e.preventDefault();
+ console.log(e);
+ e.returnValue = '';
+});
+*/