zurück zur Startseite
  


Zurück XHTMLforum > Webentwicklung (außer XHTML und CSS) > Javascript & Ajax
Seite neu laden Inkonsistentes Verhalten der duch onResize-Funktion hinzugefügten Event-Handler

Antwort
 
LinkBack Themen-Optionen Ansicht
  #1 (permalink)  
Alt 03.11.2017, 11:41
Neuer Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 19.10.2017
Beiträge: 4
nexus befindet sich auf einem aufstrebenden Ast
Standard 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();



});
Mit Zitat antworten
Sponsored Links
  #2 (permalink)  
Alt 03.11.2017, 13:42
Erfahrener Benutzer
XHTMLforum-Kenner
 
Registriert seit: 30.01.2014
Beiträge: 1.671
cloned ist ein sehr geschätzer Menschcloned ist ein sehr geschätzer Menschcloned ist ein sehr geschätzer Mensch
Standard

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)
Mit Zitat antworten
Sponsored Links
  #3 (permalink)  
Alt 03.11.2017, 20:22
Neuer Benutzer
neuer user
Thread-Ersteller
 
Registriert seit: 19.10.2017
Beiträge: 4
nexus befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von cloned Beitrag anzeigen
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:
Gegen Kritik habe ich nichts, aber dein Ton gefällt mir nicht.
Du beschäftigst dich lieber mit Hintergründen, als mit der eigentlichen Frage.
So auch heute wieder ...

Zitat:
Zitat von cloned Beitrag anzeigen
//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
Richtig, so habe ich es ja mit "Dies kommt wohl dadurch, daß onResize das Dokument mit den togglenden Click-Event-Handlern befeuert wird, die in den ausgeführten Funktionen enthalten sind." beschrieben.

Zitat:
Zitat von cloned Beitrag anzeigen
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.
Die Logik dahinter ist folgende:
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 von cloned Beitrag anzeigen
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
Hab ich so gemacht, weil ich gelesen habe, daß eine Abfrage der Fenster-Dimensionen unter JS ggf. mehr Fehlerquellen enthält als bei den Media Queries (zB. bzgl der Berücksichtigung von Scrollbalken je nach Browser) und es den Anpassungsbedarf im JS Code reduziert.

Zitat:
Zitat von cloned Beitrag anzeigen
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.
s.o.

Zitat:
Zitat von cloned Beitrag anzeigen
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".
Richtig. Die Buttons mit den chevron-icons sollen nur die Unternemüs öffnen.

--------------------------------------------------------------------------
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)
Mit Zitat antworten
  #4 (permalink)  
Alt 06.11.2017, 09:29
Erfahrener Benutzer
XHTMLforum-Kenner
 
Registriert seit: 30.01.2014
Beiträge: 1.671
cloned ist ein sehr geschätzer Menschcloned ist ein sehr geschätzer Menschcloned ist ein sehr geschätzer Mensch
Standard

Zitat:
Zitat von nexus Beitrag anzeigen
Gegen Kritik habe ich nichts, aber dein Ton gefällt mir nicht.
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:
Zitat von nexus Beitrag anzeigen
Du beschäftigst dich lieber mit Hintergründen, als mit der eigentlichen Frage.
So auch heute wieder ...
Das hat den Grund, weil ich auch die Hintergründe beachte und schlechte Lösungswege aufzeige. Dass es nicht jedem gefällt ist mir klar und diejenigen dürfen dann auch gerne meine Beiträge ignorieren.
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:
Zitat von nexus Beitrag anzeigen
Hab ich so gemacht, weil ich gelesen habe, daß eine Abfrage der Fenster-Dimensionen unter JS ggf. mehr Fehlerquellen enthält als bei den Media Queries (zB. bzgl der Berücksichtigung von Scrollbalken je nach Browser) und es den Anpassungsbedarf im JS Code reduziert.
Das würde mich interessieren, wo steht das denn?


Zitat:
Zitat von nexus Beitrag anzeigen
Richtig. Die Buttons mit den chevron-icons sollen nur die Unternemüs öffnen.
Also hat man auf "mobile" keine Chance den Hauptmenüpunkt zu öffnen?
Mit Zitat antworten
Antwort

Stichwörter
event handler, jquery, onclick, resize, toggle

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus


Ä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


Alle Zeitangaben in WEZ +2. Es ist jetzt 03:04 Uhr.