Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] JQuery Lazy + smooth scrolling to anchor #98

Closed
Kristinita opened this issue Jul 28, 2017 · 6 comments
Closed

[Question] JQuery Lazy + smooth scrolling to anchor #98

Kristinita opened this issue Jul 28, 2017 · 6 comments
Assignees
Labels

Comments

@Kristinita
Copy link

Kristinita commented Jul 28, 2017

1. Problem

If I use:

My scrollbar do not scroll to expected anchor.

If

  • I don't use JQuery Lazy,

or

  • All images downloaded in web-page,

I can successful use smooth scrolling to expected anchors.

2. Actual behavior

Demonstration video.

I click to 3.5.1 item, but scrollbar scroll to 3.1.2 item for me.

3. Settings

My page in demonstration video — http://kristinita.ru/Sublime-Text/SashaSublime

My script of Gemini, JQuery Lazy and smooth scrolling:

////////////
// Gemini //
////////////
// Example — https://github.com/noeldelgado/gemini-scrollbar/blob/master/examples/01-body.html
window.onload = function() {
    if (window.matchMedia("(min-width: 60rem)").matches) {
        // **For** PC
        var pcscrollbar = new GeminiScrollbar({
            // querySelector method — https://www.w3schools.com/jsref/met_document_queryselector.asp
            element: document.querySelector("main"),
            autoshow: true,
        }).create();
        // Smooth scrolling — https://stackoverflow.com/a/7717572/5951529
        // https://github.com/noeldelgado/gemini-scrollbar/issues/52#issuecomment-318369755
        $('a').click(function() {
            $(pcscrollbar.getViewElement()).animate({
                scrollTop: $('[name="' + $.attr(this, 'href').substr(1) + '"]').offset().top
            }, 10000);
            return false;
        });
        // JQuery Lazy support —
        // https://github.com/eisbehr-/jquery.lazy/issues/88#issuecomment-299138103
        $(".SashaLazy").Lazy({
            appendScroll: $(pcscrollbar.getViewElement()),
            // Run method “update” of JQuery Lazy:
            // https://github.com/eisbehr-/jquery.lazy/issues/88#issuecomment-299196388
            // http://jquery.eisbehr.de/lazy/example_callback-functions
            // https://github.com/noeldelgado/gemini-scrollbar#basic-methods
            beforeLoad: function() {
                pcscrollbar.update();
            }
        });
    } else {
        // For Mobile
        var mobilescrollbar = new GeminiScrollbar({
            element: document.querySelector("body"),
            autoshow: true
        }).create();
        $(".SashaLazy").Lazy({
            appendScroll: $(mobilescrollbar.getViewElement()),
            afterLoad: function() {
                mobilescrollbar.update();
            }
        });
    }
};

This script based on your and @noeldelgado answers.

4. Did not help

  1. I read description and issues of JQuery Lazy, but I don't understand, how I can solve this problem.

Thanks.

@dkern
Copy link
Owner

dkern commented Aug 1, 2017

Hello @Kristinita

Without see it it's hard to be 100% sure (your page was not available at this time), but I belive that problem belongs to how the scrips work. I mean, think about what happen:

On page load, there is no image loaded jet. You click on a link and smooth scroll figures out where (in pixel) the element you want to scroll to is located. Then the scrolling is applied. Now, on the way scrolling down, you reaches new images. Lazy will start loading these images and the content becomes bigger and bigger. But the smooth scroll still thinks the end location is on a given point and stop there.

So in general everything works as espected, but you forgot about how things work. 😉

@dkern
Copy link
Owner

dkern commented Aug 2, 2017

An Idea: A solution would be to give all your images, you want to lazy load, the exactly width and height. That would prevent that the content changes it's size on scrolling down.

@dkern
Copy link
Owner

dkern commented Aug 4, 2017

I'll close this here because of no more response and because this seems not to be an issue with lazy itself.

@dkern dkern closed this as completed Aug 4, 2017
@Kristinita
Copy link
Author

Kristinita commented Mar 25, 2018

@eisbehr,

I'll close this here because of no more response and because this seems not to be an issue with lazy itself.

Why “not to be an issue with lazy itself”?

I simplify an example. No Gemini Scrollbar, no smooth scrolling, only JQuery Lazy.

1. Summary

If I use JQuery Lazy and click to anchor link:

    scrollbar does not reach header.

2. Source

On Codepen:

Significant parts of source:

<script src="//cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/jquery.lazy/latest/jquery.lazy.min.js"></script>
<script src="//cdn.jsdelivr.net/jquery.lazy/latest/jquery.lazy.plugins.min.js"></script>
<script>
    $(function() {
        $('.SashaLazy').Lazy();
    });
</script>
<p><img class="SashaLazy" src="https://kristinita.ru//theme/images/interface-images/transparent-one-pixel.png" data-src="https://kristinita.ru/theme/images/404/SashaNose.png" alt="SashaGreenSweater"></p>
<p><img class="SashaLazy" src="https://kristinita.ru//theme/images/interface-images/transparent-one-pixel.png" data-src="https://kristinita.ru/theme/images/aside/SashaGreenSweater.jpg" alt="SashaGreenSweater"></p>

3. Demonstration

4. Expected behavior

Scrollbar move to Relevance word.

5. Actual behavior

Scrollbar move to images.

6. Exactly width and height

An Idea: A solution would be to give all your images, you want to lazy load, the exactly width and height.

  • I don't need exactly width and height for each image. For me it is enough default height and width.

Any ideas?

Thanks.

@dkern
Copy link
Owner

dkern commented Mar 26, 2018

Simply think about how things work and what you do there. You click on a link to scroll to this element/id. The browser looks where the element is located in page, and scrolls to it. But on the way down, Lazy will load the images in between (as it should be). But then, the location of the original element is not on the same spot as before loading the images. So this can't work as you expect. But this is not an issue of Lazy, you will get this problem whenever you change the page while scrolling.

If you want to use Lazy and want to scroll to elements, you need to give your images fixed dimensions, so the browser known the size of the not loaded elements before scrolling.

@julian-sloman-ffatg
Copy link

julian-sloman-ffatg commented Mar 27, 2020

Another option would be using some kind of step function to re-evaluate the target's position on scroll - tried getting that to work with jQuery's .animate

$("a[href^='#']").on("click", function (e) {
	let id = $(this).attr("href");
	const $target = $(id);

	if ($target.length > 0) { // item with that id exists
		e.preventDefault();

		$('html, body').animate({
			scrollTop: $target.offset().top // Scroll to this location.
		}, {
			duration: 800,
			step: ( now, fx ) => {
				//  location will change as images etc. are lazy loaded
				//  Where is the target now located on the page?
				let realPos = $target.offset().top;
				if (fx.end !== realPos) {
					fx.end = realPos;
				}
			},
		});

		// if supported, update the URL
		if (window.history && window.history.pushState) {
			history.pushState("", document.title, id);
		}
	}
});

seems to work for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants