UserScriptがページリロードしないと表示してくれない問題
ChatGPT.icon
ScrapboxのUserScriptがページリロードしないと表示されない原因は、Scrapboxのページ遷移が**SPA(シングルページアプリケーション)**になっているため、初回ロード後にDOMの変更が検知できないことが考えられます。 ## 解決方法
Scrapboxでは、window.scrapbox.Page.lines の変更を監視する方法が一般的です。以下の方法を試してください。
Scrapboxはページ遷移してもDOMを再構築しないため、MutationObserver を使ってアイコンが追加されるのを監視し、名前を追加するようにします。
code:javascript.js
function addTitleAfterIcons() {
for (let img of document.querySelectorAll('img.icon')) {
if (!img.nextElementSibling || !img.nextElementSibling.classList.contains("title_display")) {
let titleText = img.getAttribute("title");
if (titleText) {
let span = document.createElement('span');
span.classList.add("title_display");
span.innerText = titleText;
img.after(span);
}
}
}
}
// MutationObserverで監視
const observer = new MutationObserver(() => {
addTitleAfterIcons();
});
// 変更が発生する要素を監視
observer.observe(document.body, { childList: true, subtree: true });
// 初回実行
addTitleAfterIcons();
これにより、Scrapboxのページ遷移時にも自動的に名前が追加されます。
### **解決策 2: Scrapboxのイベントを利用する**
Scrapboxのページ変更を検知する方法として、window.scrapbox.on を使う方法もあります。
code:javascript.js
function addTitleAfterIcons() {
for (let img of document.querySelectorAll('img.icon')) {
if (!img.nextElementSibling || !img.nextElementSibling.classList.contains("title_display")) {
let titleText = img.getAttribute("title");
if (titleText) {
let span = document.createElement('span');
span.classList.add("title_display");
span.innerText = titleText;
img.after(span);
}
}
}
}
// Scrapboxのイベントを使う
window.scrapbox.on("lines:changed", addTitleAfterIcons);
// 初回実行
addTitleAfterIcons();
Scrapboxは lines:changed イベントが発生するたびに、ページ内のDOMが変更されるので、それをフックして更新する方法です。
### **どちらが良いか?**
- **リアルタイムで適用したい場合** → **MutationObserver(解決策1)**
- **Scrapboxの公式イベントを利用したい場合** → **Scrapboxイベント(解決策2)**
どちらも試して動作を確認してみてください!