[jQuery] Scroll-to-top Button bei Anker-Sprung von externer Seite einblenden

safeload

Ensign
Registriert
Juni 2010
Beiträge
244
Hi, ich möchte gerne, zusätzlich zum verwendeten onSite scroll-to-top-script, den entsprechenden Button auch dann einblenden, wenn man die Seite über einen Anker-Link von einer anderen Seite aufruft.

Dazu habe ich eine weitere Funktion angelegt, die onLoad den Offset des Elements (#map) zum oberen Dokumentrand mit einem vorgegebenem Wert vergleichen soll und bei true den Button einblendet.

Leider funktioniert dies aber nicht und ich habe keine Ahnung warum ...

Code:
// Der Button wird ausgeblendet
	$("#back_to_top").hide();
	
	// Funktion check offset onLoad
	$(function () {

		if ($('#map').offset().top < 100) {
			$('#back_to_top').fadeIn();

		} else {
			return false;
		}
	});

	// Funktion für das Scroll-Verhalten
	$(function () {

		$(window).scroll(function () {
			if ($(this).scrollTop() > 100) { // Wenn 100 Pixel gescrolled wurde
				$('#back_to_top').fadeIn();

			} else {
				$('#back_to_top').fadeOut();
			}
		});
 
Hi,

was heißt "funktioniert nicht"? Fehler? Was passiert?

Wenn du nicht weisst, warum etwas nicht funktioniert: schrittweise durch debuggen, Werte ausgeben lassen, prüfen, was du erwartest und was wirklich Fakt ist.

VG,
Mad
 
Also von JS Debugging hab ich leider noch keine Ahnung ... aber in der Konsole hab ich dies gefunden:

-"jQuery.Deferred exception: $(...).offset(...) is undefined"

-"Diese Website verwendet anscheinend einen scroll-verknüpften Positionierungseffekt. Dies könnte mit asynchronem Verschieben (Panning) schlecht zusammenspielen; siehe https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects für weitere Details und nehmen Sie an der Diskussion über damit verbundene Werkzeuge und Funktionen teil!"
 
Zuletzt bearbeitet:
ja gerne und wie kann ich dies in der Funktion umsetzen?
Ich habe übrigens die Google Maps Skripte erstmals am Ende des body eingefügt, da diese sonst sporadisch nicht geladen bzw. angezeigt wurde (blank div). Ich hoffe, hier liegt keine Fehlerquelle ...
 
Hi,

-"jQuery.Deferred exception: $(...).offset(...) is undefined"

lass dir einfach im Code mit "console.log([WERTE])" - WERTE zu ersetzen durch die Objekte und Variablen, die du ausgeben möchtest - die Werte in die Console ausgeben. Scheinbar versuchst du das "offset" auf ein Objekt zu legen, dass es entweder zu diesem Zeitpunkt nicht gibt oder das ein anderes Problem hat.

Warten kannst du, indem du wartest - da verstehe ich das Problem nicht. Prüfe vorab, ob es dein gewünschtes Objekt schon gibt und mach dann weiter, wenn das so ist.

VG,
Mad
 
ok danke, leider wird mir kein log in der FF-Konsole ausgegeben.

Code:
$(function () {
		if ($('#map').offset().top < 100) {
			console.log('#map');
			$('#back_to_top').fadeIn();
			console.log('#back_to_top');
		} else {
			return false;
		}
	});

Unbenannt.PNG


ein verzögerter Aufruf brachte keine Änderung bzgl. der Button-Einblendung

Code:
$(function () {
		setTimeout(function () {
			if ($('#map').offset().top < 100) {
				/*console.log('#map');*/
				$('#back_to_top').fadeIn();
				/*console.log('#back_to_top');*/
			} else {
				return false;
			}
		}, 2000);
	});

eine Prüfung vorab ergibt die meldung "map geladen", jedoch bleibt #map weiß bis die Meldung mit ok bestätigt wird.

Code:
	$(function () {
		if ($('#map').length > 0) {
			alert('#map geladen');

			if ($('#map').offset().top < 100) {
				console.log('#map');
				$('#back_to_top').fadeIn();
				console.log('#back_to_top');
			} else {
				return false;
			}
			
		} else {
			alert('#map nicht geladen');
			return false;
		}
	});

Unbenannt.PNG

Ein weiterer Ergänzung des Code zeigt, daß die Bedingung zur Einblendung nicht als erfüllt angesehen wird, denn es wird die Meldung "offset not true" angezeigt.

Code:
if ($('#map').offset().top < 100) {
				$('#back_to_top').fadeIn();
			} else {
				alert('offset not true');
				return false;
			}

Unbenannt.PNG

Dabei ist nach dem externen anchor-call #map direkt am oberen Dokumentrand positioniert
 
Zuletzt bearbeitet:
Hi,

natürlich wird das "console.log" nicht ausgegeben, wenn der Fehler schon davor kommt!

Lass dir doch einfach mal vor deinem "$('#map').offset()" deine "#map" ausgeben.

VG,
Mad
 
Hi evil smile,
console.log('#map'); gibt jetzt #map aus.
Also existiert das Element vor der offset Prüfung (wie "alert('#map geladen');" ja schon angedeutet hat) und der Fehler ist woanders zu suchen.

Da alert bei

Code:
    if ($('#map').offset().top < 100) {
    				$('#back_to_top').fadeIn();
    			} else {
    				alert('offset not true');
    				return false;
    			}

"offset not true" angezeigt wird, sieht es so aus, als wenn die Bedingung offset().top < 100 onLoad nicht erfüllt wird ...

edit:
alert($('#map').offset().top); gibt mir 1593 aus, also wird die Entfernung von #map zu Dokumentrand ohne Berücksichtigung des Anker-Sprungs ausgegeben.

Müsste jetzt nur noch wissen, wie ich ('#map').offset().top) NACH dem Anker-Sprung ermittle.
Timeout von 2s hat hier ja leider nichts gebracht ...
 
Zuletzt bearbeitet:
Hi,

lässt du "#map" als string ausgeben? Du sollst natürlich das Objeklt ausgeben!

Nicht die Bedingung "offset().top < 100" wird nicht erfüllt, dein Fehler von ganz oben sagt, dass "offset" keine Methode des Objekts ist. Also entweder falsches Objekt oder Objekt gibt es noch nicht!

VG,
Mad
 
ja leider als string, sorry. War mir dessen nicht bewusst :/
Hier also nochmal als object

Code:
{…}
X: undefined
__gm: Object { S: div#map, b: {…}, D: {…}, … }
center: Object { lat: _.D/this.lat(), lng: _.D/this.lng() }
controls: Array [ <1 empty slot>, {…}, {…}, … ]
data: Object { gm_accessors_: {…}, map: {…}, j: false, … }
features: Object {  }
gm_accessors_: Object { center: null, zoom: null, scrollwheel: null, … }
gm_bindings_: Object { reportErrorControl: […], center: […], zoom: […], … }
mapTypeId: "roadmap"
mapTypes: Object {  }
overlayMapTypes: Object { b: [], gm_accessors_: {…}, length: 0, … }
scrollwheel: false
streetView: Object { j: false, m: false, standAlone: false, … }
zoom: 15
__proto__: Object { constructor: tg(), streetView_changed: _.m.streetView_changed(), getDiv: _.m.getDiv(), … }
 
Hi,

"undefined" könnte das Stichwort sein. Solange das Objekt nicht existiert kannst du - natürlich - auch nicht auf die entsprechenden Funktionen zugreifen. Gibt dir das "map" irgendeine Möglichkeit für ein "loaded" oder einen anderen Callback-Event? So dass du erst darin die anderen Funktionen anstartest?

VG,
Mad
 
Also irgendwie kapier ich´s noch nicht.
Die Google Map ist doch nur ein Object innerhalb der div #map und lediglich der Abstand der div #map zum oberen Dokumentrand wird benötigt und diese ist von Beginn an in der DOM ...

(im ggs. zum eingeblendeten Button, der per jQuery erzeugt wird)

Code:
	var back_to_top_button = ['<a href="#top" id="back_to_top"><div><img src="svg/chevron-arrow-up.svg"></div></a>'].join("");
	$("body").append(back_to_top_button);

Um deine Frage aber zu beantworten: Man könnte eine callback-function hinter der function initMap() plazieren.

edit:
Hab es jetzt so gelöst, daß ich eine scroll-to-#map-Funktion einfach über den Hash der anderen Seite triggere.
Die Funktion bestimmt vorher den aktuellen Abstand zum Dokumenrand und passt so dynamisch bei verschiedenen Fensterhöhen den offset Wert beim scrollen an.

Dieses scrollen wird von der scroll-to-top-Funktion erkannt welche dann den back-to-top button einblendet.

@Madman1209: Danke für die Unterstützung!
 
Zuletzt bearbeitet:
Zurück
Oben