webupdate
This commit is contained in:
114
website/public/assets/js/mobile-touch-fix.js
Normal file
114
website/public/assets/js/mobile-touch-fix.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Mobile Touch Optimization
|
||||
* Eliminates double-tap behavior and ensures immediate response on mobile devices
|
||||
*/
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
// Only apply on touch devices
|
||||
if (!("ontouchstart" in window)) return;
|
||||
|
||||
// Disable 300ms click delay on mobile
|
||||
let touchStartX, touchStartY;
|
||||
|
||||
// Add fastclick functionality for immediate response
|
||||
document.addEventListener(
|
||||
"touchstart",
|
||||
function (e) {
|
||||
touchStartX = e.touches[0].clientX;
|
||||
touchStartY = e.touches[0].clientY;
|
||||
},
|
||||
{ passive: true },
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
"touchend",
|
||||
function (e) {
|
||||
if (!touchStartX || !touchStartY) return;
|
||||
|
||||
const touchEndX = e.changedTouches[0].clientX;
|
||||
const touchEndY = e.changedTouches[0].clientY;
|
||||
|
||||
// Check if it's a tap (not a swipe)
|
||||
const diffX = Math.abs(touchEndX - touchStartX);
|
||||
const diffY = Math.abs(touchEndY - touchStartY);
|
||||
|
||||
if (diffX < 10 && diffY < 10) {
|
||||
// This is a tap, ensure immediate response
|
||||
const target = e.target.closest(
|
||||
"a, button, [data-bs-toggle], .product-card, .portfolio-card, .blog-card, .nav-link, .btn",
|
||||
);
|
||||
if (target && !target.disabled) {
|
||||
// Add visual feedback
|
||||
target.style.opacity = "0.7";
|
||||
setTimeout(() => {
|
||||
target.style.opacity = "";
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
touchStartX = null;
|
||||
touchStartY = null;
|
||||
},
|
||||
{ passive: false },
|
||||
);
|
||||
|
||||
// Remove hover states that cause double-tap on mobile
|
||||
if (window.matchMedia("(hover: none)").matches) {
|
||||
const style = document.createElement("style");
|
||||
style.textContent = `
|
||||
/* Override hover states for immediate touch response */
|
||||
.product-card, .portfolio-card, .blog-card, .btn, .nav-link {
|
||||
transition: transform 0.1s ease, opacity 0.1s ease !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
// Optimize click handlers for mobile
|
||||
function optimizeClickHandler(selector) {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
elements.forEach((el) => {
|
||||
if (el.dataset.mobileOptimized) return;
|
||||
el.dataset.mobileOptimized = "true";
|
||||
|
||||
// Remove any existing event listeners that might cause delays
|
||||
el.style.pointerEvents = "auto";
|
||||
el.style.touchAction = "manipulation";
|
||||
|
||||
// Ensure proper z-index for touch
|
||||
const computedStyle = window.getComputedStyle(el);
|
||||
if (computedStyle.position === "static") {
|
||||
el.style.position = "relative";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Apply optimizations when DOM is ready
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
optimizeClickHandler(
|
||||
"a, button, .product-card, .portfolio-card, .blog-card, .btn, .nav-link, .filter-btn, .add-to-cart-btn",
|
||||
);
|
||||
});
|
||||
|
||||
// Apply optimizations to dynamically added content
|
||||
const observer = new MutationObserver(function (mutations) {
|
||||
mutations.forEach(function (mutation) {
|
||||
if (mutation.type === "childList") {
|
||||
mutation.addedNodes.forEach(function (node) {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
optimizeClickHandler(
|
||||
"a, button, .product-card, .portfolio-card, .blog-card, .btn, .nav-link, .filter-btn, .add-to-cart-btn",
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user