feat: boutons haut/bas de page dans la sidebar article
This commit is contained in:
@@ -656,6 +656,31 @@ textarea.form-control {
|
||||
font-size: .775rem;
|
||||
}
|
||||
|
||||
.toc-nav {
|
||||
display: flex;
|
||||
gap: .5rem;
|
||||
padding-top: .75rem;
|
||||
border-top: 1px solid var(--vl-border);
|
||||
margin-top: .25rem;
|
||||
}
|
||||
|
||||
.toc-nav-btn {
|
||||
flex: 1;
|
||||
background: none;
|
||||
border: 1px solid var(--vl-border);
|
||||
border-radius: .5rem;
|
||||
padding: .3rem .4rem;
|
||||
font-size: .75rem;
|
||||
color: var(--vl-muted);
|
||||
cursor: pointer;
|
||||
transition: color .15s, border-color .15s;
|
||||
}
|
||||
|
||||
.toc-nav-btn:hover {
|
||||
color: var(--vl-accent);
|
||||
border-color: var(--vl-accent);
|
||||
}
|
||||
|
||||
.related-card {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// reactions.js — toggle réactions via fetch, fallback formulaire natif
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
document.querySelectorAll('.reaction-form').forEach(function (form) {
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var btn = form.querySelector('.reaction-btn');
|
||||
var type = form.querySelector('[name="type"]').value;
|
||||
var uuid = form.querySelector('[name="uuid"]').value;
|
||||
var badge = form.querySelector('.reaction-count');
|
||||
var active = btn.classList.contains('btn-primary');
|
||||
|
||||
var data = new URLSearchParams();
|
||||
data.append('uuid', uuid);
|
||||
data.append('type', type);
|
||||
data.append('_ajax', '1');
|
||||
|
||||
fetch('/react', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: data.toString(),
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (json) {
|
||||
if (!json.ok) { form.submit(); return; }
|
||||
|
||||
var nowActive = json.active;
|
||||
btn.classList.toggle('btn-primary', nowActive);
|
||||
btn.classList.toggle('btn-outline-secondary', !nowActive);
|
||||
if (badge) {
|
||||
badge.classList.toggle('bg-light', nowActive);
|
||||
badge.classList.toggle('text-primary', nowActive);
|
||||
badge.classList.toggle('bg-secondary', !nowActive);
|
||||
badge.textContent = json.count;
|
||||
}
|
||||
})
|
||||
.catch(function () { form.submit(); });
|
||||
});
|
||||
});
|
||||
});
|
||||
+30
-16
@@ -1,23 +1,37 @@
|
||||
(function () {
|
||||
var headings = document.querySelectorAll('.post-content h2, .post-content h3');
|
||||
var links = document.querySelectorAll('.toc-list a');
|
||||
if (!headings.length || !links.length) return;
|
||||
|
||||
var map = {};
|
||||
links.forEach(function (a) {
|
||||
map[decodeURIComponent(a.getAttribute('href').slice(1))] = a;
|
||||
});
|
||||
|
||||
var active = null;
|
||||
var observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.isIntersecting) {
|
||||
if (active) active.classList.remove('toc-active');
|
||||
active = map[entry.target.id] || null;
|
||||
if (active) active.classList.add('toc-active');
|
||||
}
|
||||
if (headings.length && links.length) {
|
||||
var map = {};
|
||||
links.forEach(function (a) {
|
||||
map[decodeURIComponent(a.getAttribute('href').slice(1))] = a;
|
||||
});
|
||||
}, { rootMargin: '-8% 0px -82% 0px', threshold: 0 });
|
||||
|
||||
headings.forEach(function (h) { observer.observe(h); });
|
||||
var active = null;
|
||||
var observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.isIntersecting) {
|
||||
if (active) active.classList.remove('toc-active');
|
||||
active = map[entry.target.id] || null;
|
||||
if (active) active.classList.add('toc-active');
|
||||
}
|
||||
});
|
||||
}, { rootMargin: '-8% 0px -82% 0px', threshold: 0 });
|
||||
|
||||
headings.forEach(function (h) { observer.observe(h); });
|
||||
}
|
||||
|
||||
var btnTop = document.getElementById('toc-go-top');
|
||||
var btnBot = document.getElementById('toc-go-bottom');
|
||||
if (btnTop) {
|
||||
btnTop.addEventListener('click', function () {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
}
|
||||
if (btnBot) {
|
||||
btnBot.addEventListener('click', function () {
|
||||
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user