用AI写的瀑布流,标签检索,dataviewjs

```dataviewjs
// 获取所有带有#笔记标签的文档
let pages = dv.pages('#你的标签')
    .sort(file => file.file.mtime, 'desc')
    .filter(file => file.file);

// 异步获取文件内容
async function getFileContent(file) {
    try {
        if (file.content) return file.content;
        const content = await dv.io.load(file.path);
        return content || "无法获取内容";
    } catch (e) {
        console.error("读取文件内容失败:", e);
        return "无法获取内容";
    }
}

// 创建瀑布流容器
const masonryContainer = dv.el('div', '', {cls: 'masonry-container'});
masonryContainer.style.columnCount = '2'; // 两列布局
masonryContainer.style.columnGap = '15px'; // 列间距

// 创建瀑布流卡片
function createMasonryCard(file, content) {
    const card = dv.el('div', '', {cls: 'masonry-card'});
    card.style.breakInside = 'avoid'; // 防止卡片跨列断裂
    card.style.boxSizing = 'border-box';
    card.style.padding = '15px';
    card.style.marginBottom = '15px'; // 卡片间距
    card.style.borderRadius = '8px';
    card.style.backgroundColor = 'var(--background-primary)';
    card.style.border = '1px solid var(--background-modifier-border)';
    card.style.display = 'inline-block'; // 重要:瀑布流布局需要
    card.style.width = '100%'; // 占满容器宽度
    
    // 添加文档标题和链接
    const title = dv.el('h3', dv.fileLink(file.path, false, file.name));
    title.style.marginTop = '0';
    title.style.marginBottom = '10px';
    card.appendChild(title);
    
    // 添加预览内容
    let preview = content;
    if (preview.length > 200) {
        preview = preview.substring(0, 200) + '...';
    }
    
    const previewDiv = dv.el('div', preview);
    previewDiv.style.lineHeight = '1.5';
    previewDiv.style.color = 'var(--text-normal)';
    card.appendChild(previewDiv);
    
    return card;
}

// 异步渲染所有文档
(async function() {
    for (let page of pages) {
        if (!page?.file) continue;
        
        const content = await getFileContent(page.file);
        const card = createMasonryCard(page.file, content);
        masonryContainer.appendChild(card);
    }
})();

需要安装dataview 并开启js

下面还有两段跟标题有关的瀑布流

这个是将标签下的所有文件的H2 和H3列出来
H2作为标题
H3作为正文

```dataviewjs
// == H2驱动的瀑布式卡片系统 ==
// 自动提取#样式标签下的所有H2/H3结构,每个H2生成独立卡片

// 配置区 - 可自定义参数
const CONFIG = {
    columns: 2,                  // 瀑布流列数
    cardStyle: {                 // 卡片样式
        border: "1px solid var(--background-modifier-border)",
        borderRadius: "12px",
        padding: "16px",
        marginBottom: "20px",
        background: "var(--background-primary)",
        boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
        breakInside: "avoid"     // 防止卡片跨列断裂
    },
    h2Style: {                  // H2标题样式
        fontSize: "1.3em",
        fontWeight: "600",
        margin: "0 0 12px 0",
        color: "var(--text-accent)",
        borderBottom: "2px solid var(--background-modifier-border)",
        paddingBottom: "8px"
    },
    h3Style: {                  // H3条目样式
        listStyle: "none",
        padding: "8px 0",
        margin: "0",
        fontSize: "1em",
        color: "var(--text-normal)"
    },
    tagFilter: "#你的标题"           // 要筛选的标签
};

// == 主函数 ==
async function renderH2Cards() {
    // 创建瀑布流容器
    const container = dv.el("div", "", {
        attr: { 
            style: `
                column-count: ${CONFIG.columns};
                column-gap: 20px;
                margin-top: 20px;
            `
        }
    });
    
    // 获取所有带标签的文件
    const files = dv.pages(CONFIG.tagFilter).file;
    
    // 收集所有H2卡片
    let allCards = [];
    
    // 并行处理所有文件内容
    const processing = files.map(async file => {
        const content = await dv.io.load(file.path);
        const cards = createH2Cards(content);
        allCards = allCards.concat(cards);
    });
    
    await Promise.all(processing);
    
    // 随机排序卡片(可选,取消注释启用)
    // allCards = allCards.sort(() => Math.random() - 0.5);
    
    // 渲染所有卡片
    allCards.forEach(card => container.appendChild(card));
    
    // 显示卡片总数
    dv.paragraph(`共生成 <strong>${allCards.length}</strong> 个内容卡片`);
}

// == 卡片生成函数 ==
function createH2Cards(content) {
    const cards = [];
    const lines = content.split('\n');
    let currentH2 = null;
    let currentH3s = [];
    
    for (const line of lines) {
        if (line.startsWith('## ')) { // 遇到H2标题
            // 保存上一个卡片
            if (currentH2) {
                cards.push(createCard(currentH2, currentH3s));
                currentH3s = [];
            }
            currentH2 = line.replace('## ', '').trim();
        } 
        else if (line.startsWith('### ') && currentH2) { // 遇到H3标题
            currentH3s.push(line.replace('### ', '').trim());
        }
    }
    
    // 添加最后一个卡片
    if (currentH2) {
        cards.push(createCard(currentH2, currentH3s));
    }
    
    return cards;
}

// == 创建单个卡片 ==
function createCard(h2Title, h3Items) {
    const card = dv.el("div", "", {
        attr: { 
            style: `
                display: inline-block;
                width: 100%;
                ${Object.entries(CONFIG.cardStyle).map(([k,v]) => `${k}:${v}`).join(';')}
            `
        }
    });
    
    // 添加H2标题
    card.appendChild(dv.el("h3", h2Title, {
        attr: { style: Object.entries(CONFIG.h2Style).map(([k,v]) => `${k}:${v}`).join(';') }
    }));
    
    // 添加H3内容
    if (h3Items.length > 0) {
        const ul = dv.el("ul", "", { attr: { style: "padding-left:0; margin:0;" } });
        h3Items.forEach(item => {
            ul.appendChild(dv.el("li", item, {
                attr: { style: Object.entries(CONFIG.h3Style).map(([k,v]) => `${k}:${v}`).join(';') }
            }));
        });
        card.appendChild(ul);
    }
    
    return card;
}

// == 执行渲染 ==
dv.header(2, `H2内容卡片集 #${CONFIG.tagFilter.substring(1)}`);
renderH2Cards();

这个在上面的基础上带出处

```dataviewjs
// == 带来源的H2瀑布卡片系统 ==
// 每个H2生成独立卡片,底部显示小字号的来源文件名

// 配置区 - 可自定义参数
const CONFIG = {
    columns: 3,                  // 瀑布流列数
    cardStyle: {                 // 卡片样式
        border: "1px solid var(--background-modifier-border)",
        borderRadius: "12px",
        padding: "16px",
        marginBottom: "20px",
        background: "var(--background-primary)",
        boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
        breakInside: "avoid",
        position: "relative"     // 为来源标签定位
    },
    h2Style: {                  // H2标题样式
        fontSize: "1.3em",
        fontWeight: "600",
        margin: "0 0 12px 0",
        color: "var(--text-accent)",
        borderBottom: "2px solid var(--background-modifier-border)",
        paddingBottom: "8px"
    },
    h3Style: {                  // H3条目样式
        listStyle: "none",
        padding: "8px 0",
        margin: "0",
        fontSize: "1em",
        color: "var(--text-normal)"
    },
    sourceStyle: {              // 来源文件名样式
        fontSize: "0.8em",
        color: "var(--text-faint)",
        textAlign: "right",
        marginTop: "12px",
        paddingTop: "8px",
        borderTop: "1px dashed var(--background-modifier-border)"
    },
    tagFilter: "#你的标题"           // 要筛选的标签
};

// == 主函数 ==
async function renderH2CardsWithSource() {
    // 创建瀑布流容器
    const container = dv.el("div", "", {
        attr: { 
            style: `
                column-count: ${CONFIG.columns};
                column-gap: 20px;
                margin-top: 20px;
            `
        }
    });
    
    // 获取所有带标签的文件
    const files = dv.pages(CONFIG.tagFilter).file;
    
    // 收集所有H2卡片
    let allCards = [];
    
    // 并行处理所有文件内容
    const processing = files.map(async file => {
        const content = await dv.io.load(file.path);
        const cards = createH2Cards(content, file);
        allCards = allCards.concat(cards);
    });
    
    await Promise.all(processing);
    
    // 渲染所有卡片
    allCards.forEach(card => container.appendChild(card));
    
    // 显示卡片总数
    dv.paragraph(`共生成 <strong>${allCards.length}</strong> 个内容卡片`);
}

// == 卡片生成函数 ==
function createH2Cards(content, file) {
    const cards = [];
    const lines = content.split('\n');
    let currentH2 = null;
    let currentH3s = [];
    
    for (const line of lines) {
        if (line.startsWith('## ')) { // 遇到H2标题
            // 保存上一个卡片
            if (currentH2) {
                cards.push(createCard(currentH2, currentH3s, file));
                currentH3s = [];
            }
            currentH2 = line.replace('## ', '').trim();
        } 
        else if (line.startsWith('### ') && currentH2) { // 遇到H3标题
            currentH3s.push(line.replace('### ', '').trim());
        }
    }
    
    // 添加最后一个卡片
    if (currentH2) {
        cards.push(createCard(currentH2, currentH3s, file));
    }
    
    return cards;
}

// == 创建单个卡片(带来源) ==
function createCard(h2Title, h3Items, file) {
    const card = dv.el("div", "", {
        attr: { 
            style: `
                display: inline-block;
                width: 100%;
                ${Object.entries(CONFIG.cardStyle).map(([k,v]) => `${k}:${v}`).join(';')}
            `
        }
    });
    
    // 添加H2标题
    card.appendChild(dv.el("h3", h2Title, {
        attr: { style: Object.entries(CONFIG.h2Style).map(([k,v]) => `${k}:${v}`).join(';') }
    }));
    
    // 添加H3内容
    if (h3Items.length > 0) {
        const ul = dv.el("ul", "", { attr: { style: "padding-left:0; margin:0;" } });
        h3Items.forEach(item => {
            ul.appendChild(dv.el("li", item, {
                attr: { style: Object.entries(CONFIG.h3Style).map(([k,v]) => `${k}:${v}`).join(';') }
            }));
        });
        card.appendChild(ul);
    }
    
    // 添加来源文件名(小字号)
    const source = dv.el("div", `来源: ${file.name.replace('.md', '')}`, {
        attr: { style: Object.entries(CONFIG.sourceStyle).map(([k,v]) => `${k}:${v}`).join(';') }
    });
    card.appendChild(source);
    
    return card;
}

// == 执行渲染 ==
dv.header(2, `H2内容卡片集 #${CONFIG.tagFilter.substring(1)}`);
renderH2CardsWithSource();