mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 21:53:26 +00:00
perf: replace jQuery with Vanilla JS (#1681)
Also replaced `magnific-popup` with `GLightbox`
This commit is contained in:
@@ -3,18 +3,17 @@
|
||||
*/
|
||||
|
||||
export function back2top() {
|
||||
const $window = $(window);
|
||||
const $btn = $('#back-to-top');
|
||||
const btn = document.getElementById('back-to-top');
|
||||
|
||||
$window.on('scroll', () => {
|
||||
if ($window.scrollTop() > 50) {
|
||||
$btn.fadeIn();
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 50) {
|
||||
btn.classList.add('show');
|
||||
} else {
|
||||
$btn.fadeOut();
|
||||
btn.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
$btn.on('click', () => {
|
||||
$window.scrollTop(0);
|
||||
btn.addEventListener('click', () => {
|
||||
window.scrollTo({ top: 0 });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,34 +3,31 @@
|
||||
*/
|
||||
const childPrefix = 'l_';
|
||||
const parentPrefix = 'h_';
|
||||
const collapse = $('.collapse');
|
||||
const children = document.getElementsByClassName('collapse');
|
||||
|
||||
export function categoryCollapse() {
|
||||
/* close up top-category */
|
||||
collapse.on('hide.bs.collapse', function () {
|
||||
/* Bootstrap collapse events. */ const parentId =
|
||||
parentPrefix + $(this).attr('id').substring(childPrefix.length);
|
||||
if (parentId) {
|
||||
$(`#${parentId} .far.fa-folder-open`).attr(
|
||||
'class',
|
||||
'far fa-folder fa-fw'
|
||||
);
|
||||
$(`#${parentId} i.fas`).addClass('rotate');
|
||||
$(`#${parentId}`).removeClass('hide-border-bottom');
|
||||
}
|
||||
});
|
||||
[...children].forEach((elem) => {
|
||||
const id = parentPrefix + elem.id.substring(childPrefix.length);
|
||||
const parent = document.getElementById(id);
|
||||
|
||||
/* expand the top category */
|
||||
collapse.on('show.bs.collapse', function () {
|
||||
const parentId =
|
||||
parentPrefix + $(this).attr('id').substring(childPrefix.length);
|
||||
if (parentId) {
|
||||
$(`#${parentId} .far.fa-folder`).attr(
|
||||
'class',
|
||||
'far fa-folder-open fa-fw'
|
||||
);
|
||||
$(`#${parentId} i.fas`).removeClass('rotate');
|
||||
$(`#${parentId}`).addClass('hide-border-bottom');
|
||||
}
|
||||
// collapse sub-categories
|
||||
elem.addEventListener('hide.bs.collapse', () => {
|
||||
if (parent) {
|
||||
parent.querySelector('.far.fa-folder-open').className =
|
||||
'far fa-folder fa-fw';
|
||||
parent.querySelector('.fas.fa-angle-down').classList.add('rotate');
|
||||
parent.classList.remove('hide-border-bottom');
|
||||
}
|
||||
});
|
||||
|
||||
// expand sub-categories
|
||||
elem.addEventListener('show.bs.collapse', () => {
|
||||
if (parent) {
|
||||
parent.querySelector('.far.fa-folder').className =
|
||||
'far fa-folder-open fa-fw';
|
||||
parent.querySelector('.fas.fa-angle-down').classList.remove('rotate');
|
||||
parent.classList.add('hide-border-bottom');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,102 +7,103 @@
|
||||
*/
|
||||
|
||||
const clipboardSelector = '.code-header>button';
|
||||
|
||||
const ICON_DEFAULT = 'far fa-clipboard';
|
||||
const ICON_SUCCESS = 'fas fa-check';
|
||||
|
||||
const ATTR_TIMEOUT = 'timeout';
|
||||
const ATTR_TITLE_SUCCEED = 'data-title-succeed';
|
||||
const ATTR_TITLE_ORIGIN = 'data-bs-original-title';
|
||||
const TIMEOUT = 2000; // in milliseconds
|
||||
|
||||
function isLocked(node) {
|
||||
if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) {
|
||||
let timeout = $(node).attr(ATTR_TIMEOUT);
|
||||
if (node.hasAttribute(ATTR_TIMEOUT)) {
|
||||
let timeout = node.getAttribute(ATTR_TIMEOUT);
|
||||
if (Number(timeout) > Date.now()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function lock(node) {
|
||||
$(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||
node.setAttribute(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||
}
|
||||
|
||||
function unlock(node) {
|
||||
$(node).removeAttr(ATTR_TIMEOUT);
|
||||
node.removeAttribute(ATTR_TIMEOUT);
|
||||
}
|
||||
|
||||
function getIcon(btn) {
|
||||
let iconNode = $(btn).children();
|
||||
return iconNode.attr('class');
|
||||
}
|
||||
|
||||
const ICON_DEFAULT = getIcon(clipboardSelector);
|
||||
|
||||
function showTooltip(btn) {
|
||||
const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED);
|
||||
$(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
||||
const succeedTitle = btn.getAttribute(ATTR_TITLE_SUCCEED);
|
||||
btn.setAttribute(ATTR_TITLE_ORIGIN, succeedTitle);
|
||||
bootstrap.Tooltip.getInstance(btn).show();
|
||||
}
|
||||
|
||||
function hideTooltip(btn) {
|
||||
$(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN);
|
||||
bootstrap.Tooltip.getInstance(btn).hide();
|
||||
btn.removeAttribute(ATTR_TITLE_ORIGIN);
|
||||
}
|
||||
|
||||
function setSuccessIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_SUCCESS);
|
||||
const icon = btn.children[0];
|
||||
icon.setAttribute('class', ICON_SUCCESS);
|
||||
}
|
||||
|
||||
function resumeIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_DEFAULT);
|
||||
const icon = btn.children[0];
|
||||
icon.setAttribute('class', ICON_DEFAULT);
|
||||
}
|
||||
|
||||
export function initClipboard() {
|
||||
// Initial the clipboard.js object
|
||||
if ($(clipboardSelector).length) {
|
||||
const clipboard = new ClipboardJS(clipboardSelector, {
|
||||
target(trigger) {
|
||||
let codeBlock = trigger.parentNode.nextElementSibling;
|
||||
return codeBlock.querySelector('code .rouge-code');
|
||||
}
|
||||
});
|
||||
const clipboardList = document.querySelectorAll(clipboardSelector);
|
||||
|
||||
const clipboardList = document.querySelectorAll(clipboardSelector);
|
||||
[...clipboardList].map(
|
||||
(elem) =>
|
||||
new bootstrap.Tooltip(elem, {
|
||||
placement: 'left'
|
||||
})
|
||||
);
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
e.clearSelection();
|
||||
|
||||
const trigger = e.trigger;
|
||||
if (isLocked(trigger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSuccessIcon(trigger);
|
||||
showTooltip(trigger);
|
||||
lock(trigger);
|
||||
|
||||
setTimeout(() => {
|
||||
hideTooltip(trigger);
|
||||
resumeIcon(trigger);
|
||||
unlock(trigger);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
if (clipboardList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initial the clipboard.js object
|
||||
const clipboard = new ClipboardJS(clipboardSelector, {
|
||||
target: (trigger) => {
|
||||
const codeBlock = trigger.parentNode.nextElementSibling;
|
||||
return codeBlock.querySelector('code .rouge-code');
|
||||
}
|
||||
});
|
||||
|
||||
[...clipboardList].map(
|
||||
(elem) =>
|
||||
new bootstrap.Tooltip(elem, {
|
||||
placement: 'left'
|
||||
})
|
||||
);
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
const trigger = e.trigger;
|
||||
|
||||
e.clearSelection();
|
||||
|
||||
if (isLocked(trigger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSuccessIcon(trigger);
|
||||
showTooltip(trigger);
|
||||
lock(trigger);
|
||||
|
||||
setTimeout(() => {
|
||||
hideTooltip(trigger);
|
||||
resumeIcon(trigger);
|
||||
unlock(trigger);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
||||
/* --- Post link sharing --- */
|
||||
|
||||
const btnCopyLink = $('#copy-link');
|
||||
const btnCopyLink = document.getElementById('copy-link');
|
||||
|
||||
btnCopyLink.on('click', (e) => {
|
||||
let target = $(e.target);
|
||||
btnCopyLink.addEventListener('click', (e) => {
|
||||
const target = e.target;
|
||||
|
||||
if (isLocked(target)) {
|
||||
return;
|
||||
@@ -110,21 +111,23 @@ export function initClipboard() {
|
||||
|
||||
// Copy URL to clipboard
|
||||
navigator.clipboard.writeText(window.location.href).then(() => {
|
||||
const defaultTitle = target.attr(ATTR_TITLE_ORIGIN);
|
||||
const succeedTitle = target.attr(ATTR_TITLE_SUCCEED);
|
||||
const defaultTitle = target.getAttribute(ATTR_TITLE_ORIGIN);
|
||||
const succeedTitle = target.getAttribute(ATTR_TITLE_SUCCEED);
|
||||
|
||||
// Switch tooltip title
|
||||
target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
||||
target.setAttribute(ATTR_TITLE_ORIGIN, succeedTitle);
|
||||
bootstrap.Tooltip.getInstance(target).show();
|
||||
|
||||
lock(target);
|
||||
|
||||
setTimeout(() => {
|
||||
target.attr(ATTR_TITLE_ORIGIN, defaultTitle);
|
||||
target.setAttribute(ATTR_TITLE_ORIGIN, defaultTitle);
|
||||
unlock(target);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
});
|
||||
|
||||
btnCopyLink.on('mouseleave', function (e) {
|
||||
const target = $(e.target);
|
||||
target.tooltip('hide');
|
||||
btnCopyLink.addEventListener('mouseleave', (e) => {
|
||||
bootstrap.Tooltip.getInstance(e.target).hide();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const cover = {
|
||||
};
|
||||
|
||||
function removeCover(clzss) {
|
||||
$(this).parent().removeClass(clzss);
|
||||
this.parentElement.classList.remove(clzss);
|
||||
}
|
||||
|
||||
function handleImage() {
|
||||
@@ -30,32 +30,38 @@ function handleImage() {
|
||||
* Switches the LQIP with the real image URL.
|
||||
*/
|
||||
function switchLQIP() {
|
||||
const $img = $(this);
|
||||
const src = $img.attr(ATTR_DATA_SRC);
|
||||
|
||||
$img.attr('src', encodeURI(src));
|
||||
$img.removeAttr(ATTR_DATA_SRC);
|
||||
const src = this.getAttribute(ATTR_DATA_SRC);
|
||||
this.setAttribute('src', encodeURI(src));
|
||||
this.removeAttribute(ATTR_DATA_SRC);
|
||||
}
|
||||
|
||||
export function loadImg() {
|
||||
const $images = $('article img');
|
||||
const images = document.querySelectorAll('article img');
|
||||
|
||||
if ($images.length) {
|
||||
$images.on('load', handleImage);
|
||||
if (images.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
images.forEach((img) => {
|
||||
img.addEventListener('load', handleImage);
|
||||
});
|
||||
|
||||
// Images loaded from the browser cache do not trigger the 'load' event
|
||||
$('article img[loading="lazy"]').each(function () {
|
||||
if (this.complete) {
|
||||
removeCover.call(this, cover.SHIMMER);
|
||||
document.querySelectorAll('article img[loading="lazy"]').forEach((img) => {
|
||||
if (img.complete) {
|
||||
removeCover.call(img, cover.SHIMMER);
|
||||
}
|
||||
});
|
||||
|
||||
// LQIPs set by the data URI or WebP will not trigger the 'load' event,
|
||||
// so manually convert the URI to the URL of a high-resolution image.
|
||||
const $lqips = $(`article img[${ATTR_DATA_LQIP}="true"]`);
|
||||
const lqips = document.querySelectorAll(
|
||||
`article img[${ATTR_DATA_LQIP}="true"]`
|
||||
);
|
||||
|
||||
if ($lqips.length) {
|
||||
$lqips.each(switchLQIP);
|
||||
if (lqips.length) {
|
||||
lqips.forEach((lqip) => {
|
||||
switchLQIP.call(lqip);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
/**
|
||||
* Set up image popup
|
||||
*
|
||||
* See: https://github.com/dimsemenov/Magnific-Popup
|
||||
* Dependencies: https://github.com/biati-digital/glightbox
|
||||
*/
|
||||
|
||||
const IMG_CLASS = 'popup';
|
||||
|
||||
export function imgPopup() {
|
||||
if ($('.popup') <= 0) {
|
||||
if (document.getElementsByClassName(IMG_CLASS).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.popup').magnificPopup({
|
||||
type: 'image',
|
||||
closeOnContentClick: true,
|
||||
showCloseBtn: false,
|
||||
zoom: {
|
||||
enabled: true,
|
||||
duration: 300,
|
||||
easing: 'ease-in-out'
|
||||
}
|
||||
});
|
||||
GLightbox({ selector: `.${IMG_CLASS}` });
|
||||
}
|
||||
|
||||
@@ -15,15 +15,15 @@ class LocaleHelper {
|
||||
}
|
||||
|
||||
static get locale() {
|
||||
return $('html').attr('lang').substring(0, 2);
|
||||
return document.documentElement.getAttribute('lang').substring(0, 2);
|
||||
}
|
||||
|
||||
static getTimestamp(elem) {
|
||||
return Number(elem.attr(LocaleHelper.attrTimestamp)); // unix timestamp
|
||||
return Number(elem.getAttribute(this.attrTimestamp)); // unix timestamp
|
||||
}
|
||||
|
||||
static getDateFormat(elem) {
|
||||
return elem.attr(LocaleHelper.attrDateFormat);
|
||||
return elem.getAttribute(this.attrDateFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,21 +31,23 @@ export function initLocaleDatetime() {
|
||||
dayjs.locale(LocaleHelper.locale);
|
||||
dayjs.extend(window.dayjs_plugin_localizedFormat);
|
||||
|
||||
$(`[${LocaleHelper.attrTimestamp}]`).each(function () {
|
||||
const date = dayjs.unix(LocaleHelper.getTimestamp($(this)));
|
||||
const text = date.format(LocaleHelper.getDateFormat($(this)));
|
||||
$(this).text(text);
|
||||
$(this).removeAttr(LocaleHelper.attrTimestamp);
|
||||
$(this).removeAttr(LocaleHelper.attrDateFormat);
|
||||
document
|
||||
.querySelectorAll(`[${LocaleHelper.attrTimestamp}]`)
|
||||
.forEach((elem) => {
|
||||
const date = dayjs.unix(LocaleHelper.getTimestamp(elem));
|
||||
const text = date.format(LocaleHelper.getDateFormat(elem));
|
||||
elem.textContent = text;
|
||||
elem.removeAttribute(LocaleHelper.attrTimestamp);
|
||||
elem.removeAttribute(LocaleHelper.attrDateFormat);
|
||||
|
||||
// setup tooltips
|
||||
const tooltip = $(this).attr('data-bs-toggle');
|
||||
if (typeof tooltip === 'undefined' || tooltip !== 'tooltip') {
|
||||
return;
|
||||
}
|
||||
|
||||
const tooltipText = date.format('llll'); // see: https://day.js.org/docs/en/display/format#list-of-localized-formats
|
||||
$(this).attr('data-bs-title', tooltipText);
|
||||
new bootstrap.Tooltip($(this));
|
||||
});
|
||||
// setup tooltips
|
||||
if (
|
||||
elem.hasAttribute('data-bs-toggle') &&
|
||||
elem.getAttribute('data-bs-toggle') === 'tooltip'
|
||||
) {
|
||||
// see: https://day.js.org/docs/en/display/format#list-of-localized-formats
|
||||
const tooltipText = date.format('llll');
|
||||
elem.setAttribute('data-bs-title', tooltipText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
/**
|
||||
* Add listener for theme mode toggle
|
||||
*/
|
||||
const $toggleElem = $('.mode-toggle');
|
||||
const toggle = document.getElementById('mode-toggle');
|
||||
|
||||
export function modeWatcher() {
|
||||
if ($toggleElem.length === 0) {
|
||||
if (!toggle) {
|
||||
return;
|
||||
}
|
||||
|
||||
$toggleElem.off().on('click', (e) => {
|
||||
const $target = $(e.target);
|
||||
let $btn =
|
||||
$target.prop('tagName') === 'button'.toUpperCase()
|
||||
? $target
|
||||
: $target.parent();
|
||||
|
||||
modeToggle.flipMode(); // modeToggle: `_includes/mode-toggle.html`
|
||||
$btn.trigger('blur'); // remove the clicking outline
|
||||
toggle.addEventListener('click', () => {
|
||||
modeToggle.flipMode();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,121 +1,109 @@
|
||||
/**
|
||||
* This script make #search-result-wrapper switch to unloaded or shown automatically.
|
||||
*/
|
||||
const $btnSbTrigger = $('#sidebar-trigger');
|
||||
const $btnSearchTrigger = $('#search-trigger');
|
||||
const $btnCancel = $('#search-cancel');
|
||||
const $content = $('#main-wrapper>.container>.row');
|
||||
const $topbarTitle = $('#topbar-title');
|
||||
const $search = $('search');
|
||||
const $resultWrapper = $('#search-result-wrapper');
|
||||
const $results = $('#search-results');
|
||||
const $input = $('#search-input');
|
||||
const $hints = $('#search-hints');
|
||||
const $viewport = $('html,body');
|
||||
|
||||
// class names
|
||||
const C_LOADED = 'loaded';
|
||||
const C_UNLOADED = 'unloaded';
|
||||
const C_FOCUS = 'input-focus';
|
||||
const C_FLEX = 'd-flex';
|
||||
const btnSbTrigger = document.getElementById('sidebar-trigger');
|
||||
const btnSearchTrigger = document.getElementById('search-trigger');
|
||||
const btnCancel = document.getElementById('search-cancel');
|
||||
const content = document.querySelectorAll('#main-wrapper>.container>.row');
|
||||
const topbarTitle = document.getElementById('topbar-title');
|
||||
const search = document.getElementById('search');
|
||||
const resultWrapper = document.getElementById('search-result-wrapper');
|
||||
const results = document.getElementById('search-results');
|
||||
const input = document.getElementById('search-input');
|
||||
const hints = document.getElementById('search-hints');
|
||||
|
||||
class ScrollBlocker {
|
||||
static offset = 0;
|
||||
static resultVisible = false;
|
||||
// CSS class names
|
||||
const LOADED = 'loaded';
|
||||
const UNLOADED = 'unloaded';
|
||||
const FOCUS = 'input-focus';
|
||||
const FLEX = 'd-flex';
|
||||
|
||||
static on() {
|
||||
ScrollBlocker.offset = window.scrollY;
|
||||
$viewport.scrollTop(0);
|
||||
}
|
||||
|
||||
static off() {
|
||||
$viewport.scrollTop(ScrollBlocker.offset);
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Actions in mobile screens (Sidebar hidden) ---*/
|
||||
/* Actions in mobile screens (Sidebar hidden) */
|
||||
class MobileSearchBar {
|
||||
static on() {
|
||||
$btnSbTrigger.addClass(C_UNLOADED);
|
||||
$topbarTitle.addClass(C_UNLOADED);
|
||||
$btnSearchTrigger.addClass(C_UNLOADED);
|
||||
$search.addClass(C_FLEX);
|
||||
$btnCancel.addClass(C_LOADED);
|
||||
btnSbTrigger.classList.add(UNLOADED);
|
||||
topbarTitle.classList.add(UNLOADED);
|
||||
btnSearchTrigger.classList.add(UNLOADED);
|
||||
search.classList.add(FLEX);
|
||||
btnCancel.classList.add(LOADED);
|
||||
}
|
||||
|
||||
static off() {
|
||||
$btnCancel.removeClass(C_LOADED);
|
||||
$search.removeClass(C_FLEX);
|
||||
$btnSbTrigger.removeClass(C_UNLOADED);
|
||||
$topbarTitle.removeClass(C_UNLOADED);
|
||||
$btnSearchTrigger.removeClass(C_UNLOADED);
|
||||
btnCancel.classList.remove(LOADED);
|
||||
search.classList.remove(FLEX);
|
||||
btnSbTrigger.classList.remove(UNLOADED);
|
||||
topbarTitle.classList.remove(UNLOADED);
|
||||
btnSearchTrigger.classList.remove(UNLOADED);
|
||||
}
|
||||
}
|
||||
|
||||
class ResultSwitch {
|
||||
static resultVisible = false;
|
||||
|
||||
static on() {
|
||||
if (!ScrollBlocker.resultVisible) {
|
||||
// the block method must be called before $(#main-wrapper>.container) unloaded.
|
||||
ScrollBlocker.on();
|
||||
$resultWrapper.removeClass(C_UNLOADED);
|
||||
$content.addClass(C_UNLOADED);
|
||||
ScrollBlocker.resultVisible = true;
|
||||
if (!this.resultVisible) {
|
||||
resultWrapper.classList.remove(UNLOADED);
|
||||
content.forEach((el) => {
|
||||
el.classList.add(UNLOADED);
|
||||
});
|
||||
this.resultVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
static off() {
|
||||
if (ScrollBlocker.resultVisible) {
|
||||
$results.empty();
|
||||
if ($hints.hasClass(C_UNLOADED)) {
|
||||
$hints.removeClass(C_UNLOADED);
|
||||
if (this.resultVisible) {
|
||||
results.innerHTML = '';
|
||||
|
||||
if (hints.classList.contains(UNLOADED)) {
|
||||
hints.classList.remove(UNLOADED);
|
||||
}
|
||||
$resultWrapper.addClass(C_UNLOADED);
|
||||
$content.removeClass(C_UNLOADED);
|
||||
|
||||
// now the release method must be called after $(#main-wrapper>.container) display
|
||||
ScrollBlocker.off();
|
||||
|
||||
$input.val('');
|
||||
ScrollBlocker.resultVisible = false;
|
||||
resultWrapper.classList.add(UNLOADED);
|
||||
content.forEach((el) => {
|
||||
el.classList.remove(UNLOADED);
|
||||
});
|
||||
input.textContent = '';
|
||||
this.resultVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isMobileView() {
|
||||
return $btnCancel.hasClass(C_LOADED);
|
||||
return btnCancel.classList.contains(LOADED);
|
||||
}
|
||||
|
||||
export function displaySearch() {
|
||||
$btnSearchTrigger.on('click', function () {
|
||||
btnSearchTrigger.addEventListener('click', () => {
|
||||
MobileSearchBar.on();
|
||||
ResultSwitch.on();
|
||||
$input.trigger('focus');
|
||||
input.focus();
|
||||
});
|
||||
|
||||
$btnCancel.on('click', function () {
|
||||
btnCancel.addEventListener('click', () => {
|
||||
MobileSearchBar.off();
|
||||
ResultSwitch.off();
|
||||
});
|
||||
|
||||
$input.on('focus', function () {
|
||||
$search.addClass(C_FOCUS);
|
||||
input.addEventListener('focus', () => {
|
||||
search.classList.add(FOCUS);
|
||||
});
|
||||
|
||||
$input.on('focusout', function () {
|
||||
$search.removeClass(C_FOCUS);
|
||||
input.addEventListener('focusout', () => {
|
||||
search.classList.remove(FOCUS);
|
||||
});
|
||||
|
||||
$input.on('input', () => {
|
||||
if ($input.val() === '') {
|
||||
input.addEventListener('input', () => {
|
||||
if (input.value === '') {
|
||||
if (isMobileView()) {
|
||||
$hints.removeClass(C_UNLOADED);
|
||||
hints.classList.remove(UNLOADED);
|
||||
} else {
|
||||
ResultSwitch.off();
|
||||
}
|
||||
} else {
|
||||
ResultSwitch.on();
|
||||
if (isMobileView()) {
|
||||
$hints.addClass(C_UNLOADED);
|
||||
hints.classList.add(UNLOADED);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Expand or close the sidebar in mobile screens.
|
||||
*/
|
||||
|
||||
const $body = $('body');
|
||||
const ATTR_DISPLAY = 'sidebar-display';
|
||||
|
||||
class SidebarUtil {
|
||||
@@ -10,9 +9,9 @@ class SidebarUtil {
|
||||
|
||||
static toggle() {
|
||||
if (SidebarUtil.isExpanded === false) {
|
||||
$body.attr(ATTR_DISPLAY, '');
|
||||
document.body.setAttribute(ATTR_DISPLAY, '');
|
||||
} else {
|
||||
$body.removeAttr(ATTR_DISPLAY);
|
||||
document.body.removeAttribute(ATTR_DISPLAY);
|
||||
}
|
||||
|
||||
SidebarUtil.isExpanded = !SidebarUtil.isExpanded;
|
||||
@@ -20,6 +19,9 @@ class SidebarUtil {
|
||||
}
|
||||
|
||||
export function sidebarExpand() {
|
||||
$('#sidebar-trigger').on('click', SidebarUtil.toggle);
|
||||
$('#mask').on('click', SidebarUtil.toggle);
|
||||
document
|
||||
.getElementById('sidebar-trigger')
|
||||
.addEventListener('click', SidebarUtil.toggle);
|
||||
|
||||
document.getElementById('mask').addEventListener('click', SidebarUtil.toggle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user