Download All Images

Description

  • download all images from site
  • view demo – password: abc

#1. Install Code

#1.1. First, create a page in Not Linked (any name) and add a Block

01.26c29v5

Choose Gallery

01.26c29v5

Next, click Plus icon > And choose all images on your site

01.26c29v5

#1.2. Make sure choose Grid layout

01.26c29v5

#1.3. Hover on Page where you use Gallery Block > Click Gear icon

01.26c29v5

Click Advanced > Paste this code

<!-- @tuanphan - Download All Images -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
<script>
(function() {
  const CONFIG = {
    buttonText: 'Download All Images',
    buttonIcon: '<i class="fa-solid fa-download"></i>',
    downloadIcon: '<i class="fa-solid fa-circle-down"></i>'
  };

  function addDownloadAllButton() {
    const galleryBlocks = document.querySelectorAll('.gallery-block');
    
    galleryBlocks.forEach(block => {
      if (block.previousElementSibling?.classList.contains('download-all-btn-wrapper')) {
        return;
      }
      
      const buttonWrapper = document.createElement('div');
      buttonWrapper.className = 'download-all-btn-wrapper';
      
      const button = document.createElement('button');
      button.className = 'download-all-btn';
      button.innerHTML = `${CONFIG.buttonIcon} <span>${CONFIG.buttonText}</span>`;
      
      button.addEventListener('click', () => downloadAllImages(block));
      
      buttonWrapper.appendChild(button);
      block.parentNode.insertBefore(buttonWrapper, block);
    });
  }

  async function downloadAllImages(galleryBlock) {
    const images = galleryBlock.querySelectorAll('img[data-src], img[src]');
    const button = galleryBlock.previousElementSibling?.querySelector('.download-all-btn');
    
    if (!images.length) {
      alert('No images found in gallery');
      return;
    }
    
    if (button) {
      button.disabled = true;
      button.innerHTML = `<i class="fa-solid fa-spinner fa-spin"></i> <span>Downloading...</span>`;
    }
    
    for (let i = 0; i < images.length; i++) {
      const img = images[i];
      const imageUrl = img.getAttribute('data-src') || img.src;
      
      if (!imageUrl) continue;
      
      try {
        await downloadImage(imageUrl, `image-${i + 1}`);
        await new Promise(resolve => setTimeout(resolve, 300));
      } catch (err) {
        console.error('Download failed:', err);
      }
    }
    
    if (button) {
      button.disabled = false;
      button.innerHTML = `${CONFIG.buttonIcon} <span>${CONFIG.buttonText}</span>`;
    }
  }

  async function downloadImage(imageUrl, fallbackName) {
    try {
      const response = await fetch(imageUrl, { mode: 'cors' });
      if (!response.ok) throw new Error('Network response was not ok');
      
      const blob = await response.blob();
      const blobUrl = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.style.display = 'none';
      link.href = blobUrl;
      
      try {
        link.download = (new URL(imageUrl)).pathname.split('/').pop() || fallbackName;
      } catch (e) {
        link.download = fallbackName;
      }
      
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      setTimeout(() => URL.revokeObjectURL(blobUrl), 1500);
    } catch (err) {
      console.warn('Could not fetch blob for download:', err);
      window.open(imageUrl, '_blank', 'noopener');
    }
  }

  function addDownloadIconsToGallery() {
    const slides = document.querySelectorAll('.sqs-gallery-design-grid-slide');
    
    slides.forEach(slide => {
      const marginWrapper = slide.querySelector('.margin-wrapper');
      const imgElement = slide.querySelector('img[data-src], img[src]');
      
      if (!marginWrapper || !imgElement) return;
      
      if (marginWrapper.querySelector('.download-icon')) return;
      
      const downloadIcon = document.createElement('div');
      downloadIcon.className = 'download-icon';
      downloadIcon.innerHTML = CONFIG.downloadIcon;
      
      marginWrapper.style.position = 'relative';
      marginWrapper.appendChild(downloadIcon);
      
      downloadIcon.addEventListener('click', async (e) => {
        e.preventDefault();
        e.stopPropagation();
        
        const imageUrl = imgElement.getAttribute('data-src') || imgElement.src;
        if (!imageUrl) return;
        
        await downloadImage(imageUrl, 'gallery-image');
      });
    });
  }

  function init() {
    addDownloadAllButton();
    addDownloadIconsToGallery();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
  
  window.addEventListener('mercury:load', init);
})();
</script>

<style>
.download-all-btn-wrapper {
  margin-bottom: 20px;
  text-align: right;
}

.download-all-btn {
  background: #000;
  color: #fff;
  border: none;
  padding: 12px 24px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
}

.download-all-btn:hover {
  background: #333;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}

.download-all-btn:active {
  transform: translateY(0);
}

.download-all-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.download-all-btn i {
  font-size: 16px;
}

.download-icon {
  position: absolute;
  z-index: 999;
  cursor: pointer;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity 0.3s ease;
  font-size: 48px;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,0,0,0.3);
  pointer-events: none;
}

.download-icon:hover {
  color: #4CAF50;
}

.margin-wrapper:hover .download-icon {
  opacity: 1;
  pointer-events: auto;
}

@media (max-width: 768px) {
  .download-all-btn-wrapper {
    text-align: center;
  }
  
  .download-icon {
    font-size: 36px;
  }
}
</style>

01.26c29v5

#2. How to download all images

First, click on button Download all images

01.26c29v5

Click Allow

01.26c29v5

Buy me a coffee