Contao-Camp 2024
Ergebnis 1 bis 5 von 5

Thema: Contao 4.7.2 - Unterschiedliches Scroll-Verhalten in Safari, Chrome, FF, Opera

  1. #1
    Contao-Fan Avatar von Seefahrer
    Registriert seit
    20.12.2012.
    Ort
    Wurster Nordseeküste
    Beiträge
    276

    Standard Contao 4.7.2 - Unterschiedliches Scroll-Verhalten in Safari, Chrome, FF, Opera

    Hallo liebe Contao-Gemeinde ...

    ich habe da noch eine Ungereimtheit in meinem OnePager https://www.luetten-dieks-carlito.eu bemerkt:

    Und zwar soll beim Anklicken der Menüpunkte zum entsprechenden Abschnitt/Artikel gescrollt werden, die Topposition des Artikels soll dabei 80px (scrollOffset: $('#header-bar').height()) unterhalb des oberen Bildschirmrand liegen, da der Header-Bar mit dem Menü 80px hoch ist und der Header-Bar keinen Inhalt verdecken soll ...

    Mein Scroll-Script benutzt u.a. folgenden Code, um das zu bewerkstelligen:
    Code:
        ...
    
    scrollTo: function(target, callback) {
    	var offset = $(target).offset().top - this.config.scrollOffset;
    	$('html, body').animate({scrollTop: offset}, this.config.scrollSpeed, this.config.easing, callback);
    },
    
        ...
    Soweit so gut, unter Safari funktioniert das auch genauso wie es soll, unter Chrome, FF etc. kommt es zu einem merkwürdigen Effekt: Es wird zunächst korrekt zur Position 80px unterhalb des Bildschirmrands gescrollt, danach springt der Abschnitt/Artikel ruckartig an den Bildschirmrand ... Kann ich mir keinen Reim drauf machen. Die Chrome/FF Useragents, die in Safari eingebaut sind verhalten sich ok, nur die proprietären Browser lassen den Inhalt nach oben schnellen.

    Ich hoffe, dass ich mich einigermaßen verständlich gemacht habe ... läßt sich unter o.g. Link besichtigen ... Vielleicht hat von Euch einer eine Idee?! Danke im Voraus ...

  2. #2
    Contao-Urgestein Avatar von folkfreund
    Registriert seit
    09.04.2010.
    Beiträge
    1.928

    Standard

    Wie löst du denn die Scrollfunktion aus?
    Wenn du das über einen Klick auf eine Anker-Link tust, dann könnte das Verhalten daher rühren, dass abschließend noch der 'normale' Klick ausgeführt wird, der den Ziel-Anker an den oberen Rand positioniert.

    Kannst du einen Link zur Seite zeigen?

  3. #3
    Contao-Urgestein Avatar von fiedsch
    Registriert seit
    09.07.2009.
    Ort
    München
    Beiträge
    2.939

    Standard

    Zitat Zitat von folkfreund Beitrag anzeigen
    Kannst du einen Link zur Seite zeigen?
    gibt es doch schon

    Zitat Zitat von Seefahrer Beitrag anzeigen
    [...] in meinem OnePager https://www.luetten-dieks-carlito.eu bemerkt:
    Contao-Community-Treff Bayern: http://www.contao-bayern.de

  4. #4
    Contao-Fan Avatar von Seefahrer
    Registriert seit
    20.12.2012.
    Ort
    Wurster Nordseeküste
    Beiträge
    276

    Standard

    Hallo folkfreund!

    Zitat Zitat von folkfreund Beitrag anzeigen
    Wie löst du denn die Scrollfunktion aus?
    Wenn du das über einen Klick auf eine Anker-Link tust, dann könnte das Verhalten daher rühren, dass abschließend noch der 'normale' Klick ausgeführt wird, der den Ziel-Anker an den oberen Rand positioniert.
    Könnte eine Erklärung sein, aber warum dann nur in Safari ... ??? Und wenn, wie kann ich das verhindern?

    Link zur Seite: https://www.luetten-dieks-carlito.eu

    Ich verwende Trevor Davis' jQuery OnePageNav:

    Code:
    /*
     * jQuery One Page Nav Plugin
     * http://github.com/davist11/jQuery-One-Page-Nav
     *
     * Copyright (c) 2010 Trevor Davis (http://trevordavis.net)
     * Dual licensed under the MIT and GPL licenses.
     * Uses the same license as jQuery, see:
     * http://jquery.org/license
     *
     * @version 3.0.0
     *
     * Example usage:
     * $('#nav').onePageNav({
     *   currentClass: 'active',
     *   changeHash: false,
     *   scrollSpeed: 1000,
     *   scrollOffset: 80
     * });
     */
    
    ;(function($, window, document, undefined){
    
    	// our plugin constructor
    	var OnePageNav = function(elem, options){
    		this.elem = elem;
    		this.$elem = $(elem);
    		this.options = options;
    		this.metadata = this.$elem.data('plugin-options');
    		this.$win = $(window);
    		this.sections = {};
    		this.didScroll = false;
    		this.$doc = $(document);
    		this.docHeight = this.$doc.height();
    	};
    
    	// the plugin prototype
    	OnePageNav.prototype = {
    		defaults: {
                navItems: 'a',
                currentClass: 'active',
                changeHash: false,
                easing: 'swing',
                filter: null,
                scrollSpeed: 750,
                scrollOffset: 80,
                scrollThreshold: 0.5,
                begin: false,
                end: false,
                scrollChange: false
    		},
    
    		init: function() {
    			// Introduce defaults that can be extended either
    			// globally or using an object literal.
    			this.config = $.extend({}, this.defaults, this.options, this.metadata);
    
    			this.$nav = this.$elem.find(this.config.navItems);
    
    			//Filter any links out of the nav
    			if(this.config.filter) {
    				this.$nav = this.$nav.filter(this.config.filter);
    			}
    
    			//Handle clicks on the nav
    			this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this));
    
    			//Get the section positions
    			this.getPositions();
    
    			//Handle scroll changes
    			this.bindInterval();
    
    			//Update the positions on resize too
    			this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this));
    
    			return this;
    		},
    
    		adjustNav: function(self, $parent) {
    			self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
    			$parent.addClass(self.config.currentClass);
    		},
    
    		bindInterval: function() {
    			var self = this;
    			var docHeight;
    
    			self.$win.on('scroll.onePageNav', function() {
    				self.didScroll = true;
    			});
    
    			self.t = setInterval(function() {
    				docHeight = self.$doc.height();
    
    				//If it was scrolled
    				if(self.didScroll) {
    					self.didScroll = false;
    					self.scrollChange();
    				}
    
    				//If the document height changes
    				if(docHeight !== self.docHeight) {
    					self.docHeight = docHeight;
    					self.getPositions();
    				}
    			}, 250);
    		},
    
    		getHash: function($link) {
    			return $link.attr('href') ? $link.attr('href').split('#')[1] : '';
    		},
    
    		getPositions: function() {
    			var self = this;
    			var linkHref;
    			var topPos;
    			var $target;
    
    			self.$nav.each(function() {
    				linkHref = self.getHash($(this));
    				$target = linkHref ? $('#' + linkHref) : '';;
    				
    
    				if($target.length) {
    					topPos = $target.offset().top - self.config.scrollOffset;
    					self.sections[linkHref] = Math.round(topPos);
    					console.log(topPos);
    				}
    			});
    		},
    
    		getSection: function(windowPos) {
    			var returnValue = null;
    			var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold);
    
    			for(var section in this.sections) {
    				if((this.sections[section] - windowHeight) < windowPos) {
    					returnValue = section;
    				}
    			}
    
    			return returnValue;
    		},
    
    		handleClick: function(e) {
    			var self = this;
    			var $link = $(e.currentTarget);
    			var $parent = $link.parent();
    			var hash = self.getHash($link);
    			var newLoc = '#' + hash;
    
    			if (!hash || self.isExternalLink($link) || $(newLoc).length === 0) {
    				return;
    			}
    
    			if(!$parent.hasClass(self.config.currentClass)) {
    				//Start callback
    				if(self.config.begin) {
    					self.config.begin();
    				}
    
    				//Change the highlighted nav item
    				self.adjustNav(self, $parent);
    
    				//Removing the auto-adjust on scroll
    				self.unbindInterval();
    
    				//Scroll to the correct position
    				self.scrollTo(newLoc, function() {
    					//Do we need to change the hash?
    					if(self.config.changeHash) {
    						window.location.hash = newLoc;
    					}
    
    					//Add the auto-adjust on scroll back in
    					self.bindInterval();
    
    					//End callback
    					if(self.config.end) {
    						self.config.end();
    					}
    				});
    			}
    
    			e.preventDefault();
    		},
    
    		scrollChange: function() {
    			var windowTop = this.$win.scrollTop()-80;
    			var position = this.getSection(windowTop);
    			var $parent;
    
    			//If the position is set
    			if(position !== null) {
    				$parent = this.$elem.find('a[href$="#' + position + '"]').parent();
    
    				//If it's not already the current section
    				if(!$parent.hasClass(this.config.currentClass)) {
    					//Change the highlighted nav item
    					this.adjustNav(this, $parent);
    
    					//If there is a scrollChange callback
    					if(this.config.scrollChange) {
    						this.config.scrollChange($parent);
    					}
    				}
    			}
    		},
    
    		scrollTo: function(target, callback) {
    			var offset = $(target).offset().top - this.config.scrollOffset;
    			$('html, body').animate({scrollTop: offset}, this.config.scrollSpeed, this.config.easing, callback);
    		},
    
    		unbindInterval: function() {
    			clearInterval(this.t);
    			this.$win.unbind('scroll.onePageNav');
    		},
    
    		isExternalLink: function($link) {
    			return window.location.host !== $link.get(0).host;
    		}
    	};
    
    	OnePageNav.defaults = OnePageNav.prototype.defaults;
    
    	$.fn.onePageNav = function(options) {
    		return this.each(function() {
    			new OnePageNav(this, options).init();
    		});
    	};
    	
    })( jQuery, window , document );

  5. #5
    Contao-Fan Avatar von Seefahrer
    Registriert seit
    20.12.2012.
    Ort
    Wurster Nordseeküste
    Beiträge
    276

    Standard Problem mittels anderem Script gelöst ...

    Für das Script von Trevor Davis habe ich keine Lösung gefunden, scheint tatsächlich so, dass "preventDefault()" nicht greift und nach dem Smoothscroll noch ein Jump zum #anker (top: 0) ausgeführt wird.

    Mittels des "scrollspy" jQuery Plugin (https://github.com/r3plica/Scrollspy) ließ sich das Problem nun lösen, habe es um eine "easing:" Option erweitert, als template eingebunden, und voilà, funktioniert wie gewünscht ...

    Nur für den Fall, dass mal irgendjemand vor dem gleichen Problem stehen sollte ...

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •