|
|||
Inkonsistentes Verhalten der duch onResize-Funktion hinzugefügten Event-Handler
Hallo, ich hab bei meinem CSS-DropDown Menü über einen if-Block festgelegt, daß wenn es sich um ein Touch-Device handelt oder eine bestimmte Fenstergröße (Breite 900px) unterschritten wird , dem Menü Click-Event-Handler zum togglen von CSS-Klassen hinzugefügt werden.
Die aktuelle Fenstergröße wird dabei durch die Abfrage der CSS-Eigenschaft: 'Display: flex' ermittelt, welche von den Media Queries bei einer Breite < 900px gesetzt wird. Dies funktioniert gut bei onLoad. Sobald dies aber über die Resize-Funktion getriggert wird, funktionieren die Click-Events (bei einer Breite < 900 px) unzuverlässig. Dies kommt wohl dadurch, daß onResize das Dokument mit den togglenden Click-Event-Handlern befeuert wird, die in den ausgeführten Funktionen enthalten sind. Kann mir vielleicht jemand sagen, wie man diese aus der Resize-Funktion herausnehmen kann ohne die Funktionalität zu zerstören? https://codepen.io/nexusmaster/pen/MEzNdX jQuery Code:
// JavaScript Document $(document).ready(function () { // Anweisungen nach dem Ladeabschluss des DOM ausführen 'use strict'; //################################### MOBILE MENÜ EIN-/AUSBLENDEN ################################### // Funktion definieren zum Ausblenden der DropDown Menüs function resetDropDownMenu() { $('nav ul li ul').removeClass('display-flex'); // DropDown Menüs aller Ebenen ausblenden $('nav ul li i.exit-block').removeClass('exit-block'); // Exit-Icons aller Ebenen ausblenden $('nav ul li a').removeClass('touch-background-hl'); // Click Backgrounds aller Ebenen ausblenden } $('#mobile_menu_button').click(function () { $('#navigation').toggleClass('display-flex'); $(resetDropDownMenu); // Alle aktivierten Elemente des DropDown Menüs zurücksetzen }); //################################# MENÜ- UND QUITICON AUSTAUSCHEN ################################## var MENU_OPEN = false; $('.menu_icon').stop().click(function () { if (MENU_OPEN === false) { MENU_OPEN = true; $('.menu_icon').addClass('is-active'); // Animation Menü- zu Quiticon auslösen } else { MENU_OPEN = false; $('.menu_icon').removeClass('is-active'); // Animation Quit- zu Menüicon auslösen } }); //############################## DROPDOWN MOBILE MENÜ EIN-/AUSBLENDEN ############################### function isTouchDevice() { // Abfrage ob es sich um Touch-Device handelt return typeof window.ontouchstart !== 'undefined'; } $(window).resize(function () { function isSmallWindowDevice() { // Abfrage ob es sich um ein Device mit Anzeige des Mobile Menüs handelt return $('#mobile-menu-header').css('display') === 'flex'; // Abfrage ob Media Query für mobile Geräte aktiv ist } /*alert(isSmallWindowDevice());*/ if (isTouchDevice() || isSmallWindowDevice()) { // Anfang der Anweisungen für Touch- oder smallWindow-Devices // Ebene1 + 2 $('nav ul li a').click(function () { $(this).siblings('ul').toggleClass('display-flex'); // DropDown-Menü(ul), adressiert als Geschwister-Element des geclickten Links, aus- und einklappen $(this).children('i.exit-none').toggleClass('exit-block'); // Exit-Icon(i), adressiert als Kind-Element des geclickten Links, ein- und ausblenden }); // Ebene1 + 2 if ($('nav ul').css('display') !== 'flex') { // wenn Ebene ausgeblendet ist $('nav ul li a').click(function () { // hinzufügen des click events wichtig für (this) Lokalisation $(this).siblings('ul').find('li ul').removeClass('display-flex'); // Drop-Down Ebene2(ul), adressiert als Geschwister-Element des geclickten Links, ausblenden $(this).siblings('ul').find('li i.exit-block').removeClass('exit-block'); // Drop-Down Ebene1 Exit-Icon(i) ein- und ausblenden, adressiert als Geschwister-Element des geclickten Ebene1 Links $(this).siblings('ul').find('li a').removeClass('touch-background-hl touch-background-hl1 touch-background-h2'); // Drop-Down Ebene1 Background-Color zurücksetzen, adressiert über den vom Geschwister-Element des geclickten Ebene1 Links }); } //######################## MOBILE MENÜ LINKS BACKGROUND-COLOR TOGGLE ON CLICK ####################### // Alle Ebenen $('nav ul li a').click(function () { $(this).toggleClass('touch-background-hl'); // onClick Background-Color für alle Links austauschen }); //Alle Ebenen $('nav ul li').removeClass("no-touch"); // Hover Klasse für noTouch-Devices & Desktop Menü deaktivieren } // Ende der Anweisungen für Touch- oder smallWindow-Devices //######################### HOVER NUR FÜR NON-TOUCH_DEVICES AKTIVIETREN ######################### //Alle Ebenen else { $('nav ul li').addClass("no-touch"); // Hover Klasse für noTouch-Devices & Desktop Menü aktivieren $(resetDropDownMenu); // Alle durch click aktivierten Elemente des DropDown-Menüs zurücksetzen } // Ende der Anweisungen für noTouch-Devices und largeWindow-Devices }).resize(); }); |
Sponsored Links |
|
|||
Ohje, ich habe dir schon einmal in einem Thread gesagt dass deine Herangehensweise nicht gut ist und das hast du nicht gut aufgefasst. Weiterlesen also auf eigene Gefahr:
//Edit start Habe ich zuerst gar nicht bemerkt: Wenn du per onresize event-handler hinzufügst, dann fügst du diese auch so oft hinzu, wie du das fenster "resized". Füge ich bei einem .click also ein console.log hinzu, dann habe ich gleich 10 (oder mehr...) logs in der Konsole bei einem Klick. Je nachdem, wie oft der Browser die onresize Funktion aufruft. Du bindest den Klick nicht auf "nach der Resize" funktion sondern permanent. Also so lange der User das fenster kleiner schiebt. Schiebt er es von 900 auf 500 px, dann hast du dazwischen also 400 .resize() Funktionen. Abhängig davon, wie oft der browser das feuert, der hat ja auch Milisekunden dazwischen. //Edit end Die gesamte Herangehensweise ist nämlich auch hier nicht wirklich "gut". Erstens: Touch !== mobile. Es gibt auch desktop monitore die touch unterstützen. Oder zB surface geräte von Microsoft können sowohl per touch als auch per tastatur/Maus bedient werden. Auch ist die Abfrage auf css-displays nicht wirklich empfehlenswert, für das, was du willst, gibt es eigene JS-Abfragen: matchMedia, das ist im Prinzip das Selbe wie Mediaqueries im CSS, nur halt im JS. Habe ich selber auch erst vor kurzem kennen gelernt, ist ganz praktisch Nun meine eigentliche "Bemängelung": Wieso diese .resize function überhaupt? Kein user verändert die Größe seines Browsers während des surfens wirklich. Auch musst du keine Abfrage einbauen, auf welchem Gerät du bist. Mal schauen, ob ich das gut erklären kann: Du hast deine Navigation mit HTML-Aufbau so wie jetzt und blendest den mobile-button per mediaqueries ein und aus. Wenn jetzt jemand wirklich den Bildschirm kleiner schiebt (was 99,999% NICHT tun werden), dann wird die Navigation ein- und ausgeblendet für eben diese User. Schieben diese den browser wieder größer, dann sehen sie ja wieder das "normale" Menü, da diese toggle-klassen (dank mediaqueries) nur auf kleinen devices wirken. Generelle Infos, nicht spezifisch zu deinem Problem: Das Problem, welches solche Menüs immer haben, ist, dass die ersten dropdown-levels auch Links sind. Das heißt, auf "mobile" braucht es einen zusätzlichen toggle-button, welcher das Untermenü öffnet. Der fehlt bei dir auch, man kommt, soweit ich das sehe, im mobilen Bereich nicht auf den Link von zB "Rechtsgebiete". Geändert von cloned (03.11.2017 um 13:46 Uhr) |
Sponsored Links |
|
||||||
Zitat:
Du beschäftigst dich lieber mit Hintergründen, als mit der eigentlichen Frage. So auch heute wieder ... Zitat:
Zitat:
Touch Devices, smallWindow = click (kleines vertikales Menü) Touch Devices, bigWindow = click (großes horizontales Menü) Non-Touch devices, bigWindow = hover (großes horizontales Menü) Non-Touch Devices, smallWindow = click (hat keinen wirklichen Mehrwert, da hast du recht und soll nur vermeiden, daß auf großen Bildschirmen mit kleinem Browserfenster (on resize) sonst ein Mobile Menü* gezeigt wird, welches auf Grund der vertikalen ul-Verschachtelung mit hover völlig unbedienbar ist) *Der Ausdruck mobile Menü ist nur ein Arbeitstitel für mich und bezeichnet das kleine vertikale Menü, welches aber nicht ausschließlich auf mobile Devices zum Einsatz kommt. Das Surface würde damit je nach Ergebnis (window.ontouchstart) entweder ein großes Menü mit hover-events oder ein großes Menü mit click-events erhalten, welche beide jedoch mit Maus und Touch bedienbar sind. Zitat:
Zitat:
Zitat:
-------------------------------------------------------------------------- Hab es jetzt gelöst, indem ich die die if-Blöcke in die callback Funktion integriert habe, so daß die event-handler nur einmal geladen werden und die Resize-Funktion sich nur auf die Ermittlung der Fenstergröße bezieht. Geändert von nexus (05.11.2017 um 11:49 Uhr) |
|
|||
Mein Ton ist vielleicht direkt, dafür aber ehrlich. Persönlich bin ich auch froh, wenn man mir Sachen direkt und einfach erklärt, falls du dich beleidgt fühlst, tut mir das leid.
Zitat:
Du hast jetzt dein Problem ja lösen können, das ist doch gut Danke auch für die Erklärung deines Aufbaus, für mich persönlich wäre das viel zu kompliziert, aber hauptsache du bist mit dem Ergebnis zufrieden. Zitat:
Also hat man auf "mobile" keine Chance den Hauptmenüpunkt zu öffnen? |
Stichwörter |
event handler, jquery, onclick, resize, toggle |
Themen-Optionen | |
Ansicht | |
|
|
Ähnliche Themen | ||||
Thema | Autor | Forum | Antworten | Letzter Beitrag |
[PHP] Funktion zum Optimieren von CSS | Floele | Serveradministration und serverseitige Scripte | 2 | 13.08.2005 11:31 |