前言 #
在Hugo 動畫背景|3D網格加代碼瀑布風格 這邊文章中,我想要直接在文內展示該動畫背景。我可以直接在 Markdown 檔案中編寫 HTML iframe 元素創建,但我想要限制其高度,若超過便折疊,透過按鈕選擇是否展開,這樣的話更美觀且易於閱讀,就像Hugo Blowfish 主題 程式碼區塊樣式與折疊 這篇文章中提到的「可折疊程式碼區塊」,於是我透過 Perplexity 協助編寫了這個「可折疊 iframe Shortcode」。
展示 #
展示檔案路徑 #
創建/static/demo路徑,將你要展示的 .html 檔存放在該路徑下。
新增 CSS 設定 #
編輯/assets/css路徑下的custom.css,添加:
/* /layouts/shortcodes/iframe.html */
/* iframe 容器 */
.iframe-container {
position: relative;
margin: 1.5rem 0;
}
/* 折疊狀態 */
.iframe-container.collapsible {
max-height: 400px;
overflow: hidden;
transition: max-height 0.3s ease;
}
/* 展開狀態 */
.iframe-container.expanded {
max-height: none;
}
/* 漸層遮罩 */
.iframe-container.collapsible::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 80px;
background: linear-gradient(to bottom, transparent, var(--color-background));
pointer-events: none;
}
.iframe-container.expanded::after {
display: none;
}
/* 展開按鈕 */
.iframe-expand-btn {
display: block;
width: 100%;
padding: 0.5rem;
margin-top: 0.5rem;
background: var(--color-secondary);
border: 1px solid var(--color-border);
border-radius: var(--radius-base);
cursor: pointer;
font-size: 0.875rem;
text-align: center;
transition: background 0.2s;
}
.iframe-expand-btn:hover {
background: var(--color-secondary-hover);
}
如果主題不是使用 Blowfish,上述設定的參數可能要重新檢查。
創建 iframe Shortcode 並導入 JavaScript #
在/layouts/shortcodes下創建iframe.html,並編輯:
<div class="iframe-container">
<iframe src="{{ .Get "src" }}"
width="{{ .Get "width" | default "100%" }}"
height="{{ .Get "height" | default "600px" }}"
loading="lazy">
</iframe>
</div>
{{ if not (.Page.Scratch.Get "iframe-js-loaded") }}
{{ .Page.Scratch.Set "iframe-js-loaded" true }}
<script src="/js/collapsible-iframe.js" defer></script>
{{ end }}
創建 JavaScript #
編輯/static/js/collapsible-iframe.js,如路徑不存在就手動建立。
// static/js/collapsible-iframe.js
(function() {
const containers = document.querySelectorAll('.iframe-container');
// 從 HTML 讀取翻譯文字,預設為英文,這段是為了供多語言網站顯示對應文字,可直接將`Expand Content ▼`改為`展開完整內容 ▼`;`Collapse Content ▲`改為`折疊內容 ▲`
const iframeExpandText = document.documentElement.dataset.iframeExpandText || 'Expand Content ▼';
const iframeCollapseText = document.documentElement.dataset.iframeCollapseText || 'Collapse Content ▲';
containers.forEach(function(container) {
// 避免重複處理
if (container.dataset.processed) return;
container.dataset.processed = 'true';
const iframe = container.querySelector('iframe');
const iframeHeight = parseInt(iframe.getAttribute('height')) || 600;
// 只對高度超過 400px 的 iframe 啟用折疊功能
if (iframeHeight > 400) {
// 設定容器為折疊狀態
container.classList.add('collapsible');
// 建立展開/折疊按鈕
const btn = document.createElement('button');
btn.className = 'iframe-expand-btn';
btn.innerHTML = '<span class="expand-text">' + iframeExpandText + '</span><span class="collapse-text" style="display:none;">' + iframeCollapseText + '</span>';
// 將按鈕插入到容器後面
container.parentNode.insertBefore(btn, container.nextSibling);
// 按鈕點擊事件
btn.addEventListener('click', function() {
const expandSpan = btn.querySelector('.expand-text');
const collapseSpan = btn.querySelector('.collapse-text');
if (container.classList.contains('collapsible')) {
// 展開
container.classList.remove('collapsible');
container.classList.add('expanded');
expandSpan.style.display = 'none';
collapseSpan.style.display = 'inline';
} else {
// 折疊
container.classList.remove('expanded');
container.classList.add('collapsible');
expandSpan.style.display = 'inline';
collapseSpan.style.display = 'none';
container.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
});
})();
大功告成,如果你是多語言網站,請繼續參考下面步驟。
折疊按鈕多語言設定 #
修改 Shortcode #
修改iframe.html,將:
{{ if not (.Page.Scratch.Get "iframe-js-loaded") }}
{{ .Page.Scratch.Set "iframe-js-loaded" true }}
<script src="/js/collapsible-iframe.js" defer></script>
{{ end }}
改為:
{{ if not (.Page.Scratch.Get "iframe-js-loaded") }}
{{ .Page.Scratch.Set "iframe-js-loaded" true }}
<script>
document.documentElement.dataset.iframeExpandText = "{{ i18n "shortcode.collapsible-iframe.expand" }}";
document.documentElement.dataset.iframeCollapseText = "{{ i18n "shortcode.collapsible-iframe.collapse" }}";
</script>
<script src="/js/collapsible-iframe.js" defer></script>
{{ end }}
編輯 i18n 設定檔 #
編輯 /i18n 路徑下的設定檔,以繁體中文zh-TW.yaml為例,在檔案中新增:
shortcode:
collapsible-iframe:
expand: "展開完整內容 ▼"
collapse: "折疊內容 ▲"
Done!
使用方法 #
接著你就可以在 Markdown 檔案中使用:
{{< iframe src="/demo/檔名.html" width="自訂" height="自訂" >}}
不添加width或heigh的話,預設為100%及600px,可到iframe.html中修改。