This commit is contained in:
Philippe Torrel
2026-10-05 14:36:39 +02:00
parent 7ba49fc673
commit 1bd81120cc
19 changed files with 1405 additions and 0 deletions
@@ -0,0 +1,239 @@
* {
margin: 0;
}
html {
font-size: 100%;
padding: 0;
background-attachment: fixed;
background-image: -webkit-linear-gradient(top, #eef0f2, #d3d5d9);
background-image: -moz-linear-gradient(top, #eef0f2, #d3d5d9);
background-image: linear-gradient(to bottom, #eef0f2, #d3d5d9);
}
body {
color: #333;
font-size: 1em;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
text-align: left;
margin: 1em;
padding: 0;
}
p,
h1,
h2,
h3,
h4,
h5,
h6 {
margin-bottom: 1rem;
}
p {
line-height: 1.5em;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
p:last-child {
margin-bottom: 0;
}
a {
color: #2f83e8;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
strong,
b {
font-weight: bold;
}
em,
i {
font-style: italic;
}
.float_left {
float: left;
}
.float_right {
float: right;
}
.disabled {
opacity: 0.4;
cursor: default;
}
.message_number {
color: #fff;
font-size: 0.8em;
font-weight: bold;
text-align: center;
line-height: 1em;
position: absolute;
top: -0.5em;
left: -0.5em;
display: block;
padding-top: 0.3em;
min-width: 2em;
height: 2em;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
cursor: default;
background-color: #ea2314;
background-image: -webkit-linear-gradient(top, #f78f91, #c50404);
background-image: -moz-linear-gradient(top, #f78f91, #c50404);
background-image: linear-gradient(to bottom, #f78f91, #c50404);
border: 2px solid #fff;
-webkit-border-radius: 1em;
-moz-border-radius: 1em;
border-radius: 1em;
-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3);
}
.newsboard_wrapper {
margin: 0 auto 2em auto;
padding: 13px 0 0 17px;
max-width: 550px;
position: relative;
background: url('../img/sheets.png') no-repeat;
}
.newsboard_wrapper:before {
content: url('../img/paperclip.png');
position: absolute;
top: 5px;
right: 35px;
z-index: 1;
}
.newsboard_wrapper .newsboard {
padding: 29px 1.25rem 4rem 1.25rem;
min-height: 20em;
position: relative;
border: 1px solid #ccc;
background-color: #fff;
background-image: -webkit-linear-gradient(#dddddd, #ffffff 1px);
background-image: -moz-linear-gradient(#dddddd, #ffffff 1px);
background-image: linear-gradient(#dddddd, #ffffff 1px);
background-position: 0 1.3em;
-webkit-background-size: 100% 1.5em;
-moz-background-size: 100% 1.5em;
background-size: 100% 1.5em;
-webkit-box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.3);
}
.newsboard_wrapper .newsboard .close_button {
color: #777;
font-size: 1.2em;
text-decoration: none;
line-height: 1em;
position: absolute;
top: 10px;
right: 14px;
display: block;
}
.newsboard_wrapper .newsboard .close_button:hover {
color: #444;
}
.newsboard_wrapper .newsboard .newsboard_footer {
color: #999;
font-size: 0.8em;
}
.newsboard_wrapper .newsboard .paging_bar {
font-size: 1.8em;
padding: 0 1.25rem;
position: absolute;
left: 0;
right: 0;
bottom: 1rem;
white-space: nowrap;
}
.newsboard_wrapper .newsboard .paging_bar .float_left a,
.newsboard_wrapper .newsboard .paging_bar .float_right a {
color: #777;
text-decoration: none;
}
.newsboard_wrapper .newsboard .paging_bar .float_left a {
margin-right: 0.3em;
}
.newsboard_wrapper .newsboard .paging_bar .float_right a {
margin-left: 0.3em;
}
.newsboard_wrapper .newsboard .paging_bar .progressbar {
display: block;
width: 40%;
margin: 0 auto;
}
.newsboard_wrapper .newsboard .paging_bar progress {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
vertical-align: 0;
line-height: normal;
color: #2f83e8;
width: 100%;
height: 0.6rem;
border-style: none;
padding: 0;
background-color: #eee;
-webkit-border-radius: 0.3rem;
-moz-border-radius: 0.3rem;
border-radius: 0.3rem;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
}
.newsboard_wrapper .newsboard .paging_bar progress::-webkit-progress-bar {
padding: 0;
border-style: none;
background-color: transparent;
}
.newsboard_wrapper .newsboard .paging_bar progress::-webkit-progress-value {
-webkit-border-radius: 0.3rem;
border-radius: 0.3rem;
background-color: #2f83e8;
background-image: -webkit-linear-gradient(top, #8bbaf2, #176acd);
background-image: linear-gradient(to bottom, #8bbaf2, #176acd);
}
.newsboard_wrapper .newsboard .paging_bar progress::-moz-progress-bar {
-moz-border-radius: 0.3rem;
border-radius: 0.3rem;
background-color: #2f83e8;
background-image: -moz-linear-gradient(top, #8bbaf2, #176acd);
background-image: linear-gradient(to bottom, #8bbaf2, #176acd);
}
.newsboard_wrapper .newsboard .newsboard_content h1,
.newsboard_wrapper .newsboard .newsboard_content h2 {
font-weight: normal;
font-family:
'Helvetica Neue Light', 'HelveticaNeue-Light', 'Helvetica Light', 'Helvetica-Light', Helvetica, Arial, sans-serif;
letter-spacing: 0.03em;
}
.newsboard_wrapper .newsboard .newsboard_content h1 {
font-size: 1.75em;
}
.newsboard_wrapper .newsboard .newsboard_content h2 {
color: #2f83e8;
font-size: 1.2em;
line-height: 1.4em;
}
.newsboard_wrapper .newsboard .newsboard_content:empty {
color: #999;
font-size: 1.15em;
text-align: center;
padding-top: 10.5rem;
background: url('../img/empty.png') no-repeat center 3.75rem;
}
.newsboard_wrapper .newsboard .newsboard_content:empty:after {
content: 'Keine neuen Mitteilungen.';
}
.sr-only {
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
display: inline-block !important;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1,73 @@
'use strict';
(() => {
// === DOM & VARS =======
const module = document.querySelector('.newsboard') || console.error('newsboard not found');
const DOM = {
messageNumber: module.querySelector('.message_number'),
newsboardContent: module.querySelector('.newsboard_content'),
buttonNext: module.querySelector('.button-next'),
buttonLast: module.querySelector('.button-last'),
buttonPrev: module.querySelector('.button-prev'),
buttonFirst: module.querySelector('.button-first'),
progressBar: module.querySelector('.progressbar progress'),
};
console.log(DOM);
// === INIT =============
const init = () => {
// Funktionaufrufe zu beginn der Anwendung
showMessageByNumber(1);
initProgressbar();
// Eventlauscher zu beginn der Anwendung
DOM.buttonNext.addEventListener('click', onClickNext);
DOM.buttonPrev.addEventListener('click', onClickPrev);
window.addEventListener('keyup', onKeyUp);
};
// === EVENTHANDLER =====
const onKeyUp = (e) => {
// Übung 8.3 && 8.4 Tastatursteuerung
};
const onClickNext = (e) => {
showMessageByNumber((DOM.progressBar.value += 1));
};
const onClickPrev = (e) => {
showMessageByNumber((DOM.progressBar.value -= 1));
};
// === XHR/FETCH ========
// === FUNCTIONS ========
const showMessageByNumber = (n) => {
DOM.newsboardContent.innerHTML = MESSAGES[n - 1];
};
const initProgressbar = () => {
DOM.progressBar.max = MESSAGES.length;
DOM.progressBar.value = 1;
};
init();
})();
// Übung 8: Newsboard: Das geht noch besser
// Das Newsboard wartet noch auf das Vervollständigen seiner Funktionen.
// 1. Belege die Links » und « mit Funktionalität. Der Link mit der Aufschrift « soll es erlauben, zur ersten Nachricht zu springen, der Link » zur letzten.
// 2. Der bisher eher sinnlose rote Kreis in der linken oberen Ecke soll nun die Gesamtanzahl der Nachrichten anzeigen. Schreibe eine Funktion, die diese Anzahl ausliest und in das <span> mit der Klasse message_number einträgt.
// 3. Unterstütze ab sofort das Navigieren durch die News mit der Tastatur. Die Pfeiltasten nach links und rechts sollen dabei jeweils die gleiche Funktionalität wie die Buttons < und > ermöglichen.
// 4. Auch das Springen auf die erste bzw. letzte Position soll nun mit Tastatur möglich sein. Die Tastenkombination dafür ist alt und die Pfeiltaste nach links (zur ersten Nachricht) bzw. rechts (zur letzten Nachricht).
// Übung 9: Newsboard: Jetzt ist aber Schluss!
// Die neuen Features des Newsboards sind schon fast fertig. Problematisch ist aber, dass die Vorwärts- und Rückwärts-Buttons auch aktiv sind, wenn es keine vorige bzw. nächste Nachricht mehr gibt. Dies führt zu einem sehr unschönen Fehler.
// 2. Sorge dafür, dass die Vor- und Rückwärts-Buttons jeweils deaktiviert werden, sobald der Anwender am Anfang bzw. Ende der Nachrichtenliste angekommen ist.
// 3. Auch die Buttons, die den Anwender zur ersten bzw. zur letzten Nachricht führen, sollen deaktiviert sein, sobald sich der Anwender bei der ersten bzw. letzten Nachricht befindet.
@@ -0,0 +1,19 @@
// Konfigurationsvariablen
const MESSAGES = [
`<h1>Tutors are on a strike!!!</h1>
<h2>All assignmnent are automatically graded with 0 points</h2>
<p>Duis pretium ornare odio nec cursus. Nulla quis dolor vitae nulla condimentum maximus nec vitae purus. Curabitur ut mi non nulla molestie porta. Curabitur dignissim lacinia condimentum. In hac habitasse platea dictumst. Mauris ut urna magna. Mauris venenatis eu quam nec posuere. Nulla facilisi. Donec convallis sodales massa, et consequat nunc vehicula malesuada.</p>
<p class="newsboard_footer">9/25/2015 by N. O'body</p>`,
`<h1>Madness!</h1>
<h2>How to earn a fortune, with a complete stupid idea</h2>
<p>Ut molestie elementum risus, eget rutrum dui tristique id. Duis ac elit a mi convallis lacinia. Sed at ultricies magna. Pellentesque nisl est, mattis eget porta eu, rhoncus in urna. Integer faucibus lectus nec malesuada tempus. Duis consectetur sollicitudin ultricies. Cras massa nulla, aliquet vitae interdum quis, venenatis at quam.</p>
<p class="newsboard_footer">08/13/2019 by Dr. Ken Hurt</p>`,
`<h1>I did something, and you will never guess what happened next...</h1>
<h2>Donec tristique, leo at suscipit pellentesque, mauris neque congue leo!</h2>
<p>Aenean egestas mauris at neque egestas hendrerit id ut erat. Donec iaculis ornare gravida. Vestibulum condimentum, tortor nec eleifend consectetur, justo lacus dignissim ante, eget commodo enim urna sollicitudin arcu. Odio eu leo pulvinar rutrum sed a turpis. Nunc dui tortor, rutrum vitae gravida quis, hendrerit a massa. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas</p>
<p>Integer non venenatis tellus. Phasellus tellus leo, suscipit ac vulputate non, varius nec eros. Etiam scelerisque nisi arcu, interdum tempus dui volutpat vel. Donec eget posuere nulla. Etiam ornare dapibus tortor, ac sollicitudin nisi porta a. Donec tristique, leo at suscipit pellentesque, mauris neque congue leo, sed tempor massa justo a ligula. Curabitur vitae rhoncus lacus, quis varius felis. Ut tincidunt sit amet nisl finibus tempus. Curabitur mollis sit amet leo a sagittis.</p>
<p class="newsboard_footer">2015/06/02 by Chris P. Bacon</p>`,
];
@@ -0,0 +1,54 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Newsboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" />
<link rel="stylesheet" type="text/css" href="assets/css/main.css" />
<script src="assets/js/messages.js"></script>
<script src="assets/js/main.js" defer></script>
</head>
<body>
<div class="newsboard_wrapper">
<div class="newsboard">
<span class="message_number">X</span>
<a href="#" class="close_button" title="Delete message">&times;</a>
<div class="newsboard_content"></div>
<div class="paging_bar">
<span class="float_left">
<button class="button-first" title="first" aria-label="First News">
<i class="fa-solid fa-angles-left"></i>
<span class="sr-only">First News</span>
</button>
<button class="button-prev" title="prev" aria-label="Previous News">
<i class="fa-solid fa-angle-left"></i>
<span class="sr-only">Previous News</span>
</button>
</span>
<span class="float_right">
<button class="button-next" title="next" aria-label="Next News">
<i class="fa-solid fa-angle-right"></i>
<span class="sr-only">Next News</span>
</button>
<button class="button-last" title="last" aria-label="Last News">
<i class="fa-solid fa-angles-right"></i>
<span class="sr-only">Last News</span>
</button>
</span>
<span class="progressbar">
<progress max="" value="" id="messages_progress"></progress>
</span>
</div>
</div>
</div>
</body>
</html>
Binary file not shown.
@@ -56,6 +56,94 @@
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// KeyboardEvent ============================
// KeyboardEvent - keydown - wird ausgelöst, wenn Taste gedrückt (mehrfach)
$('#input-search').addEventListener('keydown', (e) => {
console.log('KeyboardEvent: ', e);
console.log('KEY_DOWN');
// console.log('e.code:', e.code);
// console.log('e.key:', e.key);
// const value = e.target.value;
// console.log('input value: ', value);
});
// KeyboardEvent - keypress - wird ausgelöst, wenn Taste gedrückt (einmalig von MacOS 2011 - 2026 und später als keydown) - DEPRECATED
$('#input-search').addEventListener('keypress', (e) => {
console.log('KeyboardEvent: ', e);
console.log('KEY_PRESS');
// console.log('e.code:', e.code);
// console.log('e.key:', e.key);
// const value = e.target.value;
// console.log('input value: ', value);
});
// KeyboardEvent - keyup - wird ausgelöst, wenn Taste losgelassen wird
$('#input-search').addEventListener('keyup', (e) => {
console.log('KeyboardEvent: ', e);
console.log('KEY_UP');
console.log('e.code:', e.code);
console.log('e.key:', e.key);
const value = e.target.value;
console.log('input value: ', value);
});
// InputEvent ================================
$('#input-search').addEventListener('input', (e) => {
console.log('======');
console.log('InputEvent: ', e);
console.log('INPUT');
console.log('e.data: ', e.data);
console.log('e.target.value: ', e.target.value);
console.log('======');
});
// InputEvent - input - wird ausgelöst, bei jeder Veränderung (range, input, textarea)
$('#input-range').addEventListener('input', (e) => {
console.log('======');
// console.log('InputEvent: ', e);
console.log('INPUT');
console.log('e.target.value: ', e.target.value);
console.log('======');
});
// InputEvent - change - wird ausgelöst, bei jeder Bestätigung (select, checkbox, radio)
$('#select-country').addEventListener('change', (e) => {
console.log('======');
// console.log('InputEvent: ', e);
console.log('CHANGE');
console.log('e.target.value: ', e.target.value);
console.log('======');
});
$('#cb-agb').addEventListener('change', (e) => {
console.log('======');
// console.log('InputEvent: ', e);
console.log('CHANGE');
console.log('e.target.checked: ', e.target.checked);
console.log('======');
});
// FocusEvent - focus - wird ausgelöst, wenn ein Element den "Fokus" erhält
$('#input-search').addEventListener('focus', (e) => {
console.log('=======');
console.log('FocusEvent: ', e);
console.log('FOCUS');
});
// FocusEvent - blur - wird ausgelöst, wenn ein Element den "Fokus" verliert
$('#input-search').addEventListener('blur', (e) => {
console.log('=======');
console.log('FocusEvent: ', e);
console.log('BLUR');
});
</script>
</body>
</html>
@@ -0,0 +1,368 @@
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
/* ---------------- CSS-Reset ------------------- */
html,
body,
a,
div,
h1,
h2,
h3,
h4,
h5,
h6,
span,
p,
img,
strong,
ul,
li,
table,
th,
td,
tr {
margin: 0px;
padding: 0px;
border: 0px none;
font-weight: normal;
font-style: inherit;
font-family: inherit;
font-variant: inherit;
text-decoration: none;
table-layout: inherit;
}
/* ---------------- Body / HTML ------------------- */
html {
font-size: 100%;
background-color: #fffef7;
}
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 1.2em;
font-weight: normal;
color: black;
margin: 0rem auto 2rem auto;
}
/* ---------------- layout ------------------- */
header {
background: url('../img/js_header.png') left top no-repeat transparent;
background-size: cover;
height: 250px;
min-width: 850px;
}
header:after {
content: ' ';
display: block;
height: 250px;
background: rgba(255, 254, 247, 0);
background: -moz-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -webkit-gradient(
left top,
left bottom,
color-stop(0%, rgba(255, 254, 247, 0)),
color-stop(22%, rgba(255, 254, 247, 0.55)),
color-stop(42%, rgba(255, 254, 247, 0.7)),
color-stop(43%, rgba(255, 254, 247, 0.71)),
color-stop(61%, rgba(255, 254, 247, 0.78)),
color-stop(75%, rgba(255, 254, 247, 0.92)),
color-stop(87%, rgba(255, 254, 247, 1)),
color-stop(100%, rgba(255, 254, 247, 1))
);
background: -webkit-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -o-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -ms-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: linear-gradient(
to bottom,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
}
main,
footer {
width: 70%;
margin: 3rem auto;
min-width: 850px;
padding: 0 20px;
box-sizing: border-box;
}
/* ---------------- Content ------------------- */
h1 {
color: #93412b;
font-size: 3em;
margin-bottom: 20px;
font-weight: bold;
}
h2 {
color: #93412b;
font-size: 2.5em;
margin-bottom: 15px;
}
h3 {
color: #93412b;
font-size: 2em;
margin-bottom: 10px;
}
p {
line-height: 15px;
margin-bottom: 15px;
line-height: 1.7em;
}
.cited {
font-style: italic;
font-size: 0.8em;
}
.u {
text-decoration: underline;
}
.b {
font-weight: bold;
}
.i {
font-style: italic;
}
.align_right {
text-align: right;
}
.align_left {
text-align: left;
margin-right: 10px;
}
.align_center {
text-align: center;
}
.float_left {
float: left;
}
.float_right {
float: right;
}
.clear_both {
clear: both;
}
strong {
font-weight: bold;
}
.special {
color: #b7595b;
font-weight: bold;
}
.keyword {
color: #db6f50;
font-weight: bold;
font-style: italic;
}
.gray {
color: gray;
}
/* Links */
main a:link,
main a:visited {
color: #eb690b;
font-weight: bold;
}
main a:focus,
main a:hover,
main a:active {
color: #eb690b;
}
ul {
list-style-position: outside;
margin-bottom: 20px;
padding-left: 22px;
}
ol {
margin-bottom: 20px;
padding-left: 30px;
}
li {
line-height: 1.4em;
}
/* ------- Article ------- */
h1 {
color: #93412b;
font-size: 2.7em;
margin-bottom: 20px;
}
#buy_form input[type='button'] {
display: inline-block;
padding: 1px 20px 3px 20px;
background-color: #93412b;
color: white;
border: 1px solid white;
font-size: 1em;
height: 32px;
}
#buy_form input[type='button']:hover {
background-color: white;
color: #93412b;
border: 1px solid #93412b;
}
#buy_form select {
display: inline-block;
font-size: 1em;
background-color: white;
color: #93412b;
border: 1px solid #93412b;
height: 32px;
}
/* ------- Chat ------- */
#chat {
width: 100%;
background-color: white;
border: 1px solid #9c352f;
height: 20rem;
position: relative;
}
#chat_window {
background-color: white;
width: 85%;
float: left;
height: 95%;
}
#chat_history {
position: absolute;
bottom: 8%;
max-height: 92%;
padding: 0px 0px 5px 7px;
}
#chat_history p {
font-size: 0.6em;
margin: 0;
}
#chat_text {
height: 8%;
position: absolute;
bottom: 0;
width: 85%;
}
#chat_text input {
width: 98%;
display: block;
margin: auto;
}
#chat_members {
list-style-type: none;
height: 100%;
width: 15%;
margin-left: 85%;
border-left: 1px solid #9c352f;
text-align: right;
box-sizing: border-box;
min-width: 100px;
font-size: 0.8em;
padding-top: 5px;
}
#chat_members li {
line-height: 1.2em;
padding: 5px 10px 2px 15px;
}
#chat_members .highlighted {
background-color: #c14d45;
color: white;
}
.chat_member {
font-weight: bold;
}
.chat_member1 {
color: #3626c8;
}
.chat_member2 {
color: #e38d0b;
}
#member_search {
position: absolute;
right: 0;
bottom: 0;
width: 15%;
height: 8%;
}
#member_search input {
width: 88%;
display: block;
margin: auto;
text-align: right;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,37 @@
'use strict';
{
const init = () => {
$('#member_search input').addEventListener('keyup', () => {
updateHighlightingOfChatMembers($('#member_search input').value);
});
};
const updateHighlightingOfChatMembers = (partOfMemberName) => {
removeHighlightsFromAllChatMembers();
highlightChatMembersBy(partOfMemberName);
};
const removeHighlightsFromAllChatMembers = () => {
chatMembers().forEach(removeHighlight);
};
const highlightChatMembersBy = (partOfMemberName) => {
if (partOfMemberName === '') return;
chatMembers()
.filter((member) => doesMemberMatch(partOfMemberName, member))
.forEach(highlight);
};
const doesMemberMatch = (partOfMemberName, member) =>
member.innerHTML.toLowerCase().includes(partOfMemberName.toLowerCase());
const chatMembers = () => $$('#chat_members li');
const highlight = (el) => el.classList.add('highlighted');
const removeHighlight = (el) => el.classList.remove('highlighted');
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
init();
}
@@ -0,0 +1,53 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>classList - DOMTokenList</title>
<!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" /> -->
<link rel="stylesheet" href="assets/css/styles.css" />
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
<script src="assets/js/main.js" defer></script>
</head>
<body>
<header></header>
<main>
<div class="container py-5">
<h1>classList - <a href="https://developer.mozilla.org/de/docs/Web/API/DOMTokenList">DOMTokenList</a></h1>
<hr />
<h2>The Chat</h2>
<div id="chat">
<div id="chat_window">
<div id="chat_history">
<p>
<span class="chat_member chat_member1">Ladislaus:</span>
Anybody there?
</p>
<p>
<span class="chat_member chat_member2">Friedlinde</span>
Yes, me!
</p>
</div>
<div id="chat_text">
<input type="text" placeholder="...new message..." />
</div>
</div>
<ul id="chat_members">
<li class="admin">Heribert</li>
<li>Friedlinde</li>
<li>Tusnelda</li>
<li>Berthold</li>
<li>Oswine</li>
<li>Ladislaus</li>
</ul>
<div id="member_search">
<input type="text" placeholder="...Find a member..." />
</div>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,368 @@
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
/* ---------------- CSS-Reset ------------------- */
html,
body,
a,
div,
h1,
h2,
h3,
h4,
h5,
h6,
span,
p,
img,
strong,
ul,
li,
table,
th,
td,
tr {
margin: 0px;
padding: 0px;
border: 0px none;
font-weight: normal;
font-style: inherit;
font-family: inherit;
font-variant: inherit;
text-decoration: none;
table-layout: inherit;
}
/* ---------------- Body / HTML ------------------- */
html {
font-size: 100%;
background-color: #fffef7;
}
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 1.2em;
font-weight: normal;
color: black;
margin: 0rem auto 2rem auto;
}
/* ---------------- layout ------------------- */
header {
background: url('../img/js_header.png') left top no-repeat transparent;
background-size: cover;
height: 250px;
min-width: 850px;
}
header:after {
content: ' ';
display: block;
height: 250px;
background: rgba(255, 254, 247, 0);
background: -moz-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -webkit-gradient(
left top,
left bottom,
color-stop(0%, rgba(255, 254, 247, 0)),
color-stop(22%, rgba(255, 254, 247, 0.55)),
color-stop(42%, rgba(255, 254, 247, 0.7)),
color-stop(43%, rgba(255, 254, 247, 0.71)),
color-stop(61%, rgba(255, 254, 247, 0.78)),
color-stop(75%, rgba(255, 254, 247, 0.92)),
color-stop(87%, rgba(255, 254, 247, 1)),
color-stop(100%, rgba(255, 254, 247, 1))
);
background: -webkit-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -o-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -ms-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: linear-gradient(
to bottom,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
}
main,
footer {
width: 70%;
margin: 3rem auto;
min-width: 850px;
padding: 0 20px;
box-sizing: border-box;
}
/* ---------------- Content ------------------- */
h1 {
color: #93412b;
font-size: 3em;
margin-bottom: 20px;
font-weight: bold;
}
h2 {
color: #93412b;
font-size: 2.5em;
margin-bottom: 15px;
}
h3 {
color: #93412b;
font-size: 2em;
margin-bottom: 10px;
}
p {
line-height: 15px;
margin-bottom: 15px;
line-height: 1.7em;
}
.cited {
font-style: italic;
font-size: 0.8em;
}
.u {
text-decoration: underline;
}
.b {
font-weight: bold;
}
.i {
font-style: italic;
}
.align_right {
text-align: right;
}
.align_left {
text-align: left;
margin-right: 10px;
}
.align_center {
text-align: center;
}
.float_left {
float: left;
}
.float_right {
float: right;
}
.clear_both {
clear: both;
}
strong {
font-weight: bold;
}
.special {
color: #b7595b;
font-weight: bold;
}
.keyword {
color: #db6f50;
font-weight: bold;
font-style: italic;
}
.gray {
color: gray;
}
/* Links */
main a:link,
main a:visited {
color: #eb690b;
font-weight: bold;
}
main a:focus,
main a:hover,
main a:active {
color: #eb690b;
}
ul {
list-style-position: outside;
margin-bottom: 20px;
padding-left: 22px;
}
ol {
margin-bottom: 20px;
padding-left: 30px;
}
li {
line-height: 1.4em;
}
/* ------- Article ------- */
h1 {
color: #93412b;
font-size: 2.7em;
margin-bottom: 20px;
}
#buy_form input[type='button'] {
display: inline-block;
padding: 1px 20px 3px 20px;
background-color: #93412b;
color: white;
border: 1px solid white;
font-size: 1em;
height: 32px;
}
#buy_form input[type='button']:hover {
background-color: white;
color: #93412b;
border: 1px solid #93412b;
}
#buy_form select {
display: inline-block;
font-size: 1em;
background-color: white;
color: #93412b;
border: 1px solid #93412b;
height: 32px;
}
/* ------- Chat ------- */
#chat {
width: 100%;
background-color: white;
border: 1px solid #9c352f;
height: 20rem;
position: relative;
}
#chat_window {
background-color: white;
width: 85%;
float: left;
height: 95%;
}
#chat_history {
position: absolute;
bottom: 8%;
max-height: 92%;
padding: 0px 0px 5px 7px;
}
#chat_history p {
font-size: 0.6em;
margin: 0;
}
#chat_text {
height: 8%;
position: absolute;
bottom: 0;
width: 85%;
}
#chat_text input {
width: 98%;
display: block;
margin: auto;
}
#chat_members {
list-style-type: none;
height: 100%;
width: 15%;
margin-left: 85%;
border-left: 1px solid #9c352f;
text-align: right;
box-sizing: border-box;
min-width: 100px;
font-size: 0.8em;
padding-top: 5px;
}
#chat_members li {
line-height: 1.2em;
padding: 5px 10px 2px 15px;
}
#chat_members .highlighted {
background-color: #c14d45;
color: white;
}
.chat_member {
font-weight: bold;
}
.chat_member1 {
color: #3626c8;
}
.chat_member2 {
color: #e38d0b;
}
#member_search {
position: absolute;
right: 0;
bottom: 0;
width: 15%;
height: 8%;
}
#member_search input {
width: 88%;
display: block;
margin: auto;
text-align: right;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,53 @@
'use strict';
// IIFE
(() => {
// === DOM & VARS =======
const module = document.querySelector('#chat') || console.warn('Element not found');
const DOM = {
module,
listItems: Array.from(module.querySelectorAll('#chat_members li')),
inputSearch: module.querySelector('#member_search input'),
};
console.log(DOM);
// === INIT =============
const init = () => {
// EventLauscher
DOM.inputSearch.addEventListener('input', onInputSearch);
// Funktionsaufruf zu beginn der Anwendung
// highlightListItemsBy('ert');
};
// === EVENTHANDLER =====
const onInputSearch = (e) => {
const inputEl = e.target;
highlightListItemsBy(inputEl.value);
};
// === XHR/FETCH ========
// === FUNCTIONS ========
const highlightListItemsBy = (searchValue = '') => {
DOM.listItems.forEach((el) => {
el.classList.remove('highlighted');
const text = el.textContent.trim().toLowerCase();
if (searchValue != '' && text.includes(searchValue.trim().toLowerCase())) {
// el.classList.add('highlighted');
addClass(el, 'highlighted');
}
});
};
// helpers
const addClass = (el, className) => {
if (Array.isArray(className)) {
el.classList.add(...className);
} else {
el.classList.add(className);
}
return el;
};
init();
})();
@@ -0,0 +1,53 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>classList - DOMTokenList</title>
<!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" /> -->
<link rel="stylesheet" href="assets/css/styles.css" />
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
<script src="assets/js/main.js" defer></script>
</head>
<body>
<header></header>
<main>
<div class="container py-5">
<h1>classList - <a href="https://developer.mozilla.org/de/docs/Web/API/DOMTokenList">DOMTokenList</a></h1>
<hr />
<h2>The Chat</h2>
<div id="chat">
<div id="chat_window">
<div id="chat_history">
<p>
<span class="chat_member chat_member1">Ladislaus:</span>
Anybody there?
</p>
<p>
<span class="chat_member chat_member2">Friedlinde</span>
Yes, me!
</p>
</div>
<div id="chat_text">
<input type="text" placeholder="...new message..." />
</div>
</div>
<ul id="chat_members">
<li class="admin">Heribert</li>
<li>Friedlinde</li>
<li>Tusnelda</li>
<li>Berthold</li>
<li>Oswine</li>
<li>Ladislaus</li>
</ul>
<div id="member_search">
<input type="search" placeholder="...Find a member..." />
</div>
</div>
</div>
</main>
</body>
</html>