You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Umbraco v13中实现按钮触发的分类图片动态过滤渲染的方案与最佳实践

Umbraco v13中实现按钮触发的分类图片动态过滤渲染的方案与最佳实践

嘿,针对你在Umbraco v13里遇到的图片分类动态过滤问题,我来分享一套实用的实现方案和最佳实践,帮你搞定高效的无刷新过滤,同时完美适配Umbraco的后台配置~

一、先把Umbraco后台数据结构捋顺(基础中的基础)

首先要确保你的图片和分类的关联逻辑符合Umbraco的内容管理规范,避免后期维护头疼:

  • 创建ImageCategory文档类型:用来管理所有分类(比如Festival、Sports、Activity),可以只加一个Name字段,后台创建对应的分类节点。
  • 创建GalleryImage文档类型:包含两个核心字段:
    • GalleryMedia:Media Picker类型,用来选择要展示的图片
    • ImageCategory:Content Picker类型,关联到刚才创建的ImageCategory节点(或者用Dropdown List预定义固定分类,看你是否需要动态新增分类)
  • 创建GalleryPage文档类型:设置为允许包含GalleryImage子节点,这样编辑人员可以在后台直接给这个页面添加图片和分类。

二、改进Razor视图:从硬编码到动态生成(适配Umbraco数据)

你之前的代码里硬编码了按钮和图片路径,这在Umbraco里完全没必要,我们可以直接从CMS数据动态生成所有内容,后期修改分类或图片都不用改代码:

@{
    // 获取当前GalleryPage下的所有GalleryImage子节点
    var galleryImages = Model.ChildrenOfType("GalleryImage").ToList();
    // 获取所有唯一的分类(这里假设ImageCategory字段存的是分类节点的名称,你也可以用别名)
    var categories = galleryImages
        .Select(x => x.Value<IPublishedContent>("imageCategory")?.Name)
        .Distinct()
        .Where(name => !string.IsNullOrEmpty(name))
        .ToList();
}

<!-- 动态生成过滤按钮 -->
<ul class="uk-navbar-nav">
    <li class="uk-active" uk-filter-control=""><a href="#">All</a></li>
    @foreach (var category in categories)
    {
        <li uk-filter-control="[data-filter='@category']">
            <a href="#">@category</a>
        </li>
    }
</ul>

<!-- 动态生成图片列表 -->
<ul class="img-gallery-container js-filter uk-child-width-1-2 uk-child-width-1-3@m uk-text-center" uk-grid>
    @foreach (var image in galleryImages)
    {
        var mediaItem = image.Value<IPublishedContent>("galleryMedia");
        // 使用Umbraco的ImageProcessor生成缩略图,提升加载速度
        var imgUrl = mediaItem?.GetCropUrl(width: 600, height: 400) ?? "";
        var categoryName = image.Value<IPublishedContent>("imageCategory")?.Name ?? "";
        var altText = image.Value<string>("imageAltText") ?? "Gallery image";

        <li data-filter="@categoryName">
            <img src="@imgUrl" alt="@altText" class="img-gal">
        </li>
    }
</ul>

三、优化JS逻辑:提升大量图片的过滤效率

你之前的hover交互效果很棒,但针对大量图片的过滤,我们可以做一些优化,同时确保逻辑更健壮:

// 缓存DOM元素,避免重复查询
const galleryContainer = document.querySelector('.img-gallery-container');
const filterButtons = document.querySelectorAll('.uk-navbar-nav li');
const imgItems = galleryContainer.querySelectorAll('li');

// 封装图片交互事件的绑定函数
function bindImageInteractions(imgEl) {
    const height = imgEl.clientHeight;
    const width = imgEl.clientWidth;

    const handleMove = (e) => {
        const xVal = e.layerX;
        const yVal = e.layerY;
        const yRotation = 20 * ((xVal - width / 2) / width);
        const xRotation = -20 * ((yVal - height / 2) / height);
        imgEl.style.transform = `perspective(500px) scale(1.01) rotateX(${xRotation}deg) rotateY(${yRotation}deg)`;
    };

    imgEl.addEventListener('mousemove', handleMove);
    imgEl.addEventListener('mouseout', () => {
        imgEl.style.transform = 'perspective(500px) scale(1) rotateX(0) rotateY(0)';
    });
    imgEl.addEventListener('mousedown', () => {
        imgEl.style.transform = 'perspective(500px) scale(0.9) rotateX(0) rotateY(0)';
    });
    imgEl.addEventListener('mouseup', () => {
        imgEl.style.transform = 'perspective(500px) scale(1.1) rotateX(0) rotateY(0)';
    });
}

// 给所有图片绑定交互事件
galleryContainer.querySelectorAll('.img-gal').forEach(bindImageInteractions);

// 自定义过滤逻辑(如果不想依赖UIkit的filter组件,也可以自己实现)
filterButtons.forEach(button => {
    button.addEventListener('click', (e) => {
        e.preventDefault();
        // 更新按钮激活状态
        filterButtons.forEach(btn => btn.classList.remove('uk-active'));
        button.classList.add('uk-active');
        
        // 获取当前要过滤的分类
        const filterValue = button.getAttribute('uk-filter-control')?.replace(/\[data-filter='(.*)'\]/, '$1') || '';
        
        // 批量处理图片显示/隐藏,比逐个操作更高效
        imgItems.forEach(item => {
            item.style.display = !filterValue || item.getAttribute('data-filter') === filterValue ? 'block' : 'none';
        });
    });
});

四、Umbraco专属最佳实践

  1. 性能优化:

    • 始终使用GetCropUrl()生成缩略图,避免加载原图,Umbraco的ImageProcessor会自动缓存裁剪后的图片
    • 给GalleryPage启用输出缓存,在后台设置缓存时长,减少服务器重复渲染的压力
    • 如果图片数量超过100张,考虑实现懒加载,结合Umbraco的loading="lazy"属性或者第三方懒加载库
  2. 后台易用性:

    • 在GalleryImage文档类型里把ImageCategory和GalleryMedia设为必填字段,避免编辑人员遗漏信息
    • 如果分类是固定的,用Dropdown List代替Content Picker,减少编辑操作步骤
  3. 可维护性:

    • 把过滤按钮和图片列表抽成独立的Partial View(比如_GalleryFilterButtons.cshtml和_GalleryImages.cshtml),方便在其他页面复用
    • 把JS逻辑封装成单独的模块文件(比如gallery-filter.js),不要直接写在Razor视图里,便于调试和维护

备注:内容来源于stack exchange,提问作者Test 1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:43:04