Die Liste im Dialog rollt, das Anschlagbrett schreibt nicht mehr ab
Zwei Dinge aus Filipes Durchgang. ERSTENS: "das hoch und runter scollen geht nicht in der liste da." Die Auswahlliste im Kanal-Dialog liegt seit dem Popover-Umbau in der obersten Ebene. Das loest das Abschneiden -- aber der Zeiger steht danach ueber dem Dialog, nicht ueber der Liste, und das Mausrad rollt den Dialog. Der Horcher haengt jetzt am Dokument (capture) und fragt selbst, ob der Zeiger im Rechteck der Liste steht. Gemessen: 5 Messungen, 0 Befunde. ZWEITENS: "gestalte diese seite auch anders ... viel uebersichtlicher." Am Anschlagbrett stand die Herkunft als vollstaendige Abschrift des Titels darueber -- derselbe Satz zweimal, direkt untereinander. Jetzt nennt sie nur noch das Brett, wenn der Titel uebernommen wurde, und kuerzt sonst auf 60 Zeichen an der Wortgrenze. Dazu Karten mit 620 px Hoechstbreite, zwei nebeneinander statt einer Zeile ueber die ganze Breite -- lesbar bleibt, was eine begrenzte Zeilenlaenge hat. Gemessen: 11 Messungen, 0 Befunde; Titel von 352 px statt voller Breite, zwei Spalten a 571 px. Geprueft: pruef-anschlagbrett (12, 0), pruef-css-klassen, pruef-highlights, pruef-chat-kanaele (81, 0), pruef-freie-namen (32, 0). Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -1221,10 +1221,49 @@
|
||||
Titel, mehr Luft, ein Rahmen, der nach Papier aussieht statt nach
|
||||
Zeile.
|
||||
------------------------------------------------------------------- */
|
||||
#liste[data-aushang="ja"] { display: grid; gap: 18px; }
|
||||
/* ZWEI NEBENEINANDER, WENN DER PLATZ REICHT (24.09.2026).
|
||||
|
||||
Filipe: "gestalte diese seite auch anders bitte. viel krasser
|
||||
geiler übersichtlicher."
|
||||
|
||||
Hier stand ein einspaltiges Raster. Auf einem breiten Schirm wurde
|
||||
damit jeder Aushang 1700 px breit -- und ein Titel in 1,32 rem ueber
|
||||
1700 px ist keine Ueberschrift mehr, sondern eine Zeile, die man
|
||||
beim Lesen verliert. Auf seinem Bildschirmfoto lief genau das ueber
|
||||
die volle Breite.
|
||||
|
||||
"Wenige, grosse Aushaenge" bleibt richtig -- gross heisst aber
|
||||
auffaellig, nicht breit. Ein Zettel am schwarzen Brett ist auch
|
||||
keine anderthalb Meter breit.
|
||||
|
||||
auto-fit mit einer OBERGRENZE je Spalte: Bei viel Platz stehen zwei
|
||||
nebeneinander, bei wenig eine, und keine wird je breiter als 620 px.
|
||||
Gerechnet wird nichts -- der Browser entscheidet nach dem Platz,
|
||||
den er hat. */
|
||||
#liste[data-aushang="ja"] {
|
||||
display: grid; gap: 18px;
|
||||
/* DIE OBERGRENZE GEHOERT AN DIE KARTE, NICHT AN DIE SPALTE.
|
||||
|
||||
Erster Versuch war "minmax(..., 620px)". Gemessen: Die
|
||||
Inhaltsspalte ist 1160 px breit, zwei Karten a 620 plus Luecke
|
||||
waeren 1258 -- es passte genau eine, und die Aenderung bewirkte
|
||||
nichts. Eine Obergrenze an der Spalte rechnet gegen eine Breite,
|
||||
die man vorher nicht kennt.
|
||||
|
||||
Mit "1fr" teilt der Browser den vorhandenen Platz: bei 1160 px
|
||||
zwei Spalten a 571, bei 390 px eine. Dass eine EINZELNE Karte
|
||||
nicht ueber die ganze Breite laeuft, sagt dann ihre eigene
|
||||
max-width -- an der Stelle, an der es hingehoert. */
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
|
||||
align-items: start;
|
||||
}
|
||||
#liste[data-aushang="ja"] .eintrag-karte { max-width: 620px; }
|
||||
#liste[data-aushang="ja"] .eintrag-karte { padding: 22px 24px; }
|
||||
#liste[data-aushang="ja"] .eintrag-titel {
|
||||
font-size: 1.32rem; line-height: 1.25;
|
||||
/* Auch innerhalb einer 620-px-Spalte: In Zeichen gemessen, damit es
|
||||
bei groesser gestellter Schrift stimmt. */
|
||||
max-width: 30ch;
|
||||
}
|
||||
#liste[data-aushang="ja"] .eintrag-text {
|
||||
font-size: .98rem; line-height: 1.6;
|
||||
|
||||
@@ -749,8 +749,40 @@
|
||||
if (e.aus) {
|
||||
const z = el('p', 'kette kette--her');
|
||||
z.append(el('span', 'kette__wort', 'Aus'));
|
||||
/* ==== NICHT DENSELBEN TEXT ZWEIMAL (24.09.2026) ==============
|
||||
|
||||
Hier stand immer "Brett: voller Titel der Quelle". Bei einem
|
||||
Eintrag, der AUS einem anderen entstanden ist, traegt er
|
||||
meistens denselben Titel -- und dann stand auf Filipes
|
||||
Bildschirmfoto ein langer Satz als Ueberschrift und darunter
|
||||
derselbe lange Satz noch einmal.
|
||||
|
||||
Die Zeile soll sagen, WOHER etwas kam. Wenn der Titel schon
|
||||
darueber steht, ist der Brettname die ganze Auskunft; der
|
||||
Rest ist Abschrift.
|
||||
|
||||
Verglichen werden die ersten vierzig Zeichen und nicht der
|
||||
ganze Text: Beim Uebernehmen wird manchmal ein Wort
|
||||
angehaengt oder ein Doppelpunkt gesetzt, und zwei Titel, die
|
||||
sich nur darin unterscheiden, sind fuer den Leser derselbe. */
|
||||
const brett = BRETT_WORT[e.aus.bereich] || e.aus.bereich;
|
||||
const eigen = String(e.titel || '').trim();
|
||||
const quelle = String(e.aus.titel || '').trim();
|
||||
const anfang = (t) => t.slice(0, 40).toLowerCase();
|
||||
const dasselbe = !!quelle && !!eigen
|
||||
&& (quelle === eigen || anfang(quelle) === anfang(eigen));
|
||||
/* Und auch ein ANDERER Titel wird nicht zum Absatz: Diese Zeile
|
||||
ist ein Verweis, kein Zitat. Geschnitten wird an einer
|
||||
Wortgrenze -- mitten im Wort abzubrechen liest sich wie ein
|
||||
Fehler. */
|
||||
const kurz = (t) => {
|
||||
if (t.length <= 60) return t;
|
||||
const schnitt = t.slice(0, 60);
|
||||
const luecke = schnitt.lastIndexOf(' ');
|
||||
return (luecke > 30 ? schnitt.slice(0, luecke) : schnitt) + ' …';
|
||||
};
|
||||
const a = el('a', 'kette__weg',
|
||||
`${BRETT_WORT[e.aus.bereich] || e.aus.bereich}: ${e.aus.titel}`);
|
||||
dasselbe ? brett : `${brett}: ${kurz(quelle)}`);
|
||||
a.href = `/workspace/bereich.html?b=${encodeURIComponent(e.aus.bereich)}`;
|
||||
z.append(a);
|
||||
if (e.aus.von_name) z.append(el('span', 'kette__wer', '· von ' + e.aus.von_name));
|
||||
|
||||
@@ -349,6 +349,65 @@
|
||||
if (dlg && dlg.open && typeof liste.showPopover === "function") {
|
||||
liste.setAttribute("popover", "manual");
|
||||
try { liste.showPopover(); } catch { /* dann eben ohne */ }
|
||||
|
||||
/* ==== UND DAS SCROLLEN SELBST UEBERNEHMEN (24.09.2026) =======
|
||||
|
||||
Filipe: "das hoch und runter scollen geht nicht in der liste
|
||||
da."
|
||||
|
||||
Gemessen, alle drei Verdaechtigen einzeln:
|
||||
|
||||
scrollTop von Hand setzen geht (80)
|
||||
das wheel-Ereignis kommt an
|
||||
overscroll-behavior unauffaellig
|
||||
|
||||
Also kann der Kasten scrollen, und das Ereignis erreicht ihn
|
||||
-- der Browser fuehrt es nur nicht aus. Der Grund ist der
|
||||
modale Dialog: Er unterdrueckt das Scrollen von allem, was
|
||||
ausserhalb von ihm liegt. Ein Popover in der Top Layer bleibt
|
||||
zwar anklickbar (das hat die Messung gestern gezeigt), aber
|
||||
gescrollt wird darin nicht.
|
||||
|
||||
DIE LISTE IN DEN DIALOG ZU HAENGEN LOEST ES NICHT -- dort
|
||||
schneidet das clip-path der abgeschraegten Ecke sie ab, genau
|
||||
das war gestern der erste, falsche Versuch.
|
||||
|
||||
Also uebernimmt die Liste das Scrollen selbst: Das Ereignis
|
||||
ist da, der Weg ist frei, es fehlt nur die Ausfuehrung. Nur
|
||||
im Popover-Fall -- ueberall sonst macht der Browser es
|
||||
richtig, und ein zweiter Scroller danebenliegend waere die
|
||||
Sorte Doppelung, die irgendwann ruckelt. */
|
||||
const rollbar = liste.querySelector(".wahl2__zeilen") || liste;
|
||||
/* AM DOKUMENT, NICHT AN DER LISTE -- und zwar in der
|
||||
Einfangphase.
|
||||
|
||||
An der Liste zu horchen klingt naeher dran und ist es nicht:
|
||||
Welches Element ein Rad-Ereignis bekommt, entscheidet der
|
||||
Treffertest, und der meldet bei einem Popover ueber einem
|
||||
modalen Dialog den DIALOG. Gemessen: Ein Ereignis, das direkt
|
||||
auf der Liste ausgeloest wird, rollt sie (100 -> 209); eines
|
||||
ueber Bildschirmkoordinaten kommt gar nicht erst an.
|
||||
|
||||
Am Dokument laeuft jedes Rad-Ereignis vorbei, egal wer den
|
||||
Treffertest gewinnt. Ob es die Liste MEINT, entscheidet dann
|
||||
die Lage des Zeigers -- das ist dieselbe Frage, nur an einer
|
||||
Stelle beantwortet, an der sie beantwortbar ist. */
|
||||
z.beiRad = (ereignis) => {
|
||||
const r = liste.getBoundingClientRect();
|
||||
const drin = ereignis.clientX >= r.left && ereignis.clientX <= r.right
|
||||
&& ereignis.clientY >= r.top && ereignis.clientY <= r.bottom;
|
||||
if (!drin) return;
|
||||
const platz = rollbar.scrollHeight - rollbar.clientHeight;
|
||||
if (platz <= 0) return;
|
||||
const vorher = rollbar.scrollTop;
|
||||
rollbar.scrollTop = Math.max(0, Math.min(platz, vorher + ereignis.deltaY));
|
||||
/* Nur wenn wirklich gerollt wurde: Am Ende der Liste soll das
|
||||
Rad nichts weiter tun -- und vor allem nicht die Seite
|
||||
darunter bewegen. */
|
||||
if (rollbar.scrollTop !== vorher) ereignis.preventDefault();
|
||||
};
|
||||
document.addEventListener("wheel", z.beiRad,
|
||||
{ passive: false, capture: true });
|
||||
}
|
||||
stelle(z);
|
||||
z.knopf.setAttribute('aria-expanded', 'true');
|
||||
@@ -383,6 +442,13 @@
|
||||
|
||||
function schliessen() {
|
||||
if (!aktiv) return;
|
||||
/* Den Rad-Horcher abmelden. Ohne das bliebe bei jedem Oeffnen
|
||||
einer mehr am Dokument haengen -- und jeder von ihnen faende
|
||||
seine Liste nicht mehr. */
|
||||
if (aktiv.beiRad) {
|
||||
document.removeEventListener("wheel", aktiv.beiRad, { capture: true });
|
||||
aktiv.beiRad = null;
|
||||
}
|
||||
aktiv.liste?.remove();
|
||||
aktiv.knopf.setAttribute('aria-expanded', 'false');
|
||||
aktiv.liste = null;
|
||||
|
||||
Reference in New Issue
Block a user