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

[FRAGE] Problem mit removeEventListener und Chrome lässt Noti bei Reload hängen

mikdoe

Moderator
Komme hier an einer Baustelle nicht weiter. Ich möchte mit folgendem Code erreichen, dass sich Firefox und Chrome bezüglich Webnotification gleich verhalten. Also beide schließen alle paar Sekunden die Noti und beide schließen sie auch, wenn man die aktuelle Seite verlässt. Dafür nehme ich bewusst in Kauf, dass der Benutzer die Noti nicht schliessen kann. Macht nichts, er kann sie weiterhin anklicken.

Das ständige neu öffnen klappt super, damit wäre der Chrome schon dem Firefox angepasst. Aber das mit dem Seitenwechsel habe ich noch nicht im Griff, es scheint mir als würde removeEventListener nicht richtig arbeiten. In beiden Browsern beibt die Webnoti offen, wenn man die Seite verlässt, sie soll sich aber schliessen. Am onbeforeunload scheint es nicht zu liegen, die Debug Ausgabe im localStorage wird nämlich korrekt erzeugt. Oder feuert das noti.close() dort nicht?
Weiß jemand, woran das liegt oder hat Lust, mit mir zusammen die Ursache zu suchen? Ich weiß nicht mehr so recht weiter.

Noch zur Info: Weil die Fehlerkonsole sich beim Seitenwechsel leert schreibe ich Debug Ausgaben ins localStorage. Das kann man im Chrome in der F12 Konsole im Reiter "Resources" anzeigen. Beim Firefox gibt es dafür ein Addon für Firebug namens "Firestorage Plus".
HTML:
<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Language" content="de">
<meta name="google" content="notranslate">
<title>Test HTML 5 Notification</title>
<style type="text/css">
body {
	font-family:	Arial;
	font-size:		12px;
}
</style>
<script>
function webnotification(act,title,options,click,clo,btn) {
	"use strict";
	if (act == 'check') {
		if (window.webkitNotifications || "Notification" in window) { return true; }
		else { return false; }
	}
	else if (act == 'send') {
		var sendNotification;
		var defaultaction = function(title,options,click,clo) {
			var noti = new Notification(title,options);
			noti.addEventListener(
				'click'
				,function() { webnotification('click',title,options,click,clo,btn); }
				,false
			);
			noti.addEventListener(
				'close'
				,function() { webnotification('close',title,options,click,clo,btn); }
				,false
			);
			var timer = window.setTimeout(function() { noti.close(); },5000);	// damit sich der Chrome genauso verhält wie der Firefox, alle paar Sekunden neu anzeigen
			window.onbeforeunload = function() {	// damit sich der Chrome genauso verhält wie der Firefox, Noti nach Seitenwechsel schließen
				window.clearTimeout(timer);
				noti.removeEventListener(
					'close'
					,function() { webnotification('close',title,options,click,clo,btn); }
					,false
				);
				noti.close();
				localStorage.setItem('kal_test','onbeforeunload hat gefeuert');	// check ob onbeforeunload feuert
			};
		};
		if (window.webkitNotifications) {	// Chrome, muss zu oberst abgefragt werden, weil er auch die Methode Notification kennt
			if (window.webkitNotifications.checkPermission() == 0) {	// 0=PERMISSION_ALLOWED; 1=PERMISSION_NOT_ALLOWED; 2=PERMISSION_DENIED
				sendNotification = defaultaction;
			}
			else {
				// ACHTUNG: Chrome lässt requestPermission nur zu, wenn es durch einen Eventhandler aufgerufen wird, der durch eine Benutzeraktion angestossen wurde!
				btn.onclick = function() {
					window.webkitNotifications.requestPermission();
					btn.style.display = 'none';
				}
				if (btn.style.display = 'none') { btn.style.display = ''; }
			}
		}
		else if ("Notification" in window) {	// Firefox
			if (Notification.permission === "granted") {
				sendNotification = defaultaction;
			}
			else if (Notification.permission !== 'denied') {
				Notification.requestPermission(function(permission) {
					if (!('permission' in Notification)) {
						Notification.permission = permission;
					}
				});
			}
		}
		if (sendNotification) {
			sendNotification(title,options,click,clo);
			localStorage.setItem('kal_termstat'+options['id'],'1');	// Status 1=wird noch angezeigt
			return true;
		}
		else { return false; }
	}
	else if (act == 'close') {
		var status = localStorage.getItem('kal_termstat'+options['id']);
		if (status == '1') {	// Firefox sendet beim anklicken ebenfalls ein close
//			localStorage.setItem('kal_termstat'+options['id'],'2');	// Status 2=wurde geschlossen
console.log('nochmal');
webnotification('send',title,options,click,clo,btn);
		}
//		if (clo) { clo(); }
	}
	else if (act == 'click') {
		localStorage.setItem('kal_termstat'+options['id'],'3');	// Status 3=wurde angeklickt
		if (click) { click(); }
	}
}
</script>
</head>

<body>

<script>
function sende() {
	var button_zulassen = document.createElement('input');
	button_zulassen.value = 'Notificationberechtigung anstossen';
	button_zulassen.type = 'button';
	button_zulassen.style.display = 'none';
	document.getElementById('schalter').appendChild(button_zulassen);

	var title = 'Testnoti';
	var dat = new Date();
	var options = {
		body:	'Testnoti Body',
		icon:	'http://www.slipway.de/images/ico_bell.png',
		id:		dat.getMilliseconds()
	};
	var klick_aufruf = function() {
		alert('angeklickt ID '+options['id']);
	};
	var klick_close = function() {
//		alert('geschlossen ID '+options['id']);
//		webnotification('send',title,options,klick_aufruf,klick_close,button_zulassen);
	};

	var ret = webnotification('send',title,options,klick_aufruf,klick_close,button_zulassen);
	document.getElementById('testergebnis').innerHTML = 'Senden war '+(ret ? 'erfolgreich' : 'nicht erfolgreich');
}

</script>

<h1>Test HTML 5 Webnotification</h1>

<div><input onclick="sende();" type="button" value="Test"></div>
<div id="testergebnis"></div>

<div id="schalter"> <br></div>

<div>
 <br> <br> <br>
Links:<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/API/notification#Browser_compatibility" target="_new">Browser Kompatibilität</a><br>
<a href="http://www.html5rocks.com/en/tutorials/notifications/quick/?redirect_from_locale=de" target="_new">Using the Notifications API Ernest Delgado</a><br>
</div>

</body>
</html>
 
Zuletzt bearbeitet:
AW: Problem mit removeEventListener

Das kann so nicht funktionieren, da du ja versuchst eine andere Funktion zu entfernen als du hinzugefügt hast. Die zwei anonymen Funktionen machen zwar das gleiche, aber es sind trotzdem unterschiedliche Funktionen:
Code:
var a = function(){alert(1);}
var b = function(){alert(1);};
alert(a === b);

Du musst dir deine anonyme Funktion in einer Varible speichern, damit du beim .removeEventListener auch Zugriff darauf hast.
 
AW: Problem mit removeEventListener

Das mit der Variable habe ich überall gelesen. Aber überall stand nicht, wofür das so ist. Ich dachte, weil meine Aufrufe identisch sind bräuchte ich das nicht. Ist natürlich Quatsch. Danke Korbinian!
Alle Fällen funktionieren jetzt, nur einer nicht:

Wenn man die Seite aufruft im Chrome, auf Test klickt und dann STRG R für Reload. Dann schließt der Chrome die Notification nicht. Warum? Weiß das jemand?
Schlimm daran ist nicht unbedingt, dass die Noti nicht schließt sondern dass alles andere gemacht wird, das heißt, mein Flag im localStorage ist weg, was bedeutet, dass auch die Noti zu ist.

Die Seite online: Test HTML 5 Notification

Zum selbst spielen:
HTML:
<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Language" content="de">
<meta name="google" content="notranslate">
<title>Test HTML 5 Notification</title>
<style type="text/css">
body {
	font-family:	Arial;
	font-size:		12px;
}
</style>
<script>
function webnotification(act,title,options,click,btn) {
	"use strict";
	if (act == 'check') {
		if (window.webkitNotifications || "Notification" in window) { return true; }
		else { return false; }
	}
	else if (act == 'send') {
		var status = localStorage.getItem('kal_termstat'+options['id']);
		if (!status) {
			var sendNotification;
			var defaultaction = function(title,options,click) {
				var listener = function() {	// Zwangsweise über Variable, weil sonst removeEventListener() nicht klappt
					var status = localStorage.getItem('kal_termstat'+options['id']);
					localStorage.removeItem('kal_termstat'+options['id']);
					window.onbeforeunload = null;
					if (status == '1') {	// Firefox feuert beim onclick auch immer onclose
						webnotification('send',title,options,click,btn);
					}
				};
				var schliessen = function() {
					window.clearTimeout(timer);
					noti.removeEventListener('close',listener,false);
					noti.close();
					localStorage.removeItem('kal_termstat'+options['id']);
				};
				var noti = new Notification(title,options);
				noti.addEventListener(
					'click'
					,function() {
						schliessen();
						window.onbeforeunload = null;
						if (click) { click(); }
					}
					,false
				);
				noti.addEventListener('close',listener,false);
				var timer = window.setTimeout(function() {	// damit sich der Chrome genauso verhält wie der Firefox, alle paar Sekunden neu anzeigen
					noti.close();
				},4500);
				window.onbeforeunload = function() {	// damit sich der Chrome genauso verhält wie der Firefox, Noti nach Seitenwechsel schließen
					schliessen();
				};
			};
			if (window.webkitNotifications) {	// Chrome, muss zu oberst abgefragt werden, weil er auch die Methode Notification kennt
				if (window.webkitNotifications.checkPermission() == 0) {	// 0=PERMISSION_ALLOWED; 1=PERMISSION_NOT_ALLOWED; 2=PERMISSION_DENIED
					sendNotification = defaultaction;
				}
				else {
					// ACHTUNG: Chrome lässt requestPermission nur zu, wenn es durch einen Eventhandler aufgerufen wird, der durch eine Benutzeraktion angestossen wurde!
					btn.onclick = function() {
						window.webkitNotifications.requestPermission();
						btn.style.display = 'none';
					}
					if (btn.style.display = 'none') { btn.style.display = ''; }
				}
			}
			else if ("Notification" in window) {	// Firefox
				if (Notification.permission === "granted") {
					sendNotification = defaultaction;
				}
				else if (Notification.permission !== 'denied') {
					Notification.requestPermission(function(permission) {
						if (!('permission' in Notification)) {
							Notification.permission = permission;
						}
					});
				}
			}
			if (sendNotification) {
				sendNotification(title,options,click);
				localStorage.setItem('kal_termstat'+options['id'],'1');	// Status 1=wird noch angezeigt
				return 1;
			}
			else { return 0; }
		}
		else { return 2; }
	}
}
</script>
</head>

<body>

<script>
function sende() {
	window.setTimeout(function() {
		var button_zulassen = document.createElement('input');
		button_zulassen.value = 'Notificationberechtigung anstossen';
		button_zulassen.type = 'button';
		button_zulassen.style.display = 'none';
		document.getElementById('schalter').appendChild(button_zulassen);

		var title = 'Testnoti '+document.getElementById('notiid').value;
		var options = {
			body:	'Testnoti Body',
			icon:	'http://www.slipway.de/images/ico_bell.png',
			id:		document.getElementById('notiid').value
		};
		var klick = function() {
			alert('angeklickt ID '+options['id']);
		};

		var ret = webnotification('send',title,options,klick,button_zulassen);
		document.getElementById('testergebnis').innerHTML = 'Senden war '+(ret ? (ret == '2' ? 'unnötig, weil die Anzeige noch läuft' : 'erfolgreich') : 'nicht erfolgreich');
	},50);	// falls man die Noti verzögert anzeigen möchte, um zu zeigen, dass sie auch zu sehen ist, wenn der Browser im Hintergrund liegt
}

</script>

<h1>Test HTML 5 Webnotification</h1>

<div>
	ID: <input type="text" id="notiid"> (unterschiedliche Nummer verwenden stapelt die Notis, das sieht im Chrome sehr nett aus)<br>
	<input onclick="sende();" type="button" value="Test">
</div>
<div id="testergebnis"></div>

<div id="schalter"></div>

<br> <br> <br> <br>
<form method="get" action="http://www.google.de" name="test"></form>
<input type="button" value="Verschwindet die Noti, wenn man hier klickt?" onclick="document.test.submit();">

<br> <br>
<form method="get" action="html5_noti.html" name="test2"></form>
<input type="button" value="Verschwindet sie auch, wenn man hier klickt?" onclick="document.test2.submit();">

<br> <br> <br> <br>
<input type="button" value="localStorage leeren" onclick="localStorage.clear();">
<div>
 <br> <br> <br>
Links:<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/API/notification#Browser_compatibility" target="_new">Browser Kompatibilität</a><br>
<a href="http://www.html5rocks.com/en/tutorials/notifications/quick/?redirect_from_locale=de" target="_new">Using the Notifications API Ernest Delgado</a><br>
</div>

</body>
</html>
 
AW: Problem mit removeEventListener

Hm... das scheint mir ein Bug im Chrome zu sein. Mach' da doch mal einen Bugrequest.
 
AW: Problem mit removeEventListener

Hier habe ich festgestellt, dass das nicht schlimm ist, denn wenn man eine Noti mit dem selben "tag" reingibt wird das hängen gebliebene ersetzt.
 
Zurück
Oben