和弦间

# ]吉他谱

Song Index [ V · 原调 f · 最后更新

font-family: Arial, sans-serif;

/* ADJUST HERE: line spacing — top/bottom padding between song entries */

/* ADJUST HERE: entry font size — controls every song title's size */

/* ADJUST HERE: back-to-top button position, size, and colors */

A – E

F – J

var root = document.getElementById("ch-index-root");

var searchBox = root.querySelector(".ch-search");

var refreshBtn = root.querySelector(".ch-refresh");

var statusEl = root.querySelector(".ch-status");

var alphaNavEl = root.querySelector(".ch-alpha-nav");

var resultsEl = root.querySelector(".ch-results");

var backToTopBtn = root.querySelector(".ch-back-to-top");

// ---- THIS PAGE'S LETTER RANGE ----

// ADJUST HERE if you re-split the pages differently.

var RANGE_START = "V";

var RANGE_END = "Z";

var INCLUDE_HASH = true; // true only on the last page, to catch non-Latin/symbol titles

var PAGE_LABEL = "V – #";

// ADJUST HERE: how far down the page (in px) before the button appears

var BACK_TO_TOP_SHOW_AFTER = 400;

window.addEventListener("scroll", function () {

if (window.scrollY > BACK_TO_TOP_SHOW_AFTER) {

backToTopBtn.classList.add("ch-visible");

backToTopBtn.classList.remove("ch-visible");

backToTopBtn.addEventListener("click", function () {

var CACHE_KEY = "chIndexCacheV3";

var PAGE_SIZE = 150; // Blogger's feed page cap

// ---- EDIT THESE TWO LISTS to keep non-song posts out of the index ----

// Any post whose labels include one of these (case-insensitive) is skipped.

var EXCLUDE_LABELS = ["Not a Song", "Announcement", "Site Update", "blog", "gos", "lessons", "misc"];

// Any post whose TITLE matches one of these patterns is skipped, no label needed.

var EXCLUDE_TITLE_PATTERNS = [

function isExcluded(title, labels) {

var lowerLabels = labels.map(function (l) { return l.toLowerCase(); });

for (var i = 0; i  1 ? parts[0].trim().toLowerCase() : "";

statusEl.textContent = msg || "";

var url = "/feeds/posts/summary?alt=json&max-results=" + PAGE_SIZE + "&start-index=" + startIndex;

if (!res.ok) throw new Error("Feed request failed (" + res.status + ")");

function fetchAllPosts() {

var excludedCount = 0;

entries.forEach(function (entry) {

(entry.link || []).forEach(function (l) {

if (isExcluded(title, labels)) {

excludedCount++;

// Blogger can return a short page even when more posts remain.

console.log("[ch-index] page : raw +" + gotThisPage + " (raw total " + rawSeen + " / reported " + total + "), kept " + allPosts.length + ", excluded " + excludedCount);

return step(1 + PAGE_SIZE, total);

console.log("[ch-index] page @" + startIndex + ": raw +" + gotThisPage + " (raw total " + rawSeen + " / reported " + total + "), kept " + allPosts.length + ", excluded " + excludedCount);

return step(startIndex + PAGE_SIZE, total);

var cached = JSON.parse(sessionStorage.getItem(CACHE_KEY) || "null");

setStatus(rangeCount(allPosts) + " songs \u00B7 " + PAGE_LABEL + " \u00B7 cached this session (" + new Date(cached.time).toLocaleTimeString() + ")");

resultsEl.innerHTML = "";

fetchAllPosts()

var singerA = getSinger(a.title);

var singerB = getSinger(b.title);

if (singerA && singerA === singerB) {

return stripLeadingArticle(a.title).length - stripLeadingArticle(b.title).length;

return stripLeadingArticle(a.title).localeCompare(stripLeadingArticle(b.title));

sessionStorage.setItem(CACHE_KEY, JSON.stringify({ posts: allPosts, time: Date.now() }));

setStatus(rangeCount(allPosts) + " songs \u00B7 " + PAGE_LABEL);

setStatus("Couldn't load the song list (" + err.message + "). Try Refresh list.");

q = q.toLowerCase();

if (post.title.toLowerCase().indexOf(q) !== -1) return true;

return post.labels.some(function (l) { return l.toLowerCase().indexOf(q) !== -1; });

var t = stripLeadingArticle(title).trim();

var c = t.charAt(0);

if (/[A-Za-z]/.test(c)) return c.toUpperCase();

// Chinese character: convert to its pinyin initial (with surname-aware

var letter = (initials && initials[0] || "").charAt(0).toUpperCase();

if (/[A-Z]/.test(letter)) return letter;

// Does this post's group key fall on THIS split page?

if (key === "#") return INCLUDE_HASH;

return key >= RANGE_START && key No songs match \u201C' + q + '\u201D.';

renderAlpha(filtered);

function renderAlpha(posts) {

alphaNavEl.innerHTML = "";

resultsEl.innerHTML = 'No matches in this range (' + PAGE_LABEL + '). Try another page.';

inRange.forEach(function (p) {

return a.localeCompare(b);

alphaNavEl.innerHTML = keys.map(function (k) {

resultsEl.innerHTML = keys.map(function (k) {

searchBox.addEventListener("input", function () { render(); });

refreshBtn.addEventListener("click", function () { loadPosts(true); });