• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] JONSUH's Hamburger Menü: hover statt click

So, da bin ich wieder :) Hab selber noch ein wenig daran gewerkelt. Zunächst mal Euch allen ganz herzlichen Dank für die super Unterstützung!!! Ich weiß das sehr zu schätzen, weil leider nicht viele in Foren so hilfsbereit sind. Oft wird einfach ein Link zu Seiten wie w3schools gepostet oder eine "fachliche Erklärung" à la Sheldon Cooper, was nicht wirklich weiterhilft. Aber wenn man wirklich Lösungshilfe bei einem Projekt erhält kann der Lösungsweg analysiert und für ähnliche Probleme adaptiert werden. Ich denke so lernt man am besten.... zumindest ist das bei mir so! :)

So wieder zurück zum Thema:
Also habe dem Icon noch eine kleine Hover-Funktion gespendet und ein off-canvas Menü hinzugefügt. Schaut Euch das bitte mal an, es ist auf meiner Dropbox. Der Farbunterschied und der rote Rahmen sind jetzt nur zum Testen da und sollen in der finalen Version natürlich nicht mehr sichtbar sein. Problem ist da jetzt, dass sich durch das Menü irgendwie die Gesamthöhe von <html> verändert hat. Ich konnte aber nicht finden woher das kommt. Vielleicht kann man hier und da noch etwas anderes optimieren/besser machen? Naja, ich denke mit Sicherheit.... - freue mich auch über jede Kritik!

Auch habe ich jetzt einige css-Stile im HTML-Header geschrieben, was später natürlich auch in die entsprechenden css-Dateien ausgelagert werden muss. Also über diesen derzeitigen "Fehler" bin ich mir schon bewusst. Ist ja noch in der Entwicklung.... :icon6:

Achso noch eine andere Funktion, die ich nicht geschafft zu implementieren: Ich möchte zusätzlich zum Öffnen per Klick auf das Icon, das Menü auch öffnen wenn die Maus zum linken Bildrand bewegt wird. Hierfür hab ich bei Stackoverflow folgendes Skript gefunden, aber es hat mit meiner Funktion nichts gemacht bzw. habe ich meine Funktion wahrscheinlich nicht ganz korrekt eingefügt.
PHP:
$("body").on("mousemove",function(event) {
    if (event.pageX < 10) {
        // do something
    }
});
Any suggestion? :confused:
 
Vielleicht kann man hier und da noch etwas anderes optimieren/besser machen?
Das Problem kommt von deinem transform: translate3d(0,500px,0);, da die Elemente dadurch stark nach unten geschoben werden. Um das zu beheben braucht dein .menu ein overflow: hidden;

habe ich meine Funktion wahrscheinlich nicht ganz korrekt eingefügt.
Dieser Codefetzen scheint jQuery zu benutzen. Das hast du bei dir aber nicht eingebunden (die Fehlerkonsole hätte dich indirekt darauf hingewiesen) - brauchst du aber auch gar nicht:
Code:
document.body.addEventListener("mousemove",function(event) {
    if (event.pageX < 10) {
        document.body.classList.add("show-menu");
    }
});
 
Danke sehr! :D

die Fehlerkonsole hätte dich indirekt darauf hingewiesen
Die Fehlerkonsole hatte ich mir sogar auch angeschaut, bin davon aber ehrlich gesagt nicht wirklich schlau geworden. Muss mir das demnächst auch noch im Detail anschauen was darin alles steht.

Dieser Codefetzen scheint jQuery zu benutzen. Das hast du bei dir aber nicht eingebunden - brauchst du aber auch gar nicht:
HELL YEAH! Wow, jetzt steht auch diese Funktion!! ;) ;) Ganz langsam nimmt das Ganze Gestalt an :)

Ich habe noch einen #main-wrapper hinzugefügt, damit bei Klick darauf das Menü wieder eingezogen wird. Das X oben rechts vom Menü funktioniert irgendwie nur sehr unzuverlässig und merkwürdig. Wenn das Menü durch das "mousemove" eingeblendet wird, dann schließt das X nur wenn zwei mal darauf geklickt wird. Wenn aber das Menü mit Klick auf den Pfeil geöffnet wird, dann schließt es das X auch durch einen Einmal-Klick. Ganz komisch! Naja jetzt durch den #menu-wrapper wird das X zwar nicht mehr wirklich benötigt und ich werde es wahrscheinlich rausnehmen.... aber kann man trotzdem herausfinden woran dieses komische Verhalten liegt?

Das Problem kommt von deinem transform: translate3d(0,500px,0);, da die Elemente dadurch stark nach unten geschoben werden. Um das zu beheben braucht dein .menu ein overflow: hidden;
Thanks again! Habe das auch eingefügt, aber da ist immer noch ein kleiner overflow unten. Wenn das durch das transform kommt.... kann man das anders/besser lösen?


Ach so, noch was: Da sind ja jetzt schon enige Javascript-Funktionen unten im HTML. Ist das so ok? Soll ich das später so lassen oder wäre es besser diese auch in eine separate JS-Datei auszulagern und dieses dann oben oder unten im HTML einzubinden? Soweit ich weiß, werden die Funktionen schneller ausgeführt wenn sie unten eingebunden werden, ist das soweit korrekt??
 
aber kann man trotzdem herausfinden woran dieses komische Verhalten liegt?
Ja, kann man. Das liegt daran, dass die Variable isOpen dann den falschen Wert hat. Ich würde mich ja in der Funktion toggleMenu nicht auf eine Variable verlassen, sondern da direkt classie.toggle verwenden:
Code:
	function toggleMenu() {
		classie.toggle( bodyEl, 'show-menu' );
	}

aber da ist immer noch ein kleiner overflow unten.
Das liegt daran, dass .menu-wrap ein padding-top und height: 100% hat. Normalerweise zählt das Padding nicht zur Höhe dazu und damit hast du mehr als 100% dargestellte Höhe. Um das zu beheben kannst du z.B. box-sizing: border-box; verwenden.
Ist das so ok? Soll ich das später so lassen oder wäre es besser diese auch in eine separate JS-Datei auszulagern und dieses dann oben oder unten im HTML einzubinden? Soweit ich weiß, werden die Funktionen schneller ausgeführt wenn sie unten eingebunden werden, ist das soweit korrekt?
Ich würde JS möglichst in JS-Dateien packen und diese dann direkt vor dem </body> einbinden. Hat den Vorteil, dass man direkt auf dem DOM arbeiten kann und nicht auf irgendwelche Events warten muss.
 
Yep, hab die Änderungen eingebunden. Funktioniert immer besser - you're great!! ;) ;) ;)

Ich würde JS möglichst in JS-Dateien packen und diese dann direkt vor dem </body> einbinden. Hat den Vorteil, dass man direkt auf dem DOM arbeiten kann und nicht auf irgendwelche Events warten muss.
Was genau meinst Du mit "direkt auf dem DOM arbeiten"? Auch wenn man die Skripte auslagert hat man doch immer noch EventListener, oder nicht?!? Zumindest in meinem main.js habe ich diese EventListener auch. Oder verstehe Dich jetzt hierbei falsch?

Habe die Menüleiste noch ein wenig bearbeitet, schau Dir das bei Gelegenheit mal bitte an auf der Dropbox :)

Irgendwie ist da aber ein unterer Teil bei der Klasse .menu, wobei ich nicht verstehe woher das kommt.
border.png

Ganz unten in der Menüleiste soll ein Footer hin mit Link zum Impressum. Aber durch dieses komische Extrateil kann ich das Ganze nicht ganz richtig positionieren.

Edit:
Ach ja, noch was: Die Funktion, dass das Menü nur eingeblendet wird wenn die Maus am linken Rand ist würde ich gerne nur dann auslösen wenn das Fenster im Fullscreen ausgelöst wird und die Maus kurze Zeit am Rand verbleibt. Um das Fenster auf Fullscreen zu checken, kenne ich folgende Variante: if (window.fullscreen) {//do this}. Nur wo müsste ich das einfügen? Habe probiert die Funktion in die {} an Stelle von //do this einzufügen, aber das hat nichts gebracht. Und dadurch wurde auch irgendwie das Ausblenden durch Klick auf #main-wrapper wieder deaktiviert....
 
Zuletzt bearbeitet:
hat man doch immer noch EventListener, oder nicht?
Natürlich hat man noch EventListener, aber man muss dann nicht auf onload bzw. DOMReady warten.

Irgendwie ist da aber ein unterer Teil bei der Klasse .menu, wobei ich nicht verstehe woher das kommt.
das .icon-list braucht ein height: 100%, wenn du willst, dass es ganz nach unten geht. Du hast da 95%.

wenn das Fenster im Fullscreen ausgelöst wird
Was ist denn für dich genau "Fullscreen"? Wenn das Browserfenster den kompletten Bildschirm ausfüllt oder wenn du F11 drückst?
 
Sooo hello again!

Die letzte Woche konnte ich leider gar nicht an der Seite weiterarbeiten, war auch ziemlich krank. Aber jetzt geht's wieder weiter :)

Also fangen wir mal an mit den Antworten:

das .icon-list braucht ein height: 100%, wenn du willst, dass es ganz nach unten geht. Du hast da 95%.
Ja richtig, wenn ich das da auf 100% statt 95% setze, dann geht das bis ganz unten. Aber damit wäre das Problem an sich nicht gelöst, sondern nur aus dem Blickfeld geschoben. Guck Dir bitte mal den Screenshot an, da sieht man genau bis wohin die 95% gehen.... aber woher dieser untere Teil her kommt, das ist mir immer noch ein absolutes Rätsel.

Was ist denn für dich genau "Fullscreen"? Wenn das Browserfenster den kompletten Bildschirm ausfüllt oder wenn du F11 drückst?
Fullscreen wäre in dem Fall für mich wenn das Browswerfenster den kompletten Bildschirm ausfüllt und nicht bei F11. Das heißt also wenn das Browserfenster nicht komplett vergrößert ist, soll das OffCanvas-Menü auf den Cursor am Rand nicht reagieren.

Nochmals vielen Dank, dass Du Dich mit so viel Zeitaufwand meinem Problem widmest!!
 

Anhänge

  • error.gif
    error.gif
    69,2 KB · Aufrufe: 6
Zuletzt bearbeitet:
aber woher dieser untere Teil her kommt, das ist mir immer noch ein absolutes Rätsel.
Mir ist jetzt nicht ganz klar, was du genau meinst...
Fullscreen wäre in dem Fall für mich wenn das Browswerfenster den kompletten Bildschirm ausfüllt und nicht bei F11. Das heißt also wenn das Browserfenster nicht komplett vergrößert ist, soll das OffCanvas-Menü auf den Cursor am Rand nicht reagieren.
Dann wird dir die fullscreen-API nicht helfen. Als einzigen Weg sehe ich jetzt, dass du screen.width mit window.innerWidth vergleichst... aber stabil ist das auch nicht wirklich.
 
Mir ist jetzt nicht ganz klar, was du genau meinst...
Schau Dir bitte mal die beiden Screenshots unten an. Ich probiere die ganze Zeit rum, aber komm da irgendwie nicht hinter..... :confused::confused:


Dann wird dir die fullscreen-API nicht helfen. Als einzigen Weg sehe ich jetzt, dass du screen.width mit window.innerWidth vergleichst... aber stabil ist das auch nicht wirklich.
Die fullscreen-API erkennt also nur das F11-Fullscreen? Hmmm.... warum ist denn der Vergleich nicht wirklich stabil? Wie sieht es aus bei Dual-Monitor-Betrieb? Screen-Width müsste dann doch trotzdem die Weite vom aktuellen Monitor ausgeben wo das Fenster sich gerade befindet, richtig?!? Die Höhe des Browswers ist mir nicht wichtig, es geht nur darum, dass die Weite den gesamten Bildschirm ausfüllt. Wäre der folgende Code dann so korrekt?

Code:
  if(screen.width === window.innerWidth){
   // do this...
  }

- - - Aktualisiert - - -

ein neues Update ist hochgeladen. Guck mal bitte. Was hälst Du davon bis jetzt? :):)

Der obige Fehler besteht leider immer noch. Ziel ist dann später den Inhalt von #content-title und #content mit klick auf den jeweiligen Menüpunkt bzw. Sprachen dynamisch zu ändern. Hierzu habe ich auch einen neuen Thread im Ajax-Forum gestartet.

- - - Aktualisiert - - -

Auch wenn ich am oberen Problem noch immer sehr ratlos bin, mache ich mal weiter... also jetzt noch ein Update :)

Jetzt hab ich ein temporäres Hintergrundbild und einen Platzhalter-Inhalt drin. Sooo aaaaaber wenn man auf einen Menüpunkt klickt und der content-wrap angezeigt wird.... erstmal alles gut. Inhalt wird angezeigt und Menü bleibt auch offen. Ich hab ja eine Funktion drin, die das Menü wieder einfährt, sobald auf #main-wrap geklickt wird. Die reagiert aber auch wenn irgendwo im content geklickt wird. Hier würde ich gerne eine Ausnahme einfügen, die das Einfahren verhindert wenn auf das graue X oben beim content geklickt wird. Kann man das irgendwie so verbinden:

Code:
wenn (click auf #main-wrap && !click auf #contentclose) {mache das}

Ist der Ansatz so richtig?
 

Anhänge

  • error.gif
    error.gif
    69,2 KB · Aufrufe: 5
  • error.png
    error.png
    61,7 KB · Aufrufe: 6
Zuletzt bearbeitet:
Schau Dir bitte mal die beiden Screenshots unten an.
Dazu hab' ich doch schon geschrieben:
das .icon-list braucht ein height: 100%, wenn du willst, dass es ganz nach unten geht. Du hast da 95%.
.menu darf ja 95% haben aber nicht .icon-list.
Ist der Ansatz so richtig?
Naja - ich würde das eher über separater Eventlistener machen. Also auf dem Element, bei dem nicht geschlossen werden soll, einen Eventhandler registrieren, der per EVENT.stopPropagation() verhindert, dass das Event zu dem tieferen Eventlistener kommt.
 
.menu darf ja 95% haben aber nicht .icon-list.
Aaaah! Yes, you're the best! Geht jetzt wie es soll. Hab das jetzt noch nicht hochgeladen auf die Dropbox, aber sie top aus jetzt. So versteh ich jetzt auch wo dieser komische Rest unten her kam..... :):D:)


Naja - ich würde das eher über separater Eventlistener machen. Also auf dem Element, bei dem nicht geschlossen werden soll, einen Eventhandler registrieren, der per EVENT.stopPropagation() verhindert, dass das Event zu dem tieferen Eventlistener kommt.
Hierzu hab ich gestern und heute eine Menge gegoogelt, Beispiele angeschaut und ausprobiert, aber das klappt nicht so wie es soll.

Zum Beispiel so im contentclose-event
PHP:
var contentclose = document.getElementById('contentclose');
contentclose.onclick = function() {
     var content = document.getElementById('content-wrap');
     content.style.display = 'none';
     event.stopPropagation();
};
oder so
PHP:
document.getElementById('contentclose').click(function() { 
     event.stopPropagation(); 
}

So wie ich das verstanden hatte, hätte die erste Version funktionieren müssen. Korrigier mich bitte wenn ich es falsch verstanden habe. Das event.stopPropagation() soll doch verhindern, dass ein event, hier ein Klick, an die untergeordneten Elemente weitergereicht werden.

Im ersten Beispiel müsste nach meiner Logik die für das Objekt bestimmte Funktion bei Klick funktionieren, der Klick aber nicht die unteren Objekte triggern. Bei dem Beispiel hat das aber gar keine Auswirkung. Und wenn ich es so mache wir in meinem zweiten Beispiel, dann funktioniert das Öffnen am linken Rand nicht mehr und auch das Anzeigen des Content bei Klick auf 'Hello' funktioniert nicht mehr.

Wo ist denn da mein Fehler?
 
OK, hab es jetzt doch noch zum Laufen gebracht. Mein erster Versuch war eigentlich richtig, nur hat das 'event' in der Klammer gefehlt. Da lernt man doch immer wieder was dazu... :):icon7:

Jetzt sieht es so aus und es funktioniert:
PHP:
var contentclose = document.getElementById('contentclose');
contentclose.onclick = function(event) {
    var content = document.getElementById('content-wrap');
    content.style.display = 'none';
    event.stopPropagation();
};
 
Zurück
Oben