在blogger页面生成博客图片墙代码

person 元章 event 2026-07-29 local_offer 代码

        在blogger页面生成博客图片墙:
        1.完美 4 列布局:使用 grid-template-columns: repeat(4, 1fr); 确保大屏幕下始终为 4 列。
        2.正方形美化:使用 aspect-ratio: 1/1; 解决图片长宽不一导致参差不齐的问题,让照片墙像 Instagram 一样整齐。
        3.原图加载:代码会通过 s0 参数向 Google 请求你上传的原始文件,彻底告别模糊。
        4.智能过滤:不仅会过滤掉没图的文章,还会过滤掉透明像素点(一些统计插件自带的图片)。
        5.手机适配:手机上会自动切换为 2 列或 1 列,不会因为太拥挤而看不清。
        代码如下:

代码展示
<!-- Blogger 高清自适应照片墙 - 完整版 -->

<!-- 1. 结构层 -->
<div id="photo-wall-container">
  <!-- 标签导航 -->
  <div id="label-filter">
    <button class="filter-btn active" onclick="filterGallery('all', this)">全部照片</button>
  </div>
  
  <!-- 照片网格 -->
  <div id="photo-wall">正在深度抓取原图高清照片...</div>
</div>

<!-- 2. 样式层 -->
<style>
  /* 容器基本设置 */
  #photo-wall-container {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px 10px;
  }

  /* 标签过滤器样式 */
  #label-filter {
    text-align: center;
    margin-bottom: 30px;
  }
  .filter-btn {
    background: #f4f4f4;
    border: none;
    padding: 10px 20px;
    margin: 5px;
    cursor: pointer;
    border-radius: 50px;
    font-size: 14px;
    transition: all 0.3s ease;
    color: #555;
  }
  .filter-btn:hover { background: #e0e0e0; }
  .filter-btn.active {
    background: #333;
    color: #fff;
    box-shadow: 0 4px 10px rgba(0,0,0,0.2);
  }

  /* 照片墙核心布局:每行 4 张 */
  #photo-wall {
    display: grid;
    /* 核心:分成4列,每列宽度相等 */
    grid-template-columns: repeat(4, 1fr);
    grid-gap: 15px; /* 图片之间的间距 */
  }

  /* 单个照片项目 */
  .photo-item {
    position: relative;
    aspect-ratio: 1 / 1; /* 强制图片为正方形,看起来最整齐 */
    overflow: hidden;
    border-radius: 10px;
    background: #eee;
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  }

  .photo-item img {
    width: 100%;
    height: 100%;
    object-fit: cover; /* 自动裁剪以填充容器 */
    display: block;
    transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
    image-rendering: -webkit-optimize-contrast; /* 提高渲染锐度 */
  }

  /* 悬停效果 */
  .photo-item:hover img {
    transform: scale(1.1);
  }

  /* 标题遮罩层 */
  .photo-info {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: linear-gradient(transparent, rgba(0,0,0,0.7));
    color: #fff;
    padding: 15px 10px;
    font-size: 13px;
    text-align: center;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  .photo-item:hover .photo-info {
    opacity: 1;
  }

  /* 隐藏项 */
  .hidden {
    display: none !important;
  }

  /* --- 响应式适配 --- */

  /* 平板:每行显示 3 张 */
  @media (max-width: 1024px) {
    #photo-wall { grid-template-columns: repeat(3, 1fr); }
  }

  /* 大屏幕手机:每行显示 2 张 */
  @media (max-width: 768px) {
    #photo-wall { grid-template-columns: repeat(2, 1fr); grid-gap: 10px; }
    .filter-btn { padding: 8px 15px; font-size: 12px; }
  }

  /* 小屏幕手机:每行显示 1 张 */
  @media (max-width: 480px) {
    #photo-wall { grid-template-columns: repeat(1, 1fr); }
  }
</style>

<!-- 3. 脚本层 -->
<script>
/**
 * 核心功能:获取真正的高清图片地址
 */
function getUltraHighRes(entry) {
  let imgUrl = "";

  // 策略1:优先从文章 HTML 正文中提取第一张图片(原图)
  if (entry.content && entry.content.$t) {
    const content = entry.content.$t;
    const match = content.match(/<img[^>]+src="([^">]+)"/);
    if (match && match[1]) {
      imgUrl = match[1];
    }
  }

  // 策略2:备选缩略图
  if (!imgUrl && entry.media$thumbnail) {
    imgUrl = entry.media$thumbnail.url;
  }

  if (imgUrl) {
    // 强制去除 Google 的压缩参数,获取 s0 (原始尺寸)
    // 兼容 /s72-c/ 和 =w120 两种格式
    imgUrl = imgUrl.replace(/\/s[0-9]+(-[a-z])?\//, '/s0/');
    if (imgUrl.indexOf('=') > -1) {
      imgUrl = imgUrl.split('=')[0] + '=s0';
    }
    return imgUrl.replace('http://', 'https://');
  }
  return null;
}

/**
 * 渲染照片墙
 */
function renderBloggerGallery(json) {
  const wall = document.getElementById('photo-wall');
  const filterBar = document.getElementById('label-filter');
  const entries = json.feed.entry || [];
  
  let html = '';
  let allLabels = new Set();
  let count = 0;

  entries.forEach(entry => {
    const imgUrl = getUltraHighRes(entry);

    // 关键过滤:如果没有图片,或者图片是占位符,则跳过文章
    if (!imgUrl || imgUrl.includes('blank.gif') || imgUrl.includes('pixel.gif')) return;

    // 提取标签
    const labels = entry.category ? entry.category.map(cat => cat.term) : [];
    labels.forEach(l => allLabels.add(l));
    
    // 生成分类 Class
    const labelClasses = labels.map(l => `tag-${l.replace(/\s+/g, '-')}`).join(' ');
    const title = entry.title.$t;
    const link = entry.link.find(l => l.rel === 'alternate').href;

    html += `
      <div class="photo-item ${labelClasses}">
        <a href="${link}" target="_blank">
          <img src="${imgUrl}" alt="${title}" loading="lazy">
          <div class="photo-info">${title}</div>
        </a>
      </div>
    `;
    count++;
  });

  if (count === 0) {
    wall.innerHTML = "未发现包含图片的文章。请确保后台“站点供稿”已设置为“完整”。";
    return;
  }

  wall.innerHTML = html;

  // 动态创建标签按钮
  allLabels.forEach(label => {
    const btn = document.createElement('button');
    btn.className = 'filter-btn';
    btn.innerText = label;
    btn.onclick = function() { filterGallery(`tag-${label.replace(/\s+/g, '-')}`, this); };
    filterBar.appendChild(btn);
  });
}

/**
 * 标签过滤逻辑
 */
function filterGallery(tag, btn) {
  // 更新按钮高亮
  document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
  btn.classList.add('active');

  // 切换图片显示
  const items = document.querySelectorAll('.photo-item');
  items.forEach(item => {
    if (tag === 'all' || item.classList.contains(tag)) {
      item.classList.remove('hidden');
    } else {
      item.classList.add('hidden');
    }
  });
}

/**
 * 自动执行加载
 */
(function() {
  const script = document.createElement('script');
  const blogUrl = window.location.origin;
  // 获取最近的 150 篇文章
  script.src = `${blogUrl}/feeds/posts/default?alt=json-in-script&callback=renderBloggerGallery&max-results=150`;
  document.body.appendChild(script);
})();
</script>

copyright 版权声明

相关文章