Use data-quiz-shown attributes for quiz mode visibility
Mark elements that should remain visible in quiz mode at build time via data-quiz-shown attributes (toolbar, breadcrumb, h1, questions, solution links, next-section/-chapter links). The runtime tail detection becomes obsolete and the CSS collapses to a single show/hide rule. Switch the body markers to data-quiz-mode / data-quiz-has-questions attributes, swap the toggle between btn-secondary and btn-primary instead of hardcoded colors, and use Bootstrap's alert alert-info for the no-questions notice.
This commit is contained in:
+18
-29
@@ -22,40 +22,27 @@ function answer(el, correct) {
|
|||||||
(function () {
|
(function () {
|
||||||
var NOTICE_ID = "quiz-mode-notice";
|
var NOTICE_ID = "quiz-mode-notice";
|
||||||
var STORAGE_KEY = "quiz-mode-enabled";
|
var STORAGE_KEY = "quiz-mode-enabled";
|
||||||
var QUIZ_CLASS = "quiz-mode-active";
|
var QUIZ_ATTR = "data-quiz-mode";
|
||||||
var HAS_Q_CLASS = "quiz-has-questions";
|
var HAS_Q_ATTR = "data-quiz-has-questions";
|
||||||
|
|
||||||
function pageHasQuestions() {
|
function pageHasQuestions() {
|
||||||
return document.querySelector(".course .question") !== null;
|
return document.querySelector(".course .question") !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tagSectionTail() {
|
|
||||||
var course = document.querySelector(".course");
|
|
||||||
if (!course) return false;
|
|
||||||
var tagged = course.querySelectorAll("[data-quiz-tail]");
|
|
||||||
for (var i = 0; i < tagged.length; i++) {
|
|
||||||
tagged[i].removeAttribute("data-quiz-tail");
|
|
||||||
}
|
|
||||||
var children = course.children;
|
|
||||||
for (var j = 0; j < children.length; j++) {
|
|
||||||
var child = children[j];
|
|
||||||
if (child.tagName !== "DIV") continue;
|
|
||||||
var text = (child.textContent || "").toLowerCase();
|
|
||||||
if (text.indexOf("weiter zum nächsten abschnitt") !== -1 ||
|
|
||||||
text.indexOf("weiter zum nächsten kapitel") !== -1) {
|
|
||||||
child.setAttribute("data-quiz-tail", "");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showNotice(text) {
|
function showNotice(text) {
|
||||||
var n = document.getElementById(NOTICE_ID);
|
var n = document.getElementById(NOTICE_ID);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
n = document.createElement("div");
|
n = document.createElement("div");
|
||||||
n.id = NOTICE_ID;
|
n.id = NOTICE_ID;
|
||||||
document.body.appendChild(n);
|
n.className = "alert alert-info";
|
||||||
|
n.setAttribute("role", "alert");
|
||||||
|
n.style.clear = "both";
|
||||||
|
var course = document.querySelector(".course");
|
||||||
|
if (course) {
|
||||||
|
course.insertBefore(n, course.firstChild);
|
||||||
|
} else {
|
||||||
|
document.body.appendChild(n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
n.textContent = text;
|
n.textContent = text;
|
||||||
}
|
}
|
||||||
@@ -67,15 +54,17 @@ function answer(el, correct) {
|
|||||||
|
|
||||||
function updateButton(btn, on) {
|
function updateButton(btn, on) {
|
||||||
btn.setAttribute("aria-pressed", on ? "true" : "false");
|
btn.setAttribute("aria-pressed", on ? "true" : "false");
|
||||||
btn.classList.toggle("active", on);
|
btn.classList.toggle("btn-primary", on);
|
||||||
|
btn.classList.toggle("btn-secondary", !on);
|
||||||
btn.title = on ? "Alles anzeigen" : "Nur Fragen anzeigen";
|
btn.title = on ? "Alles anzeigen" : "Nur Fragen anzeigen";
|
||||||
}
|
}
|
||||||
|
|
||||||
function setQuizMode(on) {
|
function setQuizMode(on) {
|
||||||
var hasQ = pageHasQuestions();
|
var hasQ = pageHasQuestions();
|
||||||
document.body.classList.toggle(HAS_Q_CLASS, hasQ);
|
if (hasQ) document.body.setAttribute(HAS_Q_ATTR, "");
|
||||||
if (on && hasQ) tagSectionTail();
|
else document.body.removeAttribute(HAS_Q_ATTR);
|
||||||
document.body.classList.toggle(QUIZ_CLASS, on);
|
if (on) document.body.setAttribute(QUIZ_ATTR, "");
|
||||||
|
else document.body.removeAttribute(QUIZ_ATTR);
|
||||||
var btn = document.getElementById("quiz-mode-toggle");
|
var btn = document.getElementById("quiz-mode-toggle");
|
||||||
if (btn) updateButton(btn, on);
|
if (btn) updateButton(btn, on);
|
||||||
if (on && !hasQ) {
|
if (on && !hasQ) {
|
||||||
@@ -89,7 +78,7 @@ function answer(el, correct) {
|
|||||||
var btn = document.getElementById("quiz-mode-toggle");
|
var btn = document.getElementById("quiz-mode-toggle");
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
btn.addEventListener("click", function () {
|
btn.addEventListener("click", function () {
|
||||||
var next = !document.body.classList.contains(QUIZ_CLASS);
|
var next = !document.body.hasAttribute(QUIZ_ATTR);
|
||||||
setQuizMode(next);
|
setQuizMode(next);
|
||||||
try { localStorage.setItem(STORAGE_KEY, next ? "1" : "0"); } catch (e) {}
|
try { localStorage.setItem(STORAGE_KEY, next ? "1" : "0"); } catch (e) {}
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-34
@@ -448,41 +448,9 @@ span.formula {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Quiz-Modus */
|
/* Quiz-Modus */
|
||||||
#quiz-mode-toggle {
|
body[data-quiz-mode][data-quiz-has-questions] .course > * {
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
#quiz-mode-toggle.active {
|
|
||||||
background: #0a7a2a;
|
|
||||||
border-color: #0a7a2a;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
#quiz-mode-toggle.active svg {
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#quiz-mode-notice {
|
|
||||||
position: fixed;
|
|
||||||
top: 12px;
|
|
||||||
right: 12px;
|
|
||||||
z-index: 99999;
|
|
||||||
max-width: 260px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
font: 500 13px/1.35 system-ui, -apple-system, sans-serif;
|
|
||||||
color: #333;
|
|
||||||
background: #fff3cd;
|
|
||||||
border: 1px solid #ffe69c;
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.quiz-mode-active.quiz-has-questions .course > * {
|
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
body.quiz-mode-active.quiz-has-questions .course > .course-toolbar,
|
body[data-quiz-mode][data-quiz-has-questions] .course > [data-quiz-shown] {
|
||||||
body.quiz-mode-active.quiz-has-questions .course > h1,
|
|
||||||
body.quiz-mode-active.quiz-has-questions .course > nav,
|
|
||||||
body.quiz-mode-active.quiz-has-questions .course > .question,
|
|
||||||
body.quiz-mode-active.quiz-has-questions .course > [data-quiz-tail],
|
|
||||||
body.quiz-mode-active.quiz-has-questions .course > [data-quiz-tail] ~ * {
|
|
||||||
display: revert !important;
|
display: revert !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="course-toolbar" style="float: right;">
|
<div class="course-toolbar" style="float: right;" data-quiz-shown>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
{% if chapter["video_url"] %}
|
{% if chapter["video_url"] %}
|
||||||
<a class="btn btn-secondary" href="{{ chapter["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a>
|
<a class="btn btn-secondary" href="{{ chapter["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav aria-label="breadcrumb">
|
<nav aria-label="breadcrumb" data-quiz-shown>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
|
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
|
||||||
<li class="breadcrumb-item"><a href="{{ edition }}_course_index.html">{{ name }}</a></li>
|
<li class="breadcrumb-item"><a href="{{ edition }}_course_index.html">{{ name }}</a></li>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<h1>{{ chapter["title"] }}</h1>
|
<h1 data-quiz-shown>{{ chapter["title"] }}</h1>
|
||||||
<p>{{ chapter["abstract"] }}</p>
|
<p>{{ chapter["abstract"] }}</p>
|
||||||
<div class="chapter-toc d-grid gap-2">
|
<div class="chapter-toc d-grid gap-2">
|
||||||
{% for section in chapter["sections"] %}
|
{% for section in chapter["sections"] %}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<div>
|
<div data-quiz-shown>
|
||||||
Weiter zum nächsten Kapitel: <a href="{{ url }}">{{ title }}</a>
|
Weiter zum nächsten Kapitel: <a href="{{ url }}">{{ title }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<div>
|
<div data-quiz-shown>
|
||||||
Weiter zum nächsten Abschnitt: <a href="{{ url }}">{{ title }}</a>
|
Weiter zum nächsten Abschnitt: <a href="{{ url }}">{{ title }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="question layout-{{ layout }}" id="{{ number }}">
|
<div class="question layout-{{ layout }}" id="{{ number }}" data-quiz-shown>
|
||||||
<div class="question-text">
|
<div class="question-text">
|
||||||
{{ number }}: {{ question }}
|
{{ number }}: {{ question }}
|
||||||
</div>
|
</div>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="solution">
|
<div class="solution" data-quiz-shown>
|
||||||
{% if has_solution %}
|
{% if has_solution %}
|
||||||
<a class="btn btn-warning btn-sm d-inline-flex align-items-center" href="{{ number }}.html" aria-label="Lösungshinweis zu Frage {{ number }}" title="Lösungshinweis">
|
<a class="btn btn-warning btn-sm d-inline-flex align-items-center" href="{{ number }}.html" aria-label="Lösungshinweis zu Frage {{ number }}" title="Lösungshinweis">
|
||||||
<svg class="solution-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" fill="currentColor" aria-hidden="true" focusable="false">
|
<svg class="solution-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" fill="currentColor" aria-hidden="true" focusable="false">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="course-toolbar" style="float: right;">
|
<div class="course-toolbar" style="float: right;" data-quiz-shown>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
{% if section["video_url"] %}
|
{% if section["video_url"] %}
|
||||||
<a class="btn btn-secondary" href="{{ section["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a>
|
<a class="btn btn-secondary" href="{{ section["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav aria-label="breadcrumb">
|
<nav aria-label="breadcrumb" data-quiz-shown>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
|
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
|
||||||
<li class="breadcrumb-item"><a href="{{ edition }}_course_index.html">{{ name }}</a></li>
|
<li class="breadcrumb-item"><a href="{{ edition }}_course_index.html">{{ name }}</a></li>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<h1>{{ section["title"] }}</h1>
|
<h1 data-quiz-shown>{{ section["title"] }}</h1>
|
||||||
|
|
||||||
<a id="margin_0"></a>
|
<a id="margin_0"></a>
|
||||||
{{ section["content"] }}
|
{{ section["content"] }}
|
||||||
Reference in New Issue
Block a user