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) {
- // New debug code added: Add delay to ensure DOM is ready
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', () => {
- this.initialize(uiBody);
- });
- } else {
- this.initialize(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);
- //Methods
- this.miniCartActivator();
- }
- initialize(uiBody) {
- console.log('Initializing MiniCartActions...');
- //Properties
- this.body = document.querySelector(uiBody);
- console.log('Body element:', this.body);
- if (!this.body) {
- console.error(`Element with selector '${uiBody}' not found.`);
- return;
- }
- this.sidebar = this.body.querySelector('.sidebar');
- this.shopping_menu = this.body.querySelector('.shopping-menu-wrapper .shopping-menu');
- console.log('Sidebar:', this.sidebar);
- console.log('Shopping menu:', this.shopping_menu);
- //mini cart and mini cart icon
- this.mini_cart = this.findMiniCart();
- this.cart_icon = this.findCartIcon();
- console.log('Mini cart found:', this.mini_cart);
- console.log('Cart icon found:', this.cart_icon);
- if (!this.mini_cart) {
- console.error('Mini cart not found! Cannot proceed.');
- return;
- }
- if (!this.cart_icon) {
- console.error('Cart icon not found! Cannot proceed.');
- return;
- }
- this.cart_items = this.shopping_menu?.querySelectorAll('.woocommerce-mini-cart-item') || [];
- this.mini_cart_counter = this.findMiniCartCounter();
- this.p_add_to_cart = this.shopping_menu?.querySelectorAll('.product-actions .add_to_cart_button') || [];
- this.close_mini_cart = this.mini_cart?.querySelector('#close-container');
- console.log('Elements found:', {
- cart_items: this.cart_items.length,
- mini_cart_counter: this.mini_cart_counter,
- p_add_to_cart: this.p_add_to_cart.length,
- close_mini_cart: this.close_mini_cart
- });
- // Test stateSetter directly without event listeners first
- this.testStateSetter();
- // Initialize the mini cart activator
- this.miniCartActivator();
- }
- 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}
- */
- console.log('=== initializeMiniCart ===');
- if (!this.mini_cart) {
- console.error('Cannot initialize: mini_cart is null');
- return;
- }
- // Clear all existing state classes first
- this.mini_cart.classList.remove('cart_active', 'cart_inactive');
- // Force DOM update
- this.mini_cart.offsetHeight;
- // Add inactive class
- this.mini_cart.classList.add('cart_inactive');
- /* More debugging added/ */
- console.log('Mini cart initialized with classes:', this.mini_cart.className);
- console.log('Mini cart computed style display:', getComputedStyle(this.mini_cart).display);
- return this.mini_cart.classList; // Missing return statemenet added.
- }
- 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.
- */
- /* Debug code added: Breaking points */
- // Log before changes
- console.log('Classes before change:', element.className);
- // Remove old class
- element.classList.remove(off);
- console.log('After removing', off, ':', element.className);
- // Add new class
- element.classList.add(on);
- console.log('After adding', on, ':', element.className);
- // Force DOM reflow
- const height = element.offsetHeight;
- console.log('Forced reflow, offsetHeight:', height);
- // Log computed styles
- const computedStyle = getComputedStyle(element);
- console.log('Computed display:', computedStyle.display);
- console.log('Computed visibility:', computedStyle.visibility);
- console.log('Computed opacity:', computedStyle.opacity);
- 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 miniCartActivator (mini_cart_actions)');
- console.log('this is close_mini_cart from miniCartActivator: ', this.close_mini_cart);
- if(this.mini_cart) {
- // Initialize state as inactive.
- this.initializeContainer(this.mini_cart);
- // Set the mini-cart state accordingly.
- this.stateControl(this.cart_icon, this.mini_cart);
- // Set the mini-cart state as inactive when clicking outside it.
- this.closeWhenOutside('body');
- }
- if(this.shopping_menu || this.sidebar) {
- // Increase the cart item count when clicking on the add-to-cart button.
- this.buttonHandler(this.p_add_to_cart, this.mini_cart_counter);
- // Append the cart counter to the shopping menu.
- this.appendElem(this.shopping_menu, this.mini_cart_counter);
- }
- }
- /* index.js */
- import MiniCartActions from './/modules/mini_cart_actions.js';
- const miniCartActions = new MiniCartActions('body');
Advertisement
Add Comment
Please, Sign In to add comment