1/** 2 * Blog Card Image Error Handler 3 * Handles image loading errors and replaces with default placeholder 4 * Works on all pages where blog cards are displayed 5 */ 6 7(function() { 8 'use strict'; 9 10 /** 11 * Handle image loading errors - replace with default placeholder 12 */ 13 function initImageErrorHandling() { 14 // Get default image URL from first image's data attribute or construct it 15 function getDefaultImageUrl() { 16 const firstImg = document.querySelector('.analysis-card-thumbnail-link img[data-default-img]'); 17 if (firstImg && firstImg.dataset.defaultImg) { 18 return firstImg.dataset.defaultImg; 19 } 20 // Fallback: construct URL from current page location 21 const baseUrl = window.location.origin; 22 return baseUrl + '/wp-content/themes/arzpayaBlog/assets/images/404/arzpaya_logo_dark_404.webp'; 23 } 24 25 const defaultImgUrl = getDefaultImageUrl(); 26 27 // Function to handle image error 28 function handleImageError(img) { 29 // Get default image URL from data attribute or use global default 30 const imgDefaultUrl = img.dataset.defaultImg || defaultImgUrl; 31 32 // Only replace if it's not already the default image 33 if (img.src !== imgDefaultUrl && !img.src.includes('arzpaya_logo_dark_404.webp')) { 34 img.src = imgDefaultUrl; 35 img.classList.add('default-placeholder'); 36 37 // Add has-placeholder class to parent link for flexbox centering 38 const parentLink = img.closest('.analysis-card-thumbnail-link'); 39 if (parentLink) { 40 parentLink.classList.add('has-placeholder'); 41 } 42 43 // Prevent infinite loop if default image also fails 44 img.onerror = null; 45 } 46 } 47 48 // Handle existing images on page load 49 function setupImageErrorHandlers() { 50 const blogCardImages = document.querySelectorAll('.analysis-card-thumbnail-link img'); 51 blogCardImages.forEach(img => { 52 // Check if image is already loaded and failed 53 if (img.complete && img.naturalHeight === 0) { 54 handleImageError(img); 55 } else { 56 // Add error handler for future load failures 57 img.addEventListener('error', function() { 58 handleImageError(this); 59 }); 60 } 61 }); 62 } 63 64 // Initial setup 65 setupImageErrorHandlers(); 66 67 // Use MutationObserver to handle dynamically loaded images (AJAX pagination, etc.) 68 const observer = new MutationObserver(function(mutations) { 69 mutations.forEach(function(mutation) { 70 mutation.addedNodes.forEach(function(node) { 71 if (node.nodeType === 1) { // Element node 72 // Check if the added node is an image 73 if (node.tagName === 'IMG' && node.closest('.analysis-card-thumbnail-link')) { 74 if (node.complete && node.naturalHeight === 0) { 75 handleImageError(node); 76 } else { 77 node.addEventListener('error', function() { 78 handleImageError(this); 79 }); 80 } 81 } 82 // Check for images inside added nodes 83 const images = node.querySelectorAll && node.querySelectorAll('.analysis-card-thumbnail-link img'); 84 if (images) { 85 images.forEach(img => { 86 if (img.complete && img.naturalHeight === 0) { 87 handleImageError(img); 88 } else { 89 img.addEventListener('error', function() { 90 handleImageError(this); 91 }); 92 } 93 }); 94 } 95 } 96 }); 97 }); 98 }); 99 100 // Observe document body for changes (covers all blog card containers
100) 101 observer.observe(document.body, { 102 childList: true, 103 subtree: true 104 }); 105 } 106 107 // Initialize when DOM is ready 108 if (document.readyState === 'loading') { 109 document.addEventListener('DOMContentLoaded', initImageErrorHandling); 110 } else { 111 initImageErrorHandling(); 112 } 113 114})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.