HTML5 新功能與 API
dialog — 原生對話框
<!-- 不需要 JavaScript 函式庫! -->
<dialog id="myDialog">
<h2>確認刪除?</h2>
<p>此操作無法復原。</p>
<form method="dialog"> <!-- ← method="dialog" 自動關閉 -->
<button value="cancel">取消</button>
<button value="confirm">確認</button>
</form>
</dialog>
<button onclick="myDialog.showModal()">刪除</button>
<script>
myDialog.addEventListener("close", () => {
console.log(myDialog.returnValue); // "cancel" 或 "confirm"
});
</script>
progress 和 meter
<!-- 進度條 -->
<label for="download">下載進度:</label>
<progress id="download" value="70" max="100">70%</progress>
<!-- 不確定進度(loading) -->
<progress>載入中...</progress>
<!-- 度量表(非進度) -->
<label for="disk">磁碟使用量:</label>
<meter id="disk" min="0" max="100"
low="25" high="75" optimum="50"
value="80">80%</meter>
<!-- 80% > high(75%) → 顯示警告色 -->
contenteditable — 可編輯內容
<div contenteditable="true"
style="border: 1px solid #ccc; padding: 10px;">
點擊這裡可以直接編輯文字!
</div>
<script>
let editor = document.querySelector('[contenteditable]');
editor.addEventListener('input', () => {
console.log('內容:', editor.innerHTML);
});
</script>
Drag and Drop
<div id="drag-item" draggable="true"
style="width:100px; height:100px; background:coral;">
拖我
</div>
<div id="drop-zone"
style="width:200px; height:200px; border:2px dashed #ccc;">
放到這裡
</div>
<script>
let item = document.getElementById('drag-item');
let zone = document.getElementById('drop-zone');
item.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', 'hello');
});
zone.addEventListener('dragover', (e) => {
e.preventDefault(); // ← 必須阻止預設行為
});
zone.addEventListener('drop', (e) => {
e.preventDefault();
let data = e.dataTransfer.getData('text/plain');
zone.textContent = `收到: ${data}`;
});
</script>
template — 模板
<!-- template 裡的內容不會顯示也不會執行 -->
<template id="card-template">
<div class="card">
<h3 class="card-title"></h3>
<p class="card-body"></p>
</div>
</template>
<div id="container"></div>
<script>
let template = document.getElementById('card-template');
let container = document.getElementById('container');
// 複製模板並填入資料
let clone = template.content.cloneNode(true);
clone.querySelector('.card-title').textContent = '標題';
clone.querySelector('.card-body').textContent = '內容';
container.appendChild(clone);
</script>
Web Components(自訂元素)
<script>
class MyCard extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<div style="border:1px solid #ccc; padding:16px; border-radius:8px;">
<h3>${this.getAttribute('title')}</h3>
<slot></slot>
</div>
`;
}
}
customElements.define('my-card', MyCard);
</script>
<!-- 使用自訂元素 -->
<my-card title="Hello">
<p>這是卡片內容</p>
</my-card>