This commit is contained in:
Philippe Torrel
2026-07-16 14:40:36 +02:00
parent a78c7aa1be
commit 145dee58e6
39 changed files with 1553 additions and 31 deletions

View File

@@ -360,11 +360,11 @@ Projektarbeit
**Übungen:**
Übung 09 - 13
Übung 08 - 10
---
#### Tag 25
#### Tag 24
**Inhalt:**
@@ -376,6 +376,6 @@ Projektarbeit
**Übungen:**
Übung 14
Übung 11 - 14
---

View File

@@ -18,38 +18,127 @@
// === INIT =============
const init = () => {
// Funktionaufrufe zu beginn der Anwendung
showMessageByNumber(1);
//////////////////
// Start 9.2 & 9.3
// ich musste hier die Reihenfolge ändern, damit meine Lösung funktioniert
// sonst wäre DOM.progressBar.value = 0 (wird erst in der initPro... auf 1 initialisiert)
initProgressbar();
updateMessageByNumber(1);
// Ende 9.2 & 9.3
/////////////////
////////////////
// Start 8.2
setMessageNumber(1);
// Ende 8.2
////////////////
// Eventlauscher zu beginn der Anwendung
DOM.buttonNext.addEventListener('click', onClickNext);
DOM.buttonPrev.addEventListener('click', onClickPrev);
///////////////////////
// Start 8.1
DOM.buttonFirst.addEventListener('click', onClickFirst);
DOM.buttonLast.addEventListener('click', onClickLast);
// Ende 8.1
///////////////
window.addEventListener('keyup', onKeyUp);
};
// === EVENTHANDLER =====
const onKeyUp = (e) => {
// Übung 8.3 && 8.4 Tastatursteuerung
console.log(e);
if (e.key === 'ArrowLeft') {
if (!e.altKey) {
onClickPrev(e);
} else {
onClickFirst(e);
}
} else if (e.key === 'ArrowRight') {
if (!e.altKey) {
onClickNext(e);
} else {
onClickLast(e);
}
}
};
const onClickNext = (e) => {
showMessageByNumber((DOM.progressBar.value += 1));
updateMessageByNumber((DOM.progressBar.value += 1));
};
const onClickPrev = (e) => {
showMessageByNumber((DOM.progressBar.value -= 1));
updateMessageByNumber((DOM.progressBar.value -= 1));
};
//////////////////
// Start 8.1
const onClickFirst = (e) => {
updateMessageByNumber((DOM.progressBar.value = 1));
};
const onClickLast = (e) => {
updateMessageByNumber((DOM.progressBar.value = MESSAGES.length));
};
// Ende 8.1
/////////////////////////
// === XHR/FETCH ========
// === FUNCTIONS ========
const showMessageByNumber = (n) => {
const updateMessageByNumber = (n) => {
DOM.newsboardContent.innerHTML = MESSAGES[n - 1];
//////////////
// Start 8.2
setMessageNumber(n);
// Ende 8.2
//////////////////
//////////////////
// Start 9.2
updateBtnState();
// Ende 9.2
///////////////////////
};
/////////////////////////
// Start 9.2
const updateBtnState = () => {
const n = DOM.progressBar.value;
if (n === 1) {
// wir sind am Anfang, also die linken Buttons AUSschalten und
// die rechten EINschalten
DOM.buttonFirst.disabled = DOM.buttonPrev.disabled = true;
DOM.buttonLast.disabled = DOM.buttonNext.disabled = false;
} else if (n > 1 && n < MESSAGES.length) {
// wir sind mitten in der message liste - also alle Buttons aktivieren
DOM.buttonFirst.disabled = false;
DOM.buttonPrev.disabled = false;
DOM.buttonLast.disabled = false;
DOM.buttonNext.disabled = false;
} else if (n === MESSAGES.length) {
// wir sind am Ende, also die linken Buttons EINschalten und
// die rechten EINschalten
DOM.buttonLast.disabled = DOM.buttonNext.disabled = true;
DOM.buttonFirst.disabled = DOM.buttonPrev.disabled = false;
}
};
// Ende 9.2 & 9.3
/////////////////////
const initProgressbar = () => {
DOM.progressBar.max = MESSAGES.length;
DOM.progressBar.value = 1;
};
//////////////
// Start 8.2
const setMessageNumber = (n) => {
DOM.messageNumber.textContent = `${n}/${MESSAGES.length}`;
};
// Ende 8.2
/////////////////////////////////
init();
})();

View File

@@ -0,0 +1,51 @@
'use strict';
(() => {
// === DOM & VARS =======
const module = document.querySelector('.light-bulbs');
const DOM = {
lights: Array.from(module.querySelectorAll('img[alt="lightbulb"]')),
};
const LIGHT_PATH_ON = 'assets/img/light_on.png';
const LIGHT_PATH_OFF = 'assets/img/light_off.png';
//
// === INIT =============
const init = () => {
// Eventlistener für jede Lampe
DOM.lights.forEach((light) => {
light.addEventListener('mouseenter', enterMouseLight);
});
turnAllLightsOff();
};
// === EVENTHANDLER =====
const enterMouseLight = (e) => {
// idx des aktuellen lichtes holen
console.log(e.target);
const idx = DOM.lights.indexOf(e.target);
if (idx === -1) return;
// nu alle lichter aus
turnAllLightsOff();
// mit den index das nächste licht einschalten oder das erste, wenn das letzte an ist
if (idx === DOM.lights.length - 1) {
DOM.lights[0].src = LIGHT_PATH_ON;
} else {
DOM.lights[idx + 1].src = LIGHT_PATH_ON;
}
};
// === XHR/FETCH ========
// === FUNCTIONS ========
const turnAllLightsOff = () => {
DOM.lights.forEach((light) => {
light.src = LIGHT_PATH_OFF;
});
};
init();
})();

View File

@@ -0,0 +1,68 @@
'use strict';
(() => {
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// === DOM & VARS =======
const DOM = {
// Alle Glühbirnen-Bilder auswählen
bulbs: $$('.light-bulbs img'),
};
const LIGHT_PATH_ON = 'assets/img/light_on.png';
const LIGHT_PATH_OFF = 'assets/img/light_off.png';
// Zähler
let activeIndex = 0;
// === INIT =============
const init = () => {
if (DOM.bulbs.length === 0) return;
// zustand reseten
updateLights(); // first bulb on
DOM.bulbs.forEach((bulb, index) => {
bulb.addEventListener('mouseenter', (e) => onBulbHover(e, index));
bulb.addEventListener('click', onBulbClick);
});
};
// === EVENTHANDLER =====
const onBulbHover = (e, hoveredIndex) => {
if (hoveredIndex === activeIndex) {
nextLight();
}
};
const onBulbClick = () => {
nextLight();
};
// === FUNCTIONS ========
const nextLight = () => {
activeIndex++;
if (activeIndex >= DOM.bulbs.length) {
activeIndex = 0;
}
updateLights();
};
const updateLights = () => {
DOM.bulbs.forEach((bulb, index) => {
if (index === activeIndex) {
bulb.src = LIGHT_PATH_ON;
} else {
bulb.src = LIGHT_PATH_OFF;
}
});
};
init();
})();

View File

@@ -2,19 +2,55 @@
(() => {
// === DOM & VARS =======
const DOM = {};
const module = document.querySelector('.light-bulbs');
const DOM = {
lightBulbs: Array.from(module.querySelectorAll('img[alt="lightbulb"]')),
};
const LIGHT_PATH_ON = 'assets/img/light_on.png';
const LIGHT_PATH_OFF = 'assets/img/light_off.png';
// console.log(DOM);
// === INIT =============
const init = () => {};
const init = () => {
setAllLightsOff();
DOM.lightBulbs.forEach((el, idx) => {
el.dataset.index = idx; // Index im HTMLImageElement ablegen (V1)
el.addEventListener('mouseenter', (e) => onMouseEnter(e, idx)); // Index als zweiten Parameter mitgeben (V2)
});
};
// === EVENTHANDLER =====
const onMouseEnter = (e, idx) => {
// const index = e.currentTarget.dataset.index;
const img = e.currentTarget;
const index = getIndexBy(img); // Index über Funktion ermitteln (V3)
// if (e.currentTarget.src.includes(LIGHT_PATH_ON)) {
const nextIndex = getNextIndex(index);
console.log(nextIndex);
setAllLightsOff();
DOM.lightBulbs[nextIndex].src = LIGHT_PATH_ON;
//
};
// === XHR/FETCH ========
// === FUNCTIONS ========
const getIndexBy = (img) => {
return DOM.lightBulbs.indexOf(img);
};
const getNextIndex = (currentIndex) => {
return currentIndex === DOM.lightBulbs.length - 1 ? 0 : currentIndex + 1;
};
const setAllLightsOff = () => {
DOM.lightBulbs.forEach((el) => {
el.src = LIGHT_PATH_OFF;
});
};
init();
})();

View File

@@ -0,0 +1,369 @@
/* -------------------------------------------- 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,
.grey {
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,107 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>010010000100111101010100</title>
<meta name="description" content="JavaScript. HTML mühelos manipuliert" />
<link rel="stylesheet" href="assets/css/styles.css" type="text/css" media="screen" />
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
</head>
<body>
<header></header>
<main>
<h1 class="article">
Hot Binary Heat Changing Mug
<span class="keyword">"010010000100111101010100"</span>
</h1>
<img
alt="Hot Binary Heat Changing Mug"
src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug.gif"
class="float_left"
id="product_img" />
<h2>Description</h2>
<p>
Numbers make up
<span class="special">everything</span> in our digital world. They flow around us, invisible like the Force or
the Matrix, controlling all our many computer-y devices. Two numbers, in particular:
<span class="special">0 and 1</span>. <span class="b i">Off and On</span>. Well, we can tell you this: when
there's no coffee in our cup, we're completely OFF our game. But when our mug is full of hot coffee, we're
totally ON. And now, with the <span class="keyword">Hot Binary Heat Changing Mug</span>, there's a mug that
tells us which state our mug is in. In binary!
</p>
<p>
See, the
<span class="keyword">Hot Binary Heat Changing Mug</span>
looks like just a dark mug with binary numbers all over it. That's its OFF or cold state. Add hot coffee (or any
liquid) and a series of digits will turn white. Read them continuously from left to right, and you'll read:
<span class="keyword">010010000100111101010100</span>. That's <span class="special">in binary</span>. Of course,
your
<span class="keyword">Hot Binary Heat Changing Mug</span>
could just be paying you a compliment. Cheeky, mug.
</p>
<p>
<img alt="010010000100111101010100" src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug_grid_embed.jpg" />
</p>
<h2>Product Specifications</h2>
<ul id="product_specification">
<li class="keyword">Hot Binary Heat Changing Mug</li>
<li>
As you add hot liquids, the binary for "HOT" appears (read from left to right in one line, not two:
010010000100111101010100)
</li>
<li>A <span class="keyword">ThinkGeek</span> creation and exclusive!</li>
<li>
Care Instructions:
<span class="i b">Hand wash only. Not microwave or dishwasher safe.</span>
</li>
<li>Materials: Ceramic</li>
<li>Dimensions: approx. 3.15" diameter x 3.75" tall</li>
</ul>
<h3>You wanna buy it?</h3>
<p class="buy_info_text">If you like to buy this brilliant mug, just do the following steps:</p>
<ol class="model" data-model="LDV73C-X3">
<li>Select how many items do you want.</li>
<li>Press "buy".</li>
</ol>
<form id="buy_form">
<select>
<option>1 item</option>
<option>2 items</option>
<option>3 items</option>
<option>4 items</option>
</select>
<input type="button" value="buy" />
</form>
</main>
<footer>(C) by ThinkGeek &ndash; Produkttext mit freundlicher Genehmigung von ThinkGeek Inc.</footer>
<script>
'use strict';
{
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// Übung 11: — Teil 6
// Der neue Wunsch besteht darin, den Text blau (blue) zu färben. Dieses Mal darfst du keine CSS-Klassen verwenden.
// Weise allen p-Elementen mithilfe des Style-Objektes die Farbe blue zu. Du kannst dafür direkt die JavaScript-Konsole verwenden.
}
</script>
</body>
</html>

View File

@@ -0,0 +1,49 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 12: Farbe Wechsel Dich</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" />
<style>
button[data-color] {
border: 5px solid #efefef;
}
</style>
</head>
<body>
<main>
<div class="container py-5">
<h1>Übung 12: Farbe Wechsel Dich</h1>
<div class="buttons">
<button class="btn btn-danger button-red" data-color="#c00"><i class="fa-solid fa-droplet"></i>Red</button>
<button class="btn btn-success button-green" data-color="#080">
<i class="fa-solid fa-droplet"></i>Green
</button>
<button class="btn btn-primary button-blue" data-color="#00F"><i class="fa-solid fa-droplet"></i>Blue</button>
</div>
</div>
</main>
<script>
'use strict';
(() => {
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// === DOM & VARS =======
const DOM = {};
// === INIT =============
const init = () => {};
// === EVENTHANDLER =====
init();
// Übung 12: Farbe wechsle dich
// Platziere drei Buttons (button-Tag) auf einer Seite mit den Texten »Red«, »Green« und »Blue«. Bei Betätigung eines Buttons soll sich der Hintergrund der Seite entsprechend färben.
})();
</script>
</body>
</html>

View File

@@ -0,0 +1,89 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 13: Farbe Wechsel Dich — Teil 2</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
.range-colors > div {
background-color: rgba(200, 200, 200, 0.6);
padding: 2rem;
margin: 1rem 0;
}
</style>
</head>
<body>
<main>
<div class="container py-5">
<h1>Übung 13: Farbe Wechsel Dich — Teil 2</h1>
<div class="range-colors">
<div class="mb-3">
<label for="input-red" class="form-label">Rot</label>
<input
type="range"
class="form-range input-red"
name="red"
id="input-red"
min="0"
max="255"
step="1"
value="255" />
</div>
<div class="mb-3">
<label for="input-green" class="form-label">Grün</label>
<input
type="range"
class="form-range input-green"
name="green"
id="input-green"
min="0"
max="255"
step="1"
value="255" />
</div>
<div class="mb-3">
<label for="input-blue" class="form-label">Blau</label>
<input
type="range"
class="form-range input-blue"
name="blue"
id="input-blue"
min="0"
max="255"
step="1"
value="255" />
</div>
<div class="mb-3">
<strong>Aktuelle Farbe:</strong>
<span id="current-color">rgb(255, 255, 255)</span>
<span id="current-hex-color">#FFFFFF</span>
</div>
</div>
</div>
</main>
<script>
'use strict';
(() => {
// === DOM & VARS =======
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
const DOM = {};
// === INIT =============
const init = () => {};
// === EVENTHANDLER =====
// === XHR/FETCH ========
// === FUNCTIONS ========
init();
})();
</script>
</body>
</html>

View File

@@ -0,0 +1,86 @@
.main-wrapper {
margin: 5rem auto;
width: 650px;
padding: 1rem;
border: 1px solid black;
}
.tours-grid {
display: grid;
width: 100%;
grid-template-columns: 1fr 1fr;
grid-template-rows: 200px 200px 0.5fr;
gap: 1rem;
grid-template-areas:
'item1 item2'
'item1 item3'
'item4 item4';
}
#fr {
grid-area: item1;
}
#uk {
grid-area: item2;
}
#it {
grid-area: item3;
}
#info {
grid-area: item4;
border: 2px solid #000077;
padding: 0.5rem;
border-radius: 10px;
}
img {
width: 100%;
height: 100%;
border-radius: 10px;
}
.tours {
position: relative;
}
.m-tours #info img {
width: 30px;
}
.flag {
font-size: 1.5rem;
}
.french-flag::before {
content: '';
display: inline-block;
width: 50px;
height: 30px;
background: red url('../img/fr.png') no-repeat;
background-size: cover;
margin-right: 0.5rem;
}
.union-jack::before {
content: '';
display: inline-block;
width: 60px;
height: 30px;
background: red url('../img/uk.png') no-repeat;
background-size: cover;
margin-right: 0.5rem;
}
.italian-flag::before {
content: '';
display: inline-block;
width: 60px;
height: 30px;
background: red url('../img/it.png') no-repeat;
background-size: cover;
margin-right: 0.5rem;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-fr" viewBox="0 0 640 480">
<path fill="#fff" d="M0 0h640v480H0z"/>
<path fill="#000091" d="M0 0h213.3v480H0z"/>
<path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
</svg>

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-it" viewBox="0 0 640 480">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#fff" d="M0 0h640v480H0z"/>
<path fill="#009246" d="M0 0h213.3v480H0z"/>
<path fill="#ce2b37" d="M426.7 0H640v480H426.7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-gb" viewBox="0 0 640 480">
<path fill="#012169" d="M0 0h640v480H0z"/>
<path fill="#FFF" d="m75 0 244 181L562 0h78v62L400 241l240 178v61h-80L320 301 81 480H0v-60l239-178L0 64V0z"/>
<path fill="#C8102E" d="m424 281 216 159v40L369 281zm-184 20 6 35L54 480H0zM640 0v3L391 191l2-44L590 0zM0 0l239 176h-60L0 42z"/>
<path fill="#FFF" d="M241 0v480h160V0zM0 160v160h640V160z"/>
<path fill="#C8102E" d="M0 193v96h640v-96zM273 0v480h96V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 504 B

View File

@@ -0,0 +1,17 @@
'use strict';
(() => {
// === DOM & VARS =======
const DOM = {};
// === INIT =============
const init = () => {};
// === EVENTHANDLER =====
// === XHR/FETCH ========
// === FUNCTIONS ========
init();
})();

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 14: awesome tours</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="assets/css/awesome-tours.css" />
<script src="assets/js/awesome-tours.js" defer></script>
</head>
<body>
<main>
<div class="main-wrapper">
<h1>Übung 14: awesome tours</h1>
<div class="m-tours tours-grid">
<div id="fr">
<img
src="assets/img/eiffelturm.jpg"
alt="Eiffel Tower"
data-description="The Eiffel Tower (/ˈaɪfəl ˈtaʊər/ eye-fəl towr; French: Tour Eiffel French pronunciation: [tuʁ‿ɛfɛl] About this sound listen) is a wrought iron lattice tower on the Champ de Mars in Paris, France. It is named after the engineer Gustave Eiffel, whose company designed and built the tower..."
data-country-code="fr"
data-flag-name="French-Flag" />
</div>
<div id="uk">
<img
src="assets/img/tower_bridge.jpg"
alt="Tower Bride"
data-description="Tower Bridge (built 18861894) is a combined bascule and suspension bridge in London. The bridge crosses the River Thames close to the Tower of London and has become an iconic symbol of London. Tower Bridge is one of five London bridges now owned..."
data-country-code="uk"
data-flag-name="Union-Jack" />
</div>
<div id="it">
<img
src="assets/img/colosseum.jpg"
alt="Colosseum"
data-description="The Colosseum or Coliseum (/kɒləˈsiːəm/ kol-ə-see-əm), also known as the Flavian Amphitheatre (Latin: Amphitheatrum Flavium; Italian: Anfiteatro Flavio [amfiteˈaːtro ˈflaːvjo] or Colosseo [kolosˈːo]), is an oval amphitheatre in the centre of the city of Rome, Italy. Built of concrete and sand,[1] it is the largest amphitheatre ever built. The Colosseum is situated just east of the Roman Forum. Construction began..."
data-country-code="it"
data-flag-name="Italian-Flag" />
</div>
<section id="info">
<p>Move your mouse pointer over the images to read the descriptions here!</p>
</section>
</div>
</div>
</main>
</body>
</html>

Binary file not shown.

View File

@@ -22,7 +22,8 @@
// === EVENTHANDLER =====
const onInputSearch = (e) => {
const value = e.target.value; // aktuelle Eingabe von input
const inputEl = e.target;
const value = inputEl.value; // aktuelle Eingabe von input
highlightListItemBy(value);
};

View File

@@ -55,15 +55,16 @@
DOM.buttonCheckOnOff = $('.button-check-on-off');
// IDL mit boolscher Wertzuweisung (RECOMMENDED)
DOM.cbAgb.checked = true;
DOM.cbAgb.checked = true; // DOM.cbAgb.setAttribute('checked', '') <- Alternative NOT RECOMMENDED
DOM.inputSearch.required = false;
DOM.inputSearch.readOnly = false;
DOM.cbAgb.checked = false;
DOM.btnSend.disabled = true;
// Content Attribut Methoden
DOM.btnSend.removeAttribute('disabled');
DOM.btnSend.setAttribute('disabled', '');
DOM.btnSend.setAttribute('disabled', ''); // (NOT RECOMMENDED)
DOM.inputRange.addEventListener('input', (e) => {
console.log('value: ', e.target.value); // aktueller Wert
@@ -80,11 +81,37 @@
} else {
DOM.btnSend.disabled = false;
}
// DOM.btnSend.disabled = (!cbEl.checked) ? true : false
// DOM.btnSend.disabled = !cbEl.checked;
});
DOM.buttonCheckOn.addEventListener('click', (e) => {
e.preventDefault(); // => Standardverhalten unterbinden (Formulardaten versenden)
DOM.cbAgb.checked = true;
DOM.btnSend.disabled = false;
});
DOM.buttonCheckOff.addEventListener('click', (e) => {
e.preventDefault(); // => Standardverhalten unterbinden (Formulardaten versenden)
DOM.cbAgb.checked = false;
DOM.btnSend.disabled = true;
});
DOM.buttonCheckOnOff.addEventListener('click', (e) => {
e.preventDefault(); // => Standardverhalten unterbinden (Formulardaten versenden)
// DOM.cbAgb.checked = !DOM.cbAgb.checked; // => !false -> true | !true -> false
// DOM.btnSend.disabled = !DOM.btnSend.disabled;
if (DOM.cbAgb.checked) {
DOM.cbAgb.checked = false;
DOM.btnSend.disabled = true;
} else {
DOM.cbAgb.checked = true;
DOM.btnSend.disabled = false;
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,105 @@
'use strict';
(() => {
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// === DOM & VARS =======
const SMALL = 14;
const NORMAL = 16;
const BIG = 24;
const VERY_LARGE = 36;
const DOM = {
// btnVeryLarge: $('.button-very-large'),
// btnBig: $('.button-big'),
// btnNormal: $('.button-normal'),
// btnSmall: $('.button-small'),
// btnInc: $('.button-increase'),
// btnDec: $('.button-decrease'),
btns: $$('.button-controls button'),
text: $('p'),
};
// === INIT =============
const init = () => {
// einmalige Zuweisung der Schriftgröße aus Browser oder CSS-Definition
DOM.text.style.fontSize = window.getComputedStyle(DOM.text).fontSize;
console.log(window.getComputedStyle(DOM.text));
console.log(DOM);
// DOM.text.style.color = 'tomato';
// DOM.text.style.backgroundColor = '#222';
// DOM.text.style.fontSize = '48px';
DOM.btns.forEach((el) => {
el.addEventListener('click', onClickFontSize);
});
// DOM.btnVeryLarge.addEventListener('click', onClickVeryLarge);
// DOM.btnBig.addEventListener('click', onClickBig);
// DOM.btnNormal.addEventListener('click', onClickNormal);
// DOM.btnSmall.addEventListener('click', onClickSmall);
// DOM.btnInc.addEventListener('click', onClickInc);
// DOM.btnDec.addEventListener('click', onClickDec);
};
// === EVENTHANDLER =====
const onClickFontSize = (e) => {
const btn = e.currentTarget;
const label = btn.dataset.label; // btn.getAttribute('data-label')
const size = btn.dataset.size; // btn.getAttribute('data-size');
switch (label) {
case 'INCREASE':
setFontSizeTo(currentFontSize() + 5);
break;
case 'DECREASE':
setFontSizeTo(currentFontSize() - 5);
break;
default:
setFontSizeTo(size);
// setFontSizeTo(eval(label)); // eval is evil -> 'VERY_LARGE' -> eval('VERY_LARGE') -> VERY_LARGE <- die Konfigurationsvariable
}
};
// const onClickVeryLarge = (e) => {
// console.log('click');
// setFontSizeTo(VERY_LARGE);
// };
// const onClickBig = (e) => {
// console.log('click');
// setFontSizeTo(BIG);
// };
// const onClickNormal = (e) => {
// console.log('click');
// setFontSizeTo(NORMAL);
// };
// const onClickSmall = (e) => {
// console.log('click');
// setFontSizeTo(SMALL);
// };
// const onClickInc = (e) => {
// setFontSizeTo(currentFontSize() + 5);
// };
// const onClickDec = (e) => {
// setFontSizeTo(currentFontSize() - 5);
// };
// === XHR/FETCH ========
// === FUNCTIONS ========
const setFontSizeTo = (size) => {
DOM.text.style.fontSize = `${size}px`;
};
const currentFontSize = () => {
// return parseInt(window.getComputedStyle(DOM.text).fontSize); // => '16px' -> 16
return parseInt(DOM.text.style.fontSize);
};
init();
})();

View File

@@ -0,0 +1,58 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Style Font-Size (Beispiel)</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/main.js" defer></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" />
</head>
<body>
<main>
<div class="container py-5">
<h1>Style Font-Size (Beispiel)</h1>
<hr />
<nav class="button-controls mb-3">
<button class="btn btn-dark button-very-large" data-label="VERY_LARGE" data-size="36">Very Large</button>
<button class="btn btn-dark button-big" data-label="BIG" data-size="24">Big</button>
<button class="btn btn-dark button-normal" data-label="NORMAL" data-size="16">Normal</button>
<button class="btn btn-dark button-small" data-label="SMALL" data-size="14">Small</button>
<hr />
<button class="btn btn-dark button-decrease" data-label="DECREASE" aria-label="Decrease">
<i class="fas fa-minus"></i>
</button>
<button class="btn btn-dark button-increase" data-label="INCREASE" aria-label="Increase">
<i class="fas fa-plus"></i>
</button>
</nav>
<section class="section-content">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse eveniet, voluptatem sint enim culpa dicta
accusamus maiores consequuntur quisquam nisi, itaque voluptas, corrupti velit. Adipisci quo suscipit,
repellendus, necessitatibus modi dolore inventore incidunt, tenetur odit numquam dolorum saepe doloribus
voluptatum eaque in quisquam neque. Nemo animi facere ipsam earum ipsa tempore porro, exercitationem debitis
perspiciatis quisquam ut ea eum. Ea quia delectus odit labore atque nesciunt esse voluptatibus reiciendis
saepe nam provident aspernatur sapiente cumque, incidunt quasi neque dignissimos impedit amet sequi aut
minus optio aliquam officiis. Deserunt dolorem quod, in voluptas sunt, praesentium tenetur ullam dolore
doloremque repudiandae reiciendis veniam debitis eaque nobis quisquam ex quibusdam fugit. Ullam nemo tenetur
perferendis iusto neque fugit excepturi, dolorum ab totam maiores ut aspernatur? Cumque dicta dolore
mollitia, porro sit hic tenetur error voluptate facere iste nisi natus? Libero quaerat ullam explicabo modi
beatae eveniet, aliquid debitis facere enim id rem illum nobis sequi hic quasi. In qui et illo officiis,
animi doloremque ipsa harum, natus voluptate quod, voluptatum architecto doloribus asperiores cupiditate.
Tenetur fuga tempore voluptatum illo velit, sed nemo commodi. Unde perspiciatis aspernatur est iusto
quisquam, magni quibusdam accusantium illo laborum nesciunt laboriosam. Quam reiciendis et ipsum sequi dolor
minus aspernatur commodi repellat, aut vero expedita libero quod consequatur! Explicabo temporibus dolore
nihil labore fugit nisi velit veniam dignissimos aperiam id eaque blanditiis, expedita voluptas inventore.
Quisquam minus consequuntur ipsum eos, pariatur fuga minima eaque, temporibus illo placeat dignissimos
laborum maiores incidunt. Dignissimos delectus eum nostrum fuga hic cum aut nesciunt eveniet, cumque ut
beatae officiis et minus vero soluta accusamus corporis aliquam eligendi. Ad, qui ipsum. Distinctio
temporibus ea sequi dignissimos voluptatum quidem! Consequuntur, veniam odit exercitationem sint a
blanditiis voluptatibus quae doloribus adipisci cupiditate, dignissimos placeat asperiores, vel at enim
impedit id debitis! Provident asperiores reprehenderit sit nesciunt?
</p>
</section>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,45 @@
p {
font-size: 1.5em;
}
.keyword {
font-weight: bolder;
color: #225;
}
#tooltip {
width: 250px;
border: 2px solid #339;
padding: 1rem;
background-color: rgba(238, 238, 255, 0.9);
font-size: 1em;
text-align: justify;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
.show {
display: block !important;
animation-name: fadeIn;
animation-duration: 0.4s;
animation-fill-mode: both;
}
.hide {
display: none !important;
}
@keyframes fadeIn {
0% {
opacity: 0;
transform: translate3d(0, 20%, 0);
}
100% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}

View File

@@ -0,0 +1,57 @@
'use strict';
(() => {
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// === DOM & VARS =======
const DOM = {
keywords: $$('.keyword'),
tooltip: $('#tooltip'),
};
const MOUSE_OFFSET_Y = 20;
const MOUSE_OFFSET_X = 10;
// === INIT =============
const init = () => {
DOM.keywords.forEach((el) => {
el.addEventListener('mousemove', onMouseMoveKeyword);
el.addEventListener('mouseleave', onMouseLeaveKeyword);
});
};
// === EVENTHANDLER =====
const onMouseMoveKeyword = (e) => {
const keywordEl = e.currentTarget;
DOM.tooltip.style.top = `${e.clientY + MOUSE_OFFSET_Y}px`;
DOM.tooltip.style.left = `${e.clientX + MOUSE_OFFSET_X}px`;
showTooltip(keywordEl);
};
// === EVENTHANDLER =====
const onMouseLeaveKeyword = (e) => {
hideTooltip();
};
// === XHR/FETCH ========
// === FUNCTIONS ========
const showTooltip = (el) => {
const text = el.dataset.tooltip;
DOM.tooltip.textContent = text;
// DOM.tooltip.style.display = 'block';
DOM.tooltip.classList.add('show');
DOM.tooltip.classList.remove('hide');
};
const hideTooltip = () => {
// DOM.tooltip.style.display = 'none';
DOM.tooltip.classList.add('hide');
DOM.tooltip.classList.remove('show');
};
init();
})();

View File

@@ -0,0 +1,48 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Tooltips</title>
<link rel="stylesheet" href="assets/css/tooltips.css" />
<script src="assets/js/tooltips.js" defer></script>
</head>
<body>
<h1>Quantum Entanglement Mugs</h1>
<h3>DRINK IN SYNC.</h3>
<p>
In the realm of
<span
class="keyword"
data-tooltip="Quantum mechanics is the fundamental physical theory that describes the behavior of matter and of light; its unusual characteristics typically occur at and ..."
>quantum mechanics </span
>, particles can be
<span
class="keyword"
data-tooltip="Entangled may refer to: Entangled state, in physics, a state arising from quantum entanglement ·">
entangled
</span>
in such a way that the state of one instantly influences the state of another, no matter the distance. This
phenomenon fascinates physicists and challenges our understanding of reality. Imagine sipping your coffee from a
mug that celebrates this
<span
class="keyword"
data-tooltip="In physics, a quantum ( pl. : quanta) is the minimum amount of any physical entity (physical property) involved in an interaction.">
quantum
</span>
wonder. Just like entangled particles, you and a friend can share a connection over any distance with these mugs.
Introducing the Quantum <span class="keyword">Entanglement</span> Mugs.
</p>
<p>
Each set of Quantum <span class="keyword">Entanglement</span> Mugs includes two ceramic mugs designed to reflect
the concept of entanglement. Share one with a friend, and no matter how far apart you are, you'll feel connected.
Use them at your next physics meetup, and your colleagues will appreciate your thoughtful nod to quantum theory.
Enjoy your coffee!
</p>
<div id="tooltip" class="hide">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis voluptates, veniam facere laudantium.
</div>
</body>
</html>

View File

@@ -0,0 +1,55 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Auslesen von Breite, Höhe und Postion</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
.box {
width: 250px;
height: 100px;
padding: 1rem;
background-color: tomato;
border: 10px solid #222;
margin: 1rem;
}
</style>
</head>
<body>
<main>
<div class="container py-5">
<h1>Auslesen von Breite, Höhe und Postion</h1>
<div class="box"></div>
</div>
</main>
<script>
'use strict';
const box = document.querySelector('.box');
// reines JS (wenn Performance keine Rolle spielt)
console.log(getComputedStyle(box).width);
console.log(getComputedStyle(box).height);
console.log(getComputedStyle(box).top);
// jQuery
console.log($('.box').outerWidth()); // 250
console.log($('.box').outerHeight()); // 100
console.log($('.box').width()); // 198
console.log($('.box').height()); // 48
console.log($('.box').position()); // {top: 96, left: 92.5}
console.log(box.getBoundingClientRect()); // => DOMRect {x: 108.5, y: 112, width: 250, height: 100, top: 112, …}
console.log(box.getBoundingClientRect().width);
console.log(box.getBoundingClientRect().height);
console.log(box.getBoundingClientRect().top);
console.log(box.getBoundingClientRect().left);
console.log(box.offsetWidth); // 250
console.log(box.offsetHeight); // 100
</script>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Eigene Attribute mit data-[ATTRIBUT_NAME] - DOMStringMap</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5">
<h1>Eigene Attribute mit data-[ATTRIBUT_NAME] - DOMStringMap</h1>
<p>
<a href="https://developer.mozilla.org/de/docs/Web/API/DOMStringMap"> DOMStringMap </a>
- Die <code>DOMStringMap</code>-Schnittstelle wird für das HTMLElement.dataset-Attribut verwendet, um Daten
für benutzerdefinierte Attribute darzustellen, die zu Elementen hinzugefügt werden.
</p>
<hr />
<button
class="btn btn-dark button"
data-content="Text für headline"
data-ref="h1"
data-content-id="0"
data-my-attribut-with-many-words="yes">
Button mit eigenen Attributen
</button>
<p class="my-5">
Lorem ipsum dolor sit
<strong
class="keyword"
data-tooltip="The brain's outer layer of neural tissue in humans and other mammals [wikipedia]."
>cerebral cortex
</strong>
amet consectetur adipisicing elit. Harum voluptatem iure earum suscipit nihil! Recusandae pariatur corporis
odit optio excepturi labore dolore non, expedita temporibus adipisci vero, modi magnam veritatis?
</p>
<button class="btn btn-dark button-redirect">
Weiterleitung in <span class="timer-counter" data-timer="5"></span>
</button>
</div>
</main>
<script>
'use strict';
(() => {
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// === DOM & VARS =======
const DOM = {
button: $('.button'),
keywords: $$('.keyword'),
buttonRedirect: $('.button-redirect'),
};
console.log(DOM);
// === INIT =============
const init = () => {
DOM.button.dataset.newData = 'neues Data Attribut'; //=> <button data-new-data="neues Data Attribut"></button>
console.log(DOM.button.dataset); //=> DOMStringMap {content: 'Text für headline', ref: 'h1', contentId: '0', myAttributWithManyWords: 'yes', newData: 'neues Data Attribut'}
// (NOT RECOMMENDED)
console.log(DOM.button.getAttribute('data-new-data')); // neues Data Attribut
DOM.button.addEventListener('click', onClickButton);
DOM.keywords.forEach((el) => {
el.addEventListener('mouseenter', onMouseEnterKeyword);
});
};
// === EVENTHANDLER =====
const onClickButton = (e) => {
const btnEl = e.currentTarget;
const { ref: selector, content } = btnEl.dataset; // Destructuring von dataset
$(selector).textContent = content;
};
const onMouseEnterKeyword = (e) => {
const el = e.currentTarget;
console.log(el.dataset.tooltip);
};
// === XHR/FETCH ========
// === FUNCTIONS ========
init();
})();
</script>
</body>
</html>