@profitlich/template-toolkit 2.18.7 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -8,18 +8,22 @@ export class MenuToggle {
|
|
|
8
8
|
#menuItemClass;
|
|
9
9
|
#scrollbarWidth;
|
|
10
10
|
#shiftElement;
|
|
11
|
+
#shiftDelay;
|
|
12
|
+
#deferPositionFixed;
|
|
11
13
|
#y;
|
|
12
14
|
#bodyClickHandler;
|
|
13
15
|
#resizeHandler;
|
|
14
16
|
#escapeHandler;
|
|
15
17
|
isActive;
|
|
16
18
|
|
|
17
|
-
constructor(menuButtonId, menuId, menuLinkClass, menuItemClass, shiftElementId) {
|
|
19
|
+
constructor(menuButtonId, menuId, menuLinkClass, menuItemClass, shiftElementId, shiftDelay = 0, deferPositionFixed = false) {
|
|
18
20
|
this.#menuButton = document.getElementById(menuButtonId);
|
|
19
21
|
this.#menu = document.getElementById(menuId);
|
|
20
22
|
this.#menuLinkClass = menuLinkClass;
|
|
21
23
|
this.#menuItemClass = menuItemClass;
|
|
22
24
|
this.#shiftElement = shiftElementId ? document.getElementById(shiftElementId) : null;
|
|
25
|
+
this.#shiftDelay = shiftDelay * 1000;
|
|
26
|
+
this.#deferPositionFixed = deferPositionFixed;
|
|
23
27
|
this.#scrollbarWidth = 0;
|
|
24
28
|
this.isActive = false;
|
|
25
29
|
this.#y = 0;
|
|
@@ -39,14 +43,18 @@ export class MenuToggle {
|
|
|
39
43
|
this.#toggleMenu();
|
|
40
44
|
}
|
|
41
45
|
});
|
|
46
|
+
|
|
47
|
+
this.#setBodyAttribute('data-menu-active', 'false');
|
|
48
|
+
this.#setBodyAttribute('data-menu-moving', 'false');
|
|
49
|
+
this.#setBodyAttribute('data-menu-fixed', 'false');
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
static getInstance(menuButtonId, menuId, menuLinkClass, menuItemClass, shiftElementId) {
|
|
52
|
+
static getInstance(menuButtonId, menuId, menuLinkClass, menuItemClass, shiftElementId, shiftDelay, deferPositionFixed) {
|
|
45
53
|
if (!MenuToggle.#instance) {
|
|
46
54
|
if (!menuButtonId || !menuId || !menuLinkClass || !menuItemClass) {
|
|
47
55
|
throw new Error("MenuToggle muss beim ersten Aufruf mit menuButtonId, menuId, menuLinkClass und menuItemClass initialisiert werden.");
|
|
48
56
|
}
|
|
49
|
-
MenuToggle.#instance = new MenuToggle(menuButtonId, menuId, menuLinkClass, menuItemClass, shiftElementId);
|
|
57
|
+
MenuToggle.#instance = new MenuToggle(menuButtonId, menuId, menuLinkClass, menuItemClass, shiftElementId, shiftDelay, deferPositionFixed);
|
|
50
58
|
}
|
|
51
59
|
return MenuToggle.#instance;
|
|
52
60
|
}
|
|
@@ -57,6 +65,7 @@ export class MenuToggle {
|
|
|
57
65
|
document.body.removeEventListener('click', this.#bodyClickHandler);
|
|
58
66
|
window.removeEventListener('resize', this.#resizeHandler);
|
|
59
67
|
this.#setBodyAttribute('data-menu-active', 'false');
|
|
68
|
+
this.#setBodyAttribute('data-menu-fixed', 'false');
|
|
60
69
|
if (this.#shiftElement) {
|
|
61
70
|
this.#shiftElement.style.marginRight = '';
|
|
62
71
|
this.#shiftElement.style.width = '';
|
|
@@ -69,16 +78,26 @@ export class MenuToggle {
|
|
|
69
78
|
this.isActive = true;
|
|
70
79
|
document.body.addEventListener('click', this.#bodyClickHandler);
|
|
71
80
|
window.addEventListener('resize', this.#resizeHandler);
|
|
72
|
-
this.#scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
73
|
-
this.#y = window.scrollY;
|
|
74
81
|
this.#setBodyAttribute('data-menu-active', 'true');
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const marginOriginal = parseFloat(window.getComputedStyle(this.#menuButton).marginRight);
|
|
79
|
-
this.#shiftElement.style.marginRight = `${marginOriginal + this.#scrollbarWidth}px`;
|
|
80
|
-
this.#adjustShiftElementWidth();
|
|
82
|
+
this.#setBodyAttribute('data-menu-moving', 'true');
|
|
83
|
+
if (!this.#deferPositionFixed) {
|
|
84
|
+
this.#setBodyAttribute('data-menu-fixed', 'true');
|
|
81
85
|
}
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
this.#scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
88
|
+
this.#y = window.scrollY;
|
|
89
|
+
document.body.style.paddingRight = `${this.#scrollbarWidth}px`;
|
|
90
|
+
document.body.style.top = `-${this.#y}px`;
|
|
91
|
+
if (this.#deferPositionFixed) {
|
|
92
|
+
this.#setBodyAttribute('data-menu-fixed', 'true');
|
|
93
|
+
}
|
|
94
|
+
if (this.#shiftElement) {
|
|
95
|
+
const marginOriginal = parseFloat(window.getComputedStyle(this.#menuButton).marginRight);
|
|
96
|
+
this.#shiftElement.style.marginRight = `${marginOriginal + this.#scrollbarWidth}px`;
|
|
97
|
+
this.#adjustShiftElementWidth();
|
|
98
|
+
}
|
|
99
|
+
this.#setBodyAttribute('data-menu-moving', 'false');
|
|
100
|
+
}, this.#shiftDelay);
|
|
82
101
|
this.#toggleEscape(true);
|
|
83
102
|
}
|
|
84
103
|
const event = new CustomEvent('eventMenuestatus', {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
body {
|
|
2
2
|
|
|
3
|
-
&[data-menu-
|
|
3
|
+
&[data-menu-fixed="true"] {
|
|
4
4
|
position: fixed;
|
|
5
5
|
width: 100%;
|
|
6
|
+
}
|
|
6
7
|
|
|
8
|
+
&[data-menu-active="true"] {
|
|
7
9
|
// Bedeckt das Menü nur einen Teil der Seite, ist also ein Teil der Seite weiterhin zu sehen,
|
|
8
10
|
// soll die Maus Interaktionen ausserhalb des Menüs ignorieren
|
|
9
11
|
.main {
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import '@mux/mux-player';
|
|
2
2
|
import './mux-player.scss';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Lädt Mux-Videos lazy und steuert Autoplay per IntersectionObserver.
|
|
6
|
+
*
|
|
7
|
+
* Ladereihenfolge:
|
|
8
|
+
* 1. observeLazyElements() beobachtet alle .mux-player-Container.
|
|
9
|
+
* 2. Betritt ein Container den Viewport, ersetzt #handleLazyLoad ihn durch
|
|
10
|
+
* ein <mux-player>-Element und ruft handleVisibilityChange auf.
|
|
11
|
+
* 3. handleVisibilityChange → #setup für alle sichtbaren Videos:
|
|
12
|
+
* - Autoplay: muted, Controls versteckt, #playPauseObserver startet
|
|
13
|
+
* - Kein Autoplay: keine Änderungen, User steuert Wiedergabe selbst
|
|
14
|
+
* - display:none beim Laden: Setup wird übersprungen; Projekt ruft
|
|
15
|
+
* handleVisibilityChange erneut auf, sobald das Video sichtbar wird.
|
|
16
|
+
* 4. onPlayerCreated (optional): wird für alle Player aufgerufen, unabhängig
|
|
17
|
+
* von Autoplay und nach dem internen Setup.
|
|
18
|
+
*
|
|
19
|
+
* Pausierlogik:
|
|
20
|
+
* - Viewport verlassen → #handlePlayPause via IntersectionObserver (nur Autoplay)
|
|
21
|
+
* - display:none gesetzt → handleVisibilityChange (manuell vom Projekt aufzurufen)
|
|
22
|
+
*/
|
|
4
23
|
export class MuxPlayer {
|
|
5
24
|
#lazyLoadObserver;
|
|
6
25
|
#playPauseObserver;
|
|
@@ -36,16 +55,19 @@ export class MuxPlayer {
|
|
|
36
55
|
// Flag setzen, um zukünftige Ausführungen zu verhindern.
|
|
37
56
|
player.dataset.isSetup = 'true';
|
|
38
57
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.#playPauseObserver.observe(player);
|
|
42
|
-
} else {
|
|
43
|
-
player.addEventListener('loadeddata', () => {
|
|
58
|
+
if (autoplay) {
|
|
59
|
+
if (player.readyState >= 2) { // HAVE_CURRENT_DATA oder höher
|
|
44
60
|
this.#playPauseObserver.observe(player);
|
|
45
|
-
}
|
|
61
|
+
} else {
|
|
62
|
+
player.addEventListener('loadeddata', () => {
|
|
63
|
+
this.#playPauseObserver.observe(player);
|
|
64
|
+
}, { once: true });
|
|
65
|
+
}
|
|
46
66
|
}
|
|
47
67
|
}
|
|
48
68
|
|
|
69
|
+
// Für Videos, die ein-/ausgeblendet werden
|
|
70
|
+
// zum Beispiel Startseite Angebote
|
|
49
71
|
handleVisibilityChange(player) {
|
|
50
72
|
const isVisible = window.getComputedStyle(player).display !== 'none';
|
|
51
73
|
|
|
@@ -100,13 +122,16 @@ export class MuxPlayer {
|
|
|
100
122
|
|
|
101
123
|
if (autoplay) {
|
|
102
124
|
player.setAttribute('data-autoplay', 'true');
|
|
125
|
+
} else {
|
|
126
|
+
player.setAttribute('data-autoplay', 'false');
|
|
103
127
|
}
|
|
104
128
|
|
|
105
|
-
const
|
|
129
|
+
const setStatus = value => player.setAttribute('data-status', value);
|
|
106
130
|
|
|
107
|
-
player.addEventListener('
|
|
108
|
-
player.addEventListener('
|
|
109
|
-
player.addEventListener('
|
|
131
|
+
player.addEventListener('loadstart', () => setStatus('loadstart'));
|
|
132
|
+
player.addEventListener('playing', () => setStatus('playing'));
|
|
133
|
+
player.addEventListener('pause', () => setStatus('pause'));
|
|
134
|
+
player.addEventListener('ended', () => setStatus('ended'));
|
|
110
135
|
|
|
111
136
|
console.log(
|
|
112
137
|
'Toolkit Video',
|
|
@@ -116,17 +141,17 @@ export class MuxPlayer {
|
|
|
116
141
|
);
|
|
117
142
|
|
|
118
143
|
container.replaceWith(player);
|
|
119
|
-
|
|
144
|
+
setStatus('false');
|
|
120
145
|
|
|
146
|
+
this.handleVisibilityChange(player);
|
|
121
147
|
if (this.#onPlayerCreated) {
|
|
122
148
|
this.#onPlayerCreated(player, container);
|
|
123
|
-
} else if (autoplay) {
|
|
124
|
-
this.handleVisibilityChange(player);
|
|
125
149
|
}
|
|
126
150
|
}
|
|
127
151
|
}
|
|
128
152
|
}
|
|
129
153
|
|
|
154
|
+
// Für autoplay Videos: play und pause
|
|
130
155
|
#handlePlayPause(entries) {
|
|
131
156
|
for (const entry of entries) {
|
|
132
157
|
const player = entry.target;
|
package/package.json
CHANGED