Development Log

Lev Lev

Removing prefixes (select, from, comma)

The following bit of code removes the word “Select” from variant selection drop-down menus, the word “From” from the price of the products which have variable prices depending on variants, and also removes all commas (“,”) from price indications, for aesthetic reasons.I placed this code into the footer section.

HTML:
JAVASCRIPT:

//remove all select from variants
function removeSelectPrefix() {
// Get all select elements on the page
const selects = document.querySelectorAll('select');
// Iterate through each select element
selects.forEach(select => {
// Get the first option element
const firstOption = select.options[0];
// Check if the first option exists and its text starts with "select"
if (firstOption && firstOption.text.toLowerCase().startsWith('select')) {
// Remove the prefix "select" from the text
firstOption.text = firstOption.text.replace(/^select\s*/i, '');
        }
    });
}
removeSelectPrefix();
//remove all from and commas from prices
var elements = document.querySelectorAll('.product-price');
elements.forEach(function(element) {
var text = element.textContent;
text = text.replace('from', '');
text = text.replace(',', '');
element.textContent = text;
});
CSS:

Read More
Lev Lev

Randomize items in shop

The following bit of code randomizes product order in the main shop category which displays all products. Very straight forward and easy to implement. Only Javascript is required.

HTML:
JAVASCRIPT:

document.addEventListener('DOMContentLoaded', function() {
var getURL = window.location.href;
const subString = 'shop';
const badString = 'shop/'; 
const badStringTwo = 'sanctum';
if (getURL.includes(badString) || getURL.includes(badStringTwo)){ 
}
else if (getURL.includes(subString)) { 
const productGrid = document.querySelector('.products-flex-container .list-grid');
if (productGrid) {
var productItems = productGrid.querySelectorAll('.grid-item');
for (var i = productItems.length; i >= 0; i--) {
productGrid.appendChild(productItems[Math.random() * i | 0]);
		}
	}
}
else { }
});
CSS:

Read More
Lev Lev

Sticky cart icon for mobile

Recently I have implemented a sticky cart icon for mobile view of the website. It is an icon that comes into view when browsing shop categories. It only appears when scrolled down a certain length and if the cart is not empty. To do this I monitor the cart contents every time the user scrolls, or if the window resizes. You may notice that the way I check whether the website is in mobile view, is not by checking the screen size, which is unreliable. Instead I directly check whether the header changes its display property to display the mobile version. This is way more robust and flawless, as screen sizes can vary considerably as new devices enter the market.

HTML:

<div id="stickyCartMobile" class="stickyCartMobile"></div>
JAVASCRIPT:

document.addEventListener('DOMContentLoaded', function() {
const subString = 'shop';
const subStringTwo = 'shop/p/';
const getURL = window.location.href;
const content = document.querySelector(".content");
const stickyCartMobile = document.getElementById('stickyCartMobile');
const headerActions = document.querySelector('.header-actions');
const cartElement = document.querySelector('.sqs-cart-quantity');
var cartQuantity = cartElement.textContent;
let isTouch = false;
function checkHeader() {
const styles = window.getComputedStyle(headerActions);
isTouch = styles.getPropertyValue('display') !== 'flex';
}
checkHeader();
if (getURL.includes(subString) && !getURL.includes(subStringTwo)) {
content.appendChild(stickyCartMobile);
} else { 
stickyCartMobile.remove();
}
function showStickyCartMobile() {
stickyCartMobile.classList.add('showing');
}
function hideStickyCartMobile() {
stickyCartMobile.classList.remove('showing');
}
function checkScrollPos() {
if (window.scrollY >= 500 && isTouch && cartQuantity > 0) {
showStickyCartMobile();
} else {
hideStickyCartMobile();
	}
}
stickyCartMobile.addEventListener('click', function() {
window.location.href = '/cart';
});
function handleScrollResize() {
cartQuantity = cartElement.textContent;
checkScrollPos();
checkHeader();
}
window.addEventListener('scroll', handleScrollResize);
window.addEventListener('resize', handleScrollResize); 
handleScrollResize(); 
});
CSS:

#stickyCartMobile {
  width: 60px;
  height: 60px;
  position: fixed;
  top: 0px;
  right: -80px;
  display: block;
  background: url('https://images.squarespace-cdn.com/content/v1/6654b2fee26f292de13f1a9d/3538cab3-d423-445f-87f8-fe805c7b4ca4/mobileShopIcon3.png') no-repeat center center;
  background-size: contain;
  z-index: 999;
  cursor: pointer;
  pointer-events: auto;
  transition: all 1s ease;
  transform: scale(0.5);
}
#stickyCartMobile.showing {
  right: 9px;
  transform: scale(1);
}
Read More
Lev Lev

to-Bottom button

To-Bottom button is slightly more complicated than the back-to-top button, but not by much. It allows the user to instantly scroll to the bottom of a potentially long page. Right now you can see the bee hanging out in the top left corner, that’s the button I am talking about. Remember that at this point in time my knowledge of Javascript is minimal. I did need to keep in mind that the websites nowadays are responsive, which means they should adapt to different device screens and input styles. Hence using an observer to monitor if the mobile menu is open and making the bee fly away during that time, for aesthetic reasons.

EDIT:
I upgraded the code to monitor page height, in case elements are added dynamically which increase the page height.

HTML:

<div id="scroll-there"></div>
<div id="beeContainerTop">
<a id="back-to-bottom" href="#scroll-there"></a>
</div>
JAVASCRIPT:

document.addEventListener('DOMContentLoaded', function() {
var beesAudio = new Audio('https://static1.squarespace.com/static/6654b2fee26f292de13f1a9d/t/66958d727cdd33076182ed01/1721077108416/Bees1.mp3/original/Bees1.mp3');
beesAudio.preload = 'auto';
beesAudio.playbackRate = 1;
beesAudio.volume = 0.3;
const content = document.querySelector(".header-nav-list");
const beeContainerTop = document.getElementById('beeContainerTop');
const burgerButton = document.querySelector('.header-burger-btn');
const mobileCartIcons = document.querySelectorAll('.header-actions-action--cart');
var mobileMenuActive = false;
var pageHeight = 0;
//basic class mods
function showBackToBottom() {
document.getElementById('back-to-bottom').classList.add('show-butt');
}
function hideBackToBottom() {
document.getElementById('back-to-bottom').classList.remove('show-butt');
}
//condition for when bee is here
function checkScrollPos() {
if (window.scrollY <= 160 && pageHeight >= window.innerHeight + 800 && mobileMenuActive == false) {
showBackToBottom();
} else {
hideBackToBottom();
	}
}
//dynamic monitoring of page height
function updatePageHeight() {
pageHeight = document.documentElement.scrollHeight;
}
// Monitor if mobile menu is open
const observerCallback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
if (burgerButton.classList.contains('burger--active')) {
mobileMenuActive = true;
mobileCartIcons.forEach(function(mobileCartIcon) {
mobileCartIcon.classList.add('menuOpen');
});
document.getElementById('back-to-bottom').classList.remove('show-butt');
} else {
mobileMenuActive = false;
mobileCartIcons.forEach(function(mobileCartIcon) {
mobileCartIcon.classList.remove('menuOpen');
});
checkScrollPos();
			}
		}
	}
};
const observer = new MutationObserver(observerCallback);
const config = { attributes: true };
observer.observe(burgerButton, config);
//main stuff
function my_function() {
function findHighestNode(nodesList) {
for (var i = nodesList.length - 1; i >= 0; i--) {
if (nodesList[i].scrollHeight && nodesList[i].clientHeight) {
var elHeight = Math.max(nodesList[i].scrollHeight, nodesList[i].clientHeight);
pageHeight = Math.max(elHeight, pageHeight);
}
if (nodesList[i].childNodes.length) findHighestNode(nodesList[i].childNodes);
	}
}
findHighestNode(document.documentElement.childNodes);
//click event
document.getElementById('back-to-bottom').addEventListener('click', function() {
beesAudio.play();
window.scrollTo(0, document.body.scrollHeight);
});
window.addEventListener('scroll', function() {
checkScrollPos();
});
checkScrollPos();
// MutationObserver to track changes in the DOM for page height
const domObserver = new MutationObserver(function(mutationsList) {
mutationsList.forEach(function(mutation) {
if (mutation.type === 'childList') {
updatePageHeight();
checkScrollPos();
		}
	});
});
// Observe changes in the entire document
domObserver.observe(document.body, { childList: true, subtree: true });
}
if (window.attachEvent) {
window.attachEvent('onload', my_function);
} else if (window.addEventListener) {
window.addEventListener('load', my_function, false);
} else {
document.addEventListener('load', my_function, false);
  }
});
CSS:

#beeContainerTop {
  width: 100%;
  position: relative;
  margin: 0 auto;
  display: flex;
  box-sizing: border-box;
  justify-content: left;
  max-width: 2200px;
  padding-left: 3vw;
  padding-right: 3vw;
}
#back-to-bottom {
  height:65px;
  width:65px;
  scale: 1.1;
  position:fixed;
  z-index:9999;
  border-radius:0%;
  margin-left: -10px;
  margin-top: 5px;
  background-image: url(https://static1.squarespace.com/static/6654b2fee26f292de13f1a9d/t/667f25d3015586177842c716/1719608787700/BeeiconYellow2+Reversed.png);
    background-size: contain;
    background-position: center center;
    background-repeat: no-repeat;
    color: transparent !important;
  @media screen and (max-width:790px) {
    left:15px;
    scale: 1;
    margin-top: 10px;
  }
  /*Position Out of View*/
  top: -300px;
  opacity:0;
  transition: all .8s ease;
}
  /*Position In View*/
#back-to-bottom.show-butt{
  top: 10px;
  opacity:1;
  transition: all .8s ease;
}

Here you have some HTML, followed by JS and CSS. This is all that there is to it to show the to-bottom bee.

Read More
Lev Lev

Back-to-top button

One of the first functionalities to implement, that went beyond the editor’s in-built abilities, was the back-to-top button. It is the bee in the bottom right corner. It appears if a page exceeds a certain scroll length and disappears if the viewer is near the top of the page. Upon clicking the bee, a buzzing sound is made and the page quickly scrolls back to the top. This, apart from it being a bee, is a common feature on websites with long pages and it should be more common in my opinion, as it is very handy. Sure my header with the menu is sticky, which means it comes back if you scroll up, but having that little extra way, just a click away, to be back at the top is grand. Especially if it is a cute bee that makes a noise when disturbed. Below I present the code which makes it possible:

HTML:

<div id="scroll-here"></div>
<div id="beeContainerBottom">
<a id="back-to-top" href="#scroll-here"></a>
</div>
JAVASCRIPT:

document.addEventListener('DOMContentLoaded', function() {
var beesUpAudio = new Audio('https://static1.squarespace.com/static/6654b2fee26f292de13f1a9d/t/66958d727cdd33076182ed01/1721077108416/Bees1.mp3/original/Bees1.mp3');
beesUpAudio.preload = 'auto';
beesUpAudio.playbackRate = 1.2; 
beesUpAudio.volume = 0.3;
const content = document.querySelector(".content");
const beeContainerBottom = document.getElementById('beeContainerBottom');
content.appendChild(beeContainerBottom);
$(function(){
function showBackToTop(){
$('#back-to-top').addClass('show-btt');
}
function hideBackToTop(){
$('#back-to-top').removeClass('show-btt');
}
function checkScrollPos(){
if ($(this).scrollTop() >= 300) {
showBackToTop();
} else {
hideBackToTop()
}
}
$('#back-to-top').click(function(){
beesUpAudio.play();
$(window).scrollTop(0)});
$(window).on('scroll', function(){
checkScrollPos();
});
checkScrollPos();
})
});
CSS:

#beeContainerBottom {
  width: 100%;
  position: relative;
  margin: 0 auto;
  display: flex;
  box-sizing: border-box;
  justify-content: right;
  max-width: 2200px;
  padding-left: 3vw;
  padding-right: 3vw;
}
#back-to-top{
  height:70px;
  width:70px;
  position:fixed;
  z-index:9999;
  border:0;
  margin-bottom: 1%;
  margin-right: -10px;
  background-image: url(https://static1.squarespace.com/static/6654b2fee26f292de13f1a9d/t/6664f35b4014e740a4ae7a59/1717891931682/BeeiconYellow2.png);
    background-size: contain;
    background-position: center center;
    background-repeat: no-repeat;
    color: transparent !important;
  /*Position Out of View*/
  bottom:-150px;
  opacity:0;
  transition: all .5s ease;
}
  /*Position In View*/
#back-to-top.show-btt{
  bottom:0;
  opacity:1;
  transition: all .5s ease;
}

Here you have some HTML, followed by JS and CSS. This is all that there is to it to show the back-to-top bee.

Read More
Lev Lev

Choosing Squarespace Platform

I needed my own website for a while now. Last time I made a website was in 2008, using Actionscript. Things have changed considerably since then. I was delighted to find out about Squarespace, as Wordpress editing capabilities left me unsatisfied. I took the plunge and signed up. The built-in editing tools for 7.1 are impressive and easy to use. I spent about a day on creating the skeletal structure for the website, and as I did, new ideas flowed into my brain. They were about the content I could post and how it would be presented.

On the second day I was a taken by surprise, finding out that although the system is very straight forward, it is also rigorous, due to the fluid engine which provides device scaling. This meant that realizing my ideas would be more difficult than I thought, because I would be dealing not with just a website, but a system that manages it. In practice it provides obstacles for implementing CSS, Javascript, HTML, and the less basic functions, such as comment sections and chat boxes. Basically, if Squarespace hasn’t implemented it themselves, there is no way to leverage their hosting service for anything else but the content of the website. Implementing CSS, JS and HTML was achieved eventually. Turns out it is not hard, just not straight forward. It is also housed in specific places which aren’t user friendly for editing it.

On the third day I have decided on the theme of my website and its iconography. At this point in time I had zero knowledge of Javascript and an outdated understanding of CSS. However, it was time to implement certain rules into the design to further personalize it and I had to learn everything I wanted to use. Many sessions with ChatGPT and Google and Squarespace forums and Youtube later, I now have a very decent ability to script almost any functionality desirable.

Further posts will be mostly focusing on me finding creative scripting solutions to the problems with my website and how they keep me from buying expensive plug-ins.

Read More