Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* mini_cart_actions.js */
- export default class MiniCartActions {
- 'use strict';
- constructor(uiBody) {
- //Properties
- this.body = document.querySelector(uiBody);
- if (!this.body) {
- console.error(`Element with selector '${uiBody}' not found.`);
- }
- this.sidebar = this.body.querySelector('.sidebar');
- this.shopping_menu = this.body.querySelector('.shopping-menu-wrapper .shopping-menu');
- //mini cart and mini cart icon
- //this.mini_cart = this.findMiniCart();
- //this.cart_icon = this.findCartIcon();
- //mini cart
- const mobile_mini_cart = this.sidebar.querySelector('.actionsWrapper .widget_shopping_cart_content');
- const default_mini_cart = this.shopping_menu.querySelector('.widget_shopping_cart_content');
- this.mini_cart = mobile_mini_cart
- ? mobile_mini_cart
- : default_mini_cart;
- //mini cart icon
- const mobile_cart_icon = this.sidebar.querySelector('.actionsWrapper .shop-icons #cart-icon');
- const default_cart_icon = this.shopping_menu.querySelector('.shop-icons #cart-icon');
- this.cart_icon = mobile_cart_icon
- ? mobile_cart_icon
- : default_cart_icon;
- this.cart_items = this.shopping_menu.querySelectorAll('.woocommerce-mini-cart-item');
- //mini cart counter
- this.mini_cart_counter = this.findMiniCartCounter();
- this.p_add_to_cart = this.shopping_menu.querySelectorAll('.product-actions .add_to_cart_button');
- //close mini cart
- this.close_mini_cart = this.mini_cart.querySelector('#close-container');
- console.log('mini-cart classlist (constructor): ', this.mini_cart);
- console.log('cart_icon classlist (constructor): ', this.cart_icon);
- /*
- this.miniCartSelector = '.shopping-menu .widget_shopping_cart_content';
- this.miniCartIconSelector = '.shop-icons #cart-icon';
- this.close_mini_cartSelector = '#close-container';
- this.cartItemsSelector = '.shopping-menu .woocommerce-mini-cart-item';
- this.miniCartCounterSelector = '.mini_cart_counter';
- this.p_add_to_cartSelector = '.product-actions .add_to_cart_button';
- */
- //Methods
- //this.initElements();
- //this.initializeContainer(this.mini_cart);
- this.miniCartActivator();
- }
- /*
- initElements() {
- // Query within this.body, not global document
- this.miniCart = this.body.querySelector(this.miniCartSelector);
- this.miniCartIcon = this.body.querySelector(this.miniCartIconSelector);
- this.close_mini_cart = this.body.querySelector(this.close_mini_cartSelector);
- this.cartItems = document.querySelectorAll(this.cartItemsSelector);
- this.miniCartCounter = document.querySelector(this.miniCartCounterSelector);
- this.p_add_to_cart = document.querySelectorAll(this.p_add_to_cartSelector);
- console.log('this is miniCartIcon from initElements: ', this.miniCartIcon);
- // Add null checks
- if (!this.miniCartIcon) {
- throw new Error('Mini cart icon not found');
- }
- if (!this.miniCart) {
- throw new Error(`Cart container not found with selector: ${this.miniCartSelector}`);
- }
- //this.miniCart.classList.add('inactive');
- }
- */
- findMiniCart() {
- /**
- * Finds the mini-cart container element in the DOM.
- * Searches first in the mobile sidebar's actionsWrapper, then falls back
- * to the desktop shopping-menu container.
- *
- * @returns {HTMLElement|null} The mini-cart container element (.widget_shopping_cart_content)
- * or null if not found in either location
- */
- let miniCart = null;
- if (this.sidebar) {
- miniCart = this.sidebar.querySelector('.actionsWrapper .widget_shopping_cart_content');
- }
- if (!miniCart && this.shopping_menu) {
- miniCart = this.shopping_menu.querySelector('.widget_shopping_cart_content');
- }
- console.log('findMiniCart(): ', miniCart);
- return miniCart;
- }
- findCartIcon() {
- /**
- * Finds the cart icon element in the DOM.
- * Searches first in the mobile sidebar's actionsWrapper, then falls back
- * to the desktop shopping-menu container.
- *
- * @returns {HTMLElement|null} The cart icon element (#cart-icon)
- * or null if not found in either location
- */
- let cartIcon = null;
- console.log('findCartIcon() (sidebar): ', cartIcon);
- if (this.sidebar) {
- cartIcon = this.sidebar.querySelector('.actionsWrapper .shop-icons #cart-icon');
- }
- if (!cartIcon && this.shopping_menu) {
- cartIcon = this.shopping_menu.querySelector('.shop-icons #cart-icon');
- }
- console.log('findCartIcon() (shopping_menu): ', cartIcon);
- return cartIcon;
- }
- findMiniCartCounter() {
- /**
- * Finds the mini-cart counter element in the DOM.
- * Searches first in the mobile sidebar's actionsWrapper, then falls back
- * to the desktop shopping-menu container.
- *
- * @returns {HTMLElement|null} The mini-cart counter element (.mini_cart_counter)
- * or null if not found in either location
- */
- let counter = null;
- if (this.sidebar) {
- counter = this.sidebar.querySelector('.actionsWrapper .mini_cart_counter');
- }
- if (!counter && this.shopping_menu) {
- counter = this.shopping_menu.querySelector('.mini_cart_counter');
- }
- console.log('findMiniCartCounter(): ', counter);
- return counter;
- }
- initializeContainer(container) {
- /**
- * Initializes the mini-cart to its default inactive state.
- * Removes any 'active' class and adds 'inactive' class to ensure
- * the mini-cart starts hidden when the page loads or reloads.
- *
- * @returns {void}
- */
- if (!container) {
- console.error('Cannot initialize mini cart - element not found');
- return;
- }
- // Remove all state classes first
- //this.mini_cart.classList.remove('cart_active', 'cart_inactive');
- // Add inactive class
- container.classList.add('cart_inactive');
- console.log('Mini cart initialized as inactive. Classes: ', container.classList.toString());
- // Force a reflow to ensure the class is applied
- this.mini_cart.offsetHeight;
- }
- stateSetter(element, off, on) {
- /**
- * stateSetter
- * Toggles the class state of a given element by removing an "off" state and adding an "on" state.
- *
- * @param {HTMLElement} element - The element to update.
- * @param {string} off - The class name representing the "off" state.
- * @param {string} on - The class name representing the "on" state.
- * @returns {HTMLElement} - The updated element.
- */
- element.classList.remove(off);
- element.classList.add(on);
- console.log('stateSetter(): ', element.classList);
- return element;
- }
- stateControl(trigger, element) {
- /**
- * stateControl
- * Binds a click event listener to the trigger element. When clicked, it toggles
- * the state (active/inactive) of the target element.
- *
- * @param {HTMLElement} trigger - The element that triggers the state change.
- * @param {HTMLElement} element - The target element whose state is toggled.
- */
- console.log('stateControl() trigger: ', trigger);
- console.log('stateControl() element: ', element);
- trigger.addEventListener('click', () => {
- if (element.classList.contains('cart_inactive')) {
- this.stateSetter(element, 'cart_inactive', 'cart_active');
- return element;
- } else if(element.classList.contains('cart_active')) {
- this.stateSetter(element, 'cart_active', 'cart_inactive');
- return element;
- } else {
- return;
- }
- });
- }
- closeMiniCart(container, closeToggle) {
- if (!container || !closeToggle) {
- console.error('closeMiniCart: Missing container or closeToggle');
- return;
- }
- console.log('Setting up close mini cart listener');
- closeToggle.addEventListener('click', (event) => {
- event.preventDefault();
- event.stopPropagation();
- console.log('Close button clicked');
- this.stateSetter(container, 'cart_active', 'cart_inactive');
- });
- return container;
- }
- appendElem(trigger, element) {
- /**
- * appendElem
- * Appends a given element to the trigger element.
- *
- * @param {HTMLElement} trigger - The parent element where the element should be appended.
- * @param {HTMLElement} element - The element to append.
- * @returns {HTMLElement} - The appended element.
- */
- if (!trigger || !element) {
- console.error('appendElem: Missing trigger or element');
- return null;
- }
- const appended = trigger.appendChild(element);
- return appended;
- }
- activateCounter() {
- /**
- * activateCounter
- * Updates the mini-cart counter state from inactive to active.
- *
- * @returns {HTMLElement|undefined} - The updated mini cart counter, if updated.
- */
- if (!this.mini_cart_counter) {
- return;
- }
- if (this.mini_cart_counter.classList.contains('counter_inactive')) {
- this.stateSetter(this.mini_cart_counter, 'counter_inactive', 'counter_active');
- return this.mini_cart_counter;
- }
- }
- buttonHandler(buttons) {
- /**
- * buttonHandler
- * Attaches a click event listener to each add-to-cart button, triggering the counter activation.
- *
- * @param {NodeList|Array} buttons - A collection of add-to-cart button elements.
- * @returns {NodeList|Array} - The collection of buttons with event listeners attached.
- */
- if (!buttons || buttons.length === 0) {
- return buttons;
- }
- buttons.forEach(button => {
- button.addEventListener('click', () => {
- this.activateCounter(); // Fixed: was missing 'this.'
- });
- });
- return buttons;
- }
- closeWhenOutside(entity) {
- /**
- * closeWhenOutside
- * Binds a click event listener to an external entity (like the document) that closes the mini-cart
- * if the click occurs outside the cart icon and mini cart.
- *
- * @param {HTMLElement} entity - The element to listen for clicks (typically document).
- */
- if (!entity) {
- console.error('closeWhenOutside: No entity provided');
- return;
- }
- if (!this.mini_cart || !this.cart_icon) {
- console.error('closeWhenOutside: Required elements not found');
- return;
- }
- console.log('Setting up outside click handler');
- entity.addEventListener('click', (event) => {
- // Only close if mini cart is currently active
- if (this.mini_cart.classList.contains('cart_active')) {
- const clickedInsideCart = this.mini_cart.contains(event.target);
- const clickedInsideIcon = this.cart_icon.contains(event.target);
- if (!clickedInsideCart && !clickedInsideIcon) {
- console.log('Clicked outside, closing mini cart');
- this.stateSetter(this.mini_cart, 'cart_active', 'cart_inactive');
- }
- }
- });
- }
- miniCartActivator() {
- /**
- * miniCartActivator
- * Ties all mini-cart related behaviors together:
- * cartState - Binds state control to the cart icon for toggling the mini-cart.
- * buttonState - Attaches event listeners to add-to-cart buttons.
- * closeWhenOutside - Sets up the event listener to close the mini-cart when clicking outside.
- * appendMenu - Appends the mini-cart counter to the shopping menu.
- *
- * @returns {object} - An object containing the activated actions.
- */
- console.log('this is events (mini_cart_actions)');
- console.log('this is events(): ', this.close_mini_cart);
- const actions = {
- initializeState: this.initializeContainer(this.mini_cart),
- cartState: this.stateControl(this.cart_icon, this.mini_cart),
- buttonState: this.buttonHandler(this.p_add_to_cart),
- closeWhenOutside: this.closeWhenOutside(document),
- appendMenu: this.appendElem(this.shopping_menu, this.mini_cart_counter)
- //closeMiniCart: this.closeMiniCart(this.mini_cart, this.cart_icon)
- };
- return actions;
- }
- }
- /* index.js */
- import MiniCartActions from './/modules/mini_cart_actions.js';
- const miniCartActions = new MiniCartActions('body');
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement