Menu tekan lama
Untuk tiga atau empat aksi yang hanya milik satu baris, dibuka di tempat alih-alih di layar tersendiri.
Pratinjau langsung
Sumber
<div class="dc-lp">
<details class="dc-lp__box">
<summary class="dc-lp__item">
<span class="dc-lp__name">현장 점검 보고서.pdf</span>
<span class="dc-lp__meta">2.4MB · 어제 오후 5:12</span>
</summary>
<div class="dc-lp__menu" role="group" aria-label="파일 동작">
<button class="dc-lp__act" type="button">이름 바꾸기</button>
<button class="dc-lp__act" type="button">공유</button>
<button class="dc-lp__act dc-lp__act--danger" type="button">삭제</button>
</div>
</details>
<p class="dc-lp__hint">길게 누르면 열립니다. 짧게 눌러도 같은 메뉴가 열려 누구나 닿을 수 있습니다.</p>
</div>
.dc-lp {
padding: var(--dc-4);
background: var(--dc-bg);
font-family: var(--dc-font);
}
.dc-lp__box {
border: 1px solid var(--dc-line);
border-radius: var(--dc-r-md);
background: var(--dc-surface);
box-shadow: var(--dc-sh-1);
}
.dc-lp__item {
display: flex;
flex-direction: column;
gap: var(--dc-1);
min-height: 44px;
padding: var(--dc-3) var(--dc-4);
border-radius: var(--dc-r-md);
list-style: none;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
-webkit-touch-callout: none;
}
.dc-lp__item::-webkit-details-marker { display: none; }
.dc-lp__item::marker { content: ""; }
.dc-lp__box[open] .dc-lp__item {
border-bottom: 1px solid var(--dc-line);
border-radius: var(--dc-r-md) var(--dc-r-md) 0 0;
background: var(--dc-sunken);
}
.dc-lp__name {
font-size: 15px;
font-weight: 600;
color: var(--dc-text);
}
.dc-lp__meta {
font-size: 12px;
color: var(--dc-text-mute);
}
.dc-lp__menu {
display: flex;
flex-direction: column;
padding: var(--dc-1);
}
.dc-lp__act {
display: flex;
align-items: center;
gap: var(--dc-3);
min-height: 48px;
padding: 0 var(--dc-3);
border: 0;
border-radius: var(--dc-r-sm);
background: none;
color: var(--dc-text);
font-family: var(--dc-font);
font-size: 15px;
text-align: left;
cursor: pointer;
transition: background var(--dc-fast);
}
.dc-lp__act:hover { background: var(--dc-sunken); }
.dc-lp__act--danger { color: var(--dc-danger); }
.dc-lp__ico {
width: 20px;
height: 20px;
flex: none;
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
}
.dc-lp__hint {
margin: var(--dc-3) 0 0;
font-size: 12px;
line-height: 1.6;
color: var(--dc-text-mute);
}
document.querySelectorAll('.dc-lp__box').forEach(function (box) {
var item = box.querySelector('.dc-lp__item');
if (!item) return;
var timer = null;
function clear() {
if (timer) { clearTimeout(timer); timer = null; }
}
item.addEventListener('pointerdown', function () {
clear();
timer = setTimeout(function () {
timer = null;
box.open = true;
}, 450);
});
['pointerup', 'pointercancel', 'pointerleave'].forEach(function (name) {
item.addEventListener(name, clear);
});
});
Cara memakainya
- Kumpulkan hanya aksi milik item itu; aksi selingkup layar taruh di bilah atas
- Letakkan aksi berisiko paling bawah dan bedakan warnanya agar jari tak menyenggolnya
- Biarkan item itu tetap terlihat di atas menu agar jelas aksi ini untuk apa
Hal yang perlu diwaspadai
- Tekan lama tidak terlihat: buat tekan singkat juga membuka, atau sediakan tombol lainnya
- Dibangun di atas details/summary, menu tetap terbuka saat skrip gagal — skrip hanya menambah tekan lama
- Beri tiap baris menu tinggi sekitar 48px; baris berdempet memicu salah tekan