// 获取所有文件
const pages = dv.pages();
// 获取所有标签的函数
function getTags(file) {
if (!file.tags) return [];
try {
if (Array.isArray(file.tags)) return file.tags;
if (typeof file.tags === 'string') {
return file.tags.split(/[,,、\s]+/).map(t => t.trim()).filter(t => t);
}
return [];
} catch (e) {
console.error("解析标签出错:", e);
return [];
}
}
// 收集所有唯一标签
let allTags = [...new Set(
pages.flatMap(p => getTags(p))
.filter(tag => tag && typeof tag === 'string')
)].sort();
// 添加"全部文件"选项
allTags.unshift("全部文件");
// 创建下拉选择器
const select = dv.el("select", "", {
style: `
margin: 15px 0;
padding: 8px 12px;
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
background: var(--background-primary);
color: var(--text-normal);
width: 200px;
`
});
// 添加选项
allTags.forEach(tag => {
const option = dv.el("option", tag);
option.value = tag;
select.append(option);
});
// 创建唯一的结果容器
const results = dv.el("div", "", {
style: "margin-top: 20px;"
});
// 创建表格容器(使用原生HTML表格)
const tableContainer = dv.el("div", "", {
style: "width: 100%; overflow-x: auto;"
});
results.append(tableContainer);
// 创建表格元素
const table = document.createElement("table");
table.style.width = "100%";
table.style.borderCollapse = "collapse";
tableContainer.append(table);
// 创建表头
const thead = document.createElement("thead");
table.append(thead);
const headerRow = document.createElement("tr");
thead.append(headerRow);
["文件", "标签", "创建日期"].forEach(text => {
const th = document.createElement("th");
th.textContent = text;
th.style.padding = "8px 12px";
th.style.borderBottom = "1px solid var(--background-modifier-border)";
th.style.textAlign = "left";
headerRow.append(th);
});
// 创建表体
const tbody = document.createElement("tbody");
table.append(tbody);
// 更新显示的函数
function updateResults(selectedTag) {
// 清空表格内容
tbody.innerHTML = '';
let filteredPages = selectedTag === "全部文件"
? pages
: pages.filter(p => getTags(p).includes(selectedTag));
// 填充表格内容
if (filteredPages.length > 0) {
filteredPages.forEach(p => {
const row = document.createElement("tr");
row.style.borderBottom = "1px solid var(--background-modifier-border)";
// 文件链接 - 修改为双链格式
const fileCell = document.createElement("td");
fileCell.style.padding = "8px 12px";
// 使用Obsidian双链格式 [[文件名]]
const link = dv.el("span", `[[${p.file.name}]]`);
fileCell.append(link);
row.append(fileCell);
// 标签
const tagsCell = document.createElement("td");
tagsCell.style.padding = "8px 12px";
tagsCell.textContent = getTags(p).join(", ");
row.append(tagsCell);
// 创建日期
const dateCell = document.createElement("td");
dateCell.style.padding = "8px 12px";
dateCell.textContent = p.file.ctime ? new Date(p.file.ctime).toLocaleDateString() : "无日期";
row.append(dateCell);
tbody.append(row);
});
} else {
const row = document.createElement("tr");
const cell = document.createElement("td");
cell.colSpan = 3;
cell.textContent = "没有找到匹配的文件";
cell.style.color = "var(--text-muted)";
cell.style.fontStyle = "italic";
cell.style.padding = "12px";
cell.style.textAlign = "center";
row.append(cell);
tbody.append(row);
}
}
// 事件监听
select.addEventListener("change", (e) => {
updateResults(e.target.value);
});
// 初始渲染
dv.container.append(select, results);
updateResults(select.value);
该代码能够对仓库中的笔记进行检索,并支持下拉式按键搜索对应标签的笔记。
DataviewJS 下拉筛选菜单搜索功能 - 经验分享 - Obsidian 中文论坛
!!!本代码基于上面文章中的代码,由AI进行更改,可能会由于某些未知错误无法生成或出现不符合预期的情况,需要各位自行解决。
感谢论坛大佬对相关代码的研究和分享。