MediaWiki:Timeless.js:修订间差异

来自「荏苒之境」
无编辑摘要
无编辑摘要
第12行: 第12行:
         this.collectHeadings();
         this.collectHeadings();
         window.addEventListener('resize', () => this.cacheExpired = true);
         window.addEventListener('resize', () => this.cacheExpired = true);
         window.addEventListener('DOMContentLoaded', () => {
         window.addEventListener('DOMContentLoaded', () => this.cacheExpired = true);
        this.cacheExpired = true;
        console.log("Hello world");
        });
     }
     }


第49行: 第46行:
}
}


let toc = document.getElementById('toc');
class FloatingToC {
let siteNavigation = document.getElementById('mw-site-navigation');
constructor(toc) {
this.ignoreScrollUpdate = false;
   
    let tocTextList = Array.from(toc.querySelectorAll(".toctext"));
    this.tocTexts = new Map(tocTextList.map(t => {
    let textContent = t.textContent
    t.parentElement.onclick = () => {
    this.ignoreScrollUpdate = true;
    this.setCurrentHeading(textContent);
    };
    return [textContent, t];
    }));


if (toc && siteNavigation) {
this.tracker = new HeadingTracker(
    toc.parentNode.removeChild(toc);
document.getElementById('mw-content-text'));
    siteNavigation.appendChild(toc);
   
window.addEventListener('scroll', this.onScroll);
    var ignoreScrollUpdate
}
    var lastHeading
     var setCurrentHeading
     setCurrentHeading(heading) {
   
     const heading = this.heading;
    let tocTextList = Array.from(toc.querySelectorAll(".toctext"))
     const lastHeading = this.lastHeading;
    let tocTexts = new Map(tocTextList.map(t => {
    
     let textContent = t.textContent
     t.parentElement.onclick = () => {
    ignoreScrollUpdate = true;
    setCurrentHeading(textContent);
    };
     return [textContent, t];
    }));
   
    setCurrentHeading = heading => {
     if (heading == lastHeading) {
     if (heading == lastHeading) {
     return;
     return;
     }
     }
     if (lastHeading) {
     if (lastHeading) {
     let text = tocTexts.get(lastHeading)
     let text = this.tocTexts.get(lastHeading)
     if (text) text.classList.remove('current-heading');
     if (text) text.classList.remove('current-heading');
     }
     }
     lastHeading = heading;
     this.lastHeading = heading;
     if (heading) {
     if (heading) {
     let text = tocTexts.get(heading)
     let text = this.tocTexts.get(heading)
     if (text) text.classList.add('current-heading');
     if (text) text.classList.add('current-heading');
     }
     }
     };
     };
   
let tracker = new HeadingTracker(
document.getElementById('mw-content-text'));
window.addEventListener('scroll', () => {
onScroll() {
if (window.innerWidth < 1100) {
if (window.innerWidth < 1100) {
return;
return;
}
}
if (ignoreScrollUpdate) {
if (this.ignoreScrollUpdate) {
ignoreScrollUpdate = false;
this.ignoreScrollUpdate = false;
return;
return;
}
}
    let heading = tracker.getNearestHeadingAboveViewport();
    let heading = this.tracker.getNearestHeadingAboveViewport();
    setCurrentHeading(heading ? heading.textContent : null);
    this.setCurrentHeading(heading ? heading.textContent : null);
});
}
}
 
let floatingToC
let toc = document.getElementById('toc');
let siteNavigation = document.getElementById('mw-site-navigation');
 
document.addEventListener('replysubmit', () => {
let new_toc = document.querySelectorAll('.mw-parser-output > #toc')[0];
if (new_toc != null) {
}
});
 
if (toc && siteNavigation) {
    toc.parentNode.removeChild(toc);
    siteNavigation.appendChild(toc);
    floatingToC = new floatingToC(toc);
}
}

2025年8月24日 (日) 13:05的版本

/* 将为Timeless皮肤的用户加载此处的所有JavaScript  */

class HeadingTracker {
    constructor(rootElement) {
    	this.rootElement = rootElement
        this.headings = [];
        this.cacheExpired = true;
        this.init();
    }

    init() {
        this.collectHeadings();
        window.addEventListener('resize', () => this.cacheExpired = true);
        window.addEventListener('DOMContentLoaded', () => this.cacheExpired = true);
    }

    collectHeadings() {
        const rawHeadings = Array.from(this.rootElement.querySelectorAll('h1, h2, h3, h4, h5, h6'));
        this.headings = rawHeadings
            .map(heading => ({
                element: heading,
                top: heading.getBoundingClientRect().top + window.scrollY
            }))
            .sort((a, b) => a.top - b.top);
        this.cacheExpired = false;
    }

    getNearestHeadingAboveViewport() {
        if (this.cacheExpired) this.collectHeadings();

        const scrollY = window.scrollY + 60;
        let left = 0, right = this.headings.length - 1;
        let result = null;

        while (left <= right) {
            const mid = Math.floor((left + right) / 2);
            if (this.headings[mid].top <= scrollY) {
                result = this.headings[mid].element;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return result;
    }
}

class FloatingToC {
	constructor(toc) {
		this.ignoreScrollUpdate = false;
	    
	    let tocTextList = Array.from(toc.querySelectorAll(".toctext"));
	    this.tocTexts = new Map(tocTextList.map(t => {
	    	let textContent = t.textContent
	    	t.parentElement.onclick = () => {
	    		this.ignoreScrollUpdate = true;
	    		this.setCurrentHeading(textContent);
	    	};
	    	return [textContent, t];
	    }));

		this.tracker = new HeadingTracker(
			document.getElementById('mw-content-text'));
		
		window.addEventListener('scroll', this.onScroll);
	}
	
    setCurrentHeading(heading) {
    	const heading = this.heading;
    	const lastHeading = this.lastHeading;
    	
    	if (heading == lastHeading) {
    		return;
    	}
    	if (lastHeading) {
    		let text = this.tocTexts.get(lastHeading)
    		if (text) text.classList.remove('current-heading');
    	}
    	this.lastHeading = heading;
    	if (heading) {
    		let text = this.tocTexts.get(heading)
    		if (text) text.classList.add('current-heading');
    	}
    };
	
	onScroll() {
		if (window.innerWidth < 1100) {
			return;
		}
		if (this.ignoreScrollUpdate) {
			this.ignoreScrollUpdate = false;
			return;
		}
	    let heading = this.tracker.getNearestHeadingAboveViewport();
	    this.setCurrentHeading(heading ? heading.textContent : null);
	}
}

let floatingToC
let toc = document.getElementById('toc');
let siteNavigation = document.getElementById('mw-site-navigation');

document.addEventListener('replysubmit', () => {
	let new_toc = document.querySelectorAll('.mw-parser-output > #toc')[0];
	if (new_toc != null) {
		
	}
});

if (toc && siteNavigation) {
    toc.parentNode.removeChild(toc);
    siteNavigation.appendChild(toc);
    floatingToC = new floatingToC(toc);
}