refactor main.js into smaller pieces, and moved navbar.js to assets

This commit is contained in:
Aaron Qian 2022-11-10 23:23:50 -08:00 committed by Aaron Qian
parent fd8eeb3330
commit 177dffe553
No known key found for this signature in database
GPG key ID: BF1A987C395B5B0E
19 changed files with 214 additions and 207 deletions

View file

@ -2,3 +2,7 @@ import 'jquery';
import 'popper.js';
import 'bootstrap';
import '@fortawesome/fontawesome-free';
import './core';
import './features';
import './sections';

View file

@ -0,0 +1,36 @@
let deviceState = {
isMobile: false,
isTablet: false,
isLaptop: false,
};
function detectDeviceState() {
if (window.innerWidth <= 425) {
deviceState = {
isMobile: true,
isTablet: false,
isLaptop: false,
};
} else if (window.innerWidth <= 768) {
deviceState = {
isMobile: false,
isTablet: true,
isLaptop: false,
};
} else {
deviceState = {
isMobile: false,
isTablet: false,
isLaptop: true,
};
}
}
detectDeviceState();
window.addEventListener('resize', detectDeviceState);
// returns a copy of the device state
// so other parts of code can't override this.
export function getDeviceState() {
return { ... deviceState };
}

View file

@ -0,0 +1 @@
export * from './device';

View file

@ -0,0 +1,7 @@
if (process.env.FEATURE_VIDEOPLAYER) {
import('./videoplayer');
}
if (process.env.FEATURE_TOC) {
import('./toc');
}

View file

@ -0,0 +1,48 @@
import { getDeviceState } from '../../core';
// Toggle Table of Contents on click. Here, class "hide" open the toc
function toggleTOC() {
let toc = document.getElementById("toc-section");
if (toc == null) {
return
}
if (toc.classList.contains("hide")) {
toc.classList.remove("hide");
} else {
// if sidebar-section is open, then close it first
let sidebar = document.getElementById("sidebar-section");
if (sidebar != null && sidebar.classList.contains("hide")) {
sidebar.classList.remove("hide");
}
// add "hide" class
toc.classList.add("hide");
// if it is mobile device. then scroll to top.
const { isMobile } = getDeviceState();
if (isMobile && toc.classList.contains("hide")) {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
}
if (document.getElementById("hero-area") != null) {
document.getElementById("hero-area").classList.toggle("hide");
}
}
window.addEventListener('DOMContentLoaded', () => {
// bind click event to #toc-toggle in navbar-2.html
const $toggle = document.getElementById('toc-toggler');
if ($toggle) $toggle.addEventListener('click', toggleTOC);
// hide TOC when user clicks on a TOC link.
// Only applies if it's mobile.
const $toc = document.getElementById("TableOfContents");
if ($toc) {
$toc.addEventListener('click', (event) => {
const { isMobile } = getDeviceState();
if (isMobile && event.target.nodeName === 'A') {
toggleTOC();
}
});
}
});

View file

@ -0,0 +1,3 @@
if (process.env.FEATURE_VIDEOPLAYER_PLYR) {
import('./plyr');
}

View file

@ -0,0 +1,5 @@
import Plyr from 'plyr';
import { videoplayer } from '@params';
const { plyr: options } = videoplayer;
window.addEventListener('DOMContentLoaded', () => Plyr.setup('.js-player', options));

View file

@ -0,0 +1,34 @@
// Show more rows in the taken courses table
function toggleCourseVisibility(elem) {
// find the courses
let courses = elem.parentNode.getElementsByClassName("course");
if (courses == null) {
return
}
// toggle hidden-course class from the third elements
for (const course of courses) {
if (course.classList.contains("hidden-course") || course.classList.contains("toggled-hidden-course")) {
course.classList.toggle("hidden-course");
course.classList.add("toggled-hidden-course");
}
}
// toggle the buttons visibility
let buttonsToToggle = elem.parentNode.getElementsByClassName("show-more-btn");
for (const buttonToToggle of buttonsToToggle) {
buttonToToggle.classList.toggle("hidden");
}
}
window.addEventListener('DOMContentLoaded', () => {
const $els = [
document.getElementById('show-more-btn'),
document.getElementById('show-less-btn'),
];
$els.filter(($el) => $el != null).forEach(($el) =>
$el.addEventListener('click', ({target}) =>
toggleCourseVisibility(target)));
});

View file

@ -0,0 +1,4 @@
import './navbar';
import './sidebar';
import './education';

View file

@ -1,4 +1,4 @@
"use strict";
import $ from 'jquery';
const updateNavBar = () => {
if ($(document).scrollTop() > 40) {
@ -37,27 +37,25 @@ const updateNavBar = () => {
}
};
(function ($) {
jQuery(document).ready(function () {
// change navbar style on scroll
// ==================================================
// When the user scrolls down 80px from the top of the document, resize the navbar's padding and the logo's font size
// $.onscroll = function() {scrollFunction()};
$(document).scroll(function () {
updateNavBar();
});
// Creates a click handler to collapse the navigation when
// anchors in the mobile nav pop up are clicked
var navMain = $(".navbar-collapse");
if (navMain) {
navMain.on("click", "a", null, function (e) {
$('.navbar-collapse').collapse('hide');
});
}
$(document).ready(function () {
// change navbar style on scroll
// ==================================================
// When the user scrolls down 80px from the top of the document, resize the navbar's padding and the logo's font size
// $.onscroll = function() {scrollFunction()};
$(document).scroll(function () {
updateNavBar();
});
})(jQuery);
// Creates a click handler to collapse the navigation when
// anchors in the mobile nav pop up are clicked
var navMain = $(".navbar-collapse");
if (navMain) {
navMain.on("click", "a", null, function (e) {
$('.navbar-collapse').collapse('hide');
});
}
updateNavBar();
});

View file

@ -0,0 +1,39 @@
import { getDeviceState } from '../core/device';
// Toggle sidebar on click. Here, class "hide" open the sidebar
function toggleSidebar() {
let sidebar = document.getElementById("sidebar-section");
if (sidebar == null) {
return
}
if (sidebar.classList.contains("hide")) {
sidebar.classList.remove("hide")
} else {
// if toc-section is open, then close it first
let toc = document.getElementById("toc-section");
if (toc != null && toc.classList.contains("hide")) {
toc.classList.remove("hide");
}
// add "hide" class
sidebar.classList.add("hide");
// if it is mobile device. then scroll to top.
const { isMobile } = getDeviceState();
if (isMobile && sidebar.classList.contains("hide")) {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
if (document.getElementById("hero-area") != null) {
document.getElementById("hero-area").classList.toggle("hide");
}
}
}
if (document.getElementById("content-section") != null) {
document.getElementById("content-section").classList.toggle("hide");
}
}
window.addEventListener('DOMContentLoaded', () => {
// bind click event to #sidebar-toggler in navbar-2.html
const $toggle = document.getElementById('sidebar-toggler');
if ($toggle) $toggle.addEventListener('click', toggleSidebar);
});

View file

@ -179,7 +179,7 @@
{{ define "toc" }}
<section class="toc-section" id="toc-section">
{{ if and site.Params.enableTOC ( .Params.enableTOC | default true ) }}
{{ if and site.Params.features.toc.enable ( .Params.enableTOC | default true ) }}
<div class="toc-holder">
<h5 class="text-center pl-3">{{ i18n "toc_heading" }}</h5>
<hr>

View file

@ -29,7 +29,7 @@
<nav class="navbar navbar-expand-xl top-navbar final-navbar shadow">
<div class="container">
<button class="navbar-toggler navbar-light" id="sidebar-toggler" type="button" onclick="toggleSidebar()">
<button class="navbar-toggler navbar-light" id="sidebar-toggler" type="button">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="{{ site.BaseURL | relLangURL }}">
@ -38,7 +38,7 @@
{{ end }}
{{- site.Title -}}
</a>
<button class="navbar-toggler navbar-light" id="toc-toggler" type="button" onclick="toggleTOC()">
<button class="navbar-toggler navbar-light" id="toc-toggler" type="button">
<span class="navbar-toggler-icon"></span>
</button>

View file

@ -1,7 +1,4 @@
{{ partial "helpers/script-bundle.html" }}
<script type="text/javascript" src="{{ "/js/navbar.js" | relURL }}"></script>
<script type="text/javascript" src="{{ "/js/plyr.js" | relURL }}"></script>
<script type="text/javascript" src="{{ "/js/main.js" | relURL }}"></script>
{{ if site.Params.darkMode.enable }}
{{ if eq site.Params.darkMode.provider "darkreader" }}

View file

@ -90,9 +90,9 @@
{{ end }}
{{ if gt (len .takenCourses.courses) $collapseAfter }}
<button type="button" class="btn btn-link show-more-btn pt-0 {{ if .takenCourses.showGrades }}ml-1{{ else }}ml-2{{ end }}"
onclick="toggleCourseVisibility(this);" id="show-more-btn" aria-label="{{ i18n "show_more"}}">{{ i18n "show_more"}}</button>
id="show-more-btn" aria-label="{{ i18n "show_more"}}">{{ i18n "show_more"}}</button>
<button type="button" class="btn btn-link show-more-btn hidden pt-0 {{ if .takenCourses.showGrades }}ml-1{{ else }}ml-2{{ end }}"
onclick="toggleCourseVisibility(this);" id="show-less-btn" aria-label="{{ i18n "show_less"}}">{{ i18n "show_less"}}</button>
id="show-less-btn" aria-label="{{ i18n "show_less"}}">{{ i18n "show_less"}}</button>
{{ end }}
</div>
{{ end }}

View file

@ -90,9 +90,9 @@
{{ end }}
{{ if gt (len .takenCourses.courses ) $collapseAfter }}
<button type="button" class="btn btn-link show-more-btn pt-0 {{ if .takenCourses.showGrades }}ml-1{{ else }}ml-2{{ end }}"
onclick="toggleCourseVisibility(this);" id="show-more-btn">{{ i18n "show_more"}}</button>
id="show-more-btn">{{ i18n "show_more"}}</button>
<button type="button" class="btn btn-link show-more-btn hidden pt-0 {{ if .takenCourses.showGrades }}ml-1{{ else }}ml-2{{ end }}"
onclick="toggleCourseVisibility(this);" id="show-less-btn">{{ i18n "show_less"}}</button>
id="show-less-btn">{{ i18n "show_less"}}</button>
{{ end }}
</div>
{{ end }}

View file

@ -16,6 +16,13 @@ Yellow: #FFC212
body {
background-color: #f9fafc;
font-family: "Muli";
/*
Removed smooth scrolling implementation in main.js in favor of
simpler css approach.
See: https://css-tricks.com/snippets/jquery/smooth-scrolling/
*/
scroll-behavior: smooth;
}
h1,

View file

@ -1,173 +0,0 @@
"use strict";
var projectCards;
var isMobile = false, isTablet = false, isLaptop = false;
(function ($) {
jQuery(document).ready(function () {
function detectDevice() {
if (window.innerWidth <= 425) {
isMobile = true;
isTablet = false;
isLaptop = false;
} else if (window.innerWidth <= 768) {
isMobile = false;
isTablet = true;
isLaptop = false;
} else {
isMobile = false;
isTablet = false;
isLaptop = true;
}
}
detectDevice();
// ================= Smooth Scroll ===================
function addSmoothScroll() {
// ref: https://css-tricks.com/snippets/jquery/smooth-scrolling/
// Select all links with hashes
$('a[href*="#"]')
// Remove links that don't actually link to anything
.not('[href="#"]')
.not('[href="#0"]')
.click(function (event) {
// On-page links
if (
location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '')
&&
location.hostname == this.hostname
) {
// Figure out element to scroll to
var target = $(decodeURI(this.hash));
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
// Does a scroll target exist?
if (target.length) {
// Only prevent default if animation is actually gonna happen
event.preventDefault();
let offset = 60;
if (isMobile) {
offset = 710;
} else if (isTablet) {
offset = 60;
}
$('html, body').animate({
scrollTop: target.offset().top - offset
}, 1000, function () {
// Callback after animation
// Must change focus!
var $target = $(target);
$target.focus();
if ($target.is(":focus")) { // Checking if the target was focused
return false;
} else {
$target.attr('tabindex', '-1'); // Adding tabindex for elements not focusable
$target.focus(); // Set focus again
};
});
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = this.hash
}
}
});
}
addSmoothScroll();
// ===================== Video Player ==================
function renderVideoPlayer(){
var videos = document.getElementsByClassName("video-player");
for (var i =0; i< videos.length; i++ ){
const player = new Plyr("#"+videos[i].id);
}
}
renderVideoPlayer();
// re-render custom functions on window resize
window.onresize = function () {
detectDevice();
addSmoothScroll();
};
});
})(jQuery);
// Toggle sidebar on click. Here, class "hide" open the sidebar
function toggleSidebar() {
let sidebar = document.getElementById("sidebar-section");
if (sidebar == null) {
return
}
if (sidebar.classList.contains("hide")) {
sidebar.classList.remove("hide")
} else {
// if toc-section is open, then close it first
let toc = document.getElementById("toc-section");
if (toc != null && toc.classList.contains("hide")) {
toc.classList.remove("hide");
}
// add "hide" class
sidebar.classList.add("hide")
// if it is mobile device. then scroll to top.
if (isMobile && sidebar.classList.contains("hide")) {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
if (document.getElementById("hero-area") != null) {
document.getElementById("hero-area").classList.toggle("hide");
}
}
}
if (document.getElementById("content-section") != null) {
document.getElementById("content-section").classList.toggle("hide");
}
}
// Toggle Table of Contents on click. Here, class "hide" open the toc
function toggleTOC() {
let toc = document.getElementById("toc-section");
if (toc == null) {
return
}
if (toc.classList.contains("hide")) {
toc.classList.remove("hide");
} else {
// if sidebar-section is open, then close it first
let sidebar = document.getElementById("sidebar-section");
if (sidebar != null && sidebar.classList.contains("hide")) {
sidebar.classList.remove("hide");
}
// add "hide" class
toc.classList.add("hide")
// if it is mobile device. then scroll to top.
if (isMobile && toc.classList.contains("hide")) {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
}
if (document.getElementById("hero-area") != null) {
document.getElementById("hero-area").classList.toggle("hide");
}
}
// Show more rows in the taken courses table
function toggleCourseVisibility(elem) {
// find the courses
let courses = elem.parentNode.getElementsByClassName("course");
if (courses == null) {
return
}
// toggle hidden-course class from the third elements
for (const course of courses) {
if (course.classList.contains("hidden-course") || course.classList.contains("toggled-hidden-course")) {
course.classList.toggle("hidden-course");
course.classList.add("toggled-hidden-course");
}
}
// toggle the buttons visibility
let buttonsToToggle = elem.parentNode.getElementsByClassName("show-more-btn");
for (const buttonToToggle of buttonsToToggle) {
buttonToToggle.classList.toggle("hidden");
}
}

View file

@ -49,9 +49,6 @@ var isMobile = false, isTablet = false, isLaptop = false;
elems = toc.getElementsByTagName("li");
for (let i = 0; i < elems.length; i++) {
elems[i].classList.add("nav-item");
if (isMobile) {
elems[i].setAttribute("onclick", "toggleTOC()");
}
}
// add "nav-link" class to the "a" elements
elems = toc.getElementsByTagName("a");