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

Direct link to sub-item not scrolling to correct position #351

Open
adrianbj opened this issue Jan 17, 2018 · 10 comments
Open

Direct link to sub-item not scrolling to correct position #351

adrianbj opened this issue Jan 17, 2018 · 10 comments
Assignees
Milestone

Comments

@adrianbj
Copy link
Contributor

I am sure I must have some setting incorrect, but the first time I load this:
https://adrianbj.github.io/TracyDebugger/#/debug-bar?id=module-disabler

it has the "module-disabler" section at the bottom of the page. I browser reload brings it to the top as expected.

However I don't see the problem with the docs page for docsify, eg: https://docsify.js.org/#/configuration?id=load-navbar works as expected on the first load.

Am I doing something incorrectly?

Thanks, and I hope this is the best place to ask for help.

@QingWei-Li
Copy link
Member

Because there is a picture on your page, the picture height is unknown at first load.

@adrianbj
Copy link
Contributor Author

Any chance you could move the scroll feature code to be triggered after all images have been loaded?

@QingWei-Li QingWei-Li added this to the 4.7.0 milestone Feb 10, 2018
@QingWei-Li QingWei-Li removed this from the 4.7.0 milestone Jun 29, 2018
@adrianbj
Copy link
Contributor Author

Hi @QingWei-Li - any chance I can get this back on your radar please?

@cheng-kang
Copy link
Contributor

@adrianbj just raised a PR for this issue: #723

Would be great if you could help testing it 😄

@IssueHuntBot
Copy link

@issuehuntfest has funded $40.00 to this issue. See it on IssueHunt

@rizdaprasetya
Copy link
Contributor

rizdaprasetya commented Sep 5, 2019

Took quite a while to wait proposed PR to be merged, I end up creating a plugin to overcome this issue
Just include this script tag like the other default Docsify plugins (search, emoji, etc). Put it after Docsify script tag.

<script src="https://cdn.jsdelivr.net/gh/rizdaprasetya/docsify-fix-pageload-scroll@master/index.js"></script>

or add this on your $docsify.plugins declaration:

function (hook, vm) {
    hook.ready(function () {
        // true = show debug log
        let dd = false 
        let TARGET_QUERY = 'id'
        let SCROLL_DELAY = 2000 // in milisecond
        let location = window.location

        dd&&console.log('custom scroll plugin called!')
        let currentUrlWithoutHash = new URL(
            location.origin+location.pathname+
            location.search+location.hash.substring(1)
        )
        let urlQueryParam = currentUrlWithoutHash.searchParams
        let isUrlHasIdQuery = urlQueryParam.has(TARGET_QUERY)
        if(isUrlHasIdQuery){
            dd&&console.log('url has id, will scroll to element')
            let urlId = urlQueryParam.get(TARGET_QUERY)
            // run delayed, to make sure everything loaded
            setTimeout(function() {
                dd&&console.log('will scroll now!')
                try{
                    document.querySelector('#'+urlId)
                        .scrollIntoView()
                } catch(e){ dd&&console.log('custom scroll failed',e) }
            }, SCROLL_DELAY);
        }
    })
},

Incase anyone interested.
Ugly maybe, but it simply works for me ¯_(ツ)_/¯

@Chimildic
Copy link

Chimildic commented Dec 18, 2020

Works for me

// index.html
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="./script/docsify-fix-pageload-scroll.js"></script>
// docsify-fix-pageload-scroll.js
(function () {
    function create() {
        return (hook) => {
            const TARGET_QUERY = 'id';
            const SCROLL_DELAY = 500;

            hook.doneEach(function () {
                if (!location.hash.includes('?')) return;
                let searchParams = new URLSearchParams(location.hash.split('?')[1]);
                let header = document.querySelector('#' + searchParams.get(TARGET_QUERY));
                header && setTimeout(() => header.scrollIntoView(), SCROLL_DELAY);
            });
        };
    }

    if (typeof $docsify === 'object') {
        $docsify.plugins = [].concat(create(), $docsify.plugins);
    }
})();

@iammerrick
Copy link

iammerrick commented Aug 3, 2021

I solved this problem a bit differently, instead of waiting for a certain amount of time, I instead check the top offset of the targeted element. Once the top offset value is "settled" I scroll it into view. All of this feels hacky as can be to me but alas! :-D

(function (win) {
  function create() {
    const urlId = new URLSearchParams(win.location.search).get("id");
    if (!urlId) return null;

    return function (hook, vm) {
      const threshold = 20;
      let identical = 0;
      let lastCheck = 0;

      hook.ready(function () {
        const element = win.document.getElementById(urlId);
        (function poll() {
          var elDistanceToTop =
            window.pageYOffset + element.getBoundingClientRect().top;

          if (lastCheck === elDistanceToTop) {
            identical++;
          }

          lastCheck = elDistanceToTop;

          if (identical > threshold) {
            element.scrollIntoView();
          } else {
            setTimeout(poll, 10);
          }
        })();
      });
    };
  }

  win.ScrollAfterImageLoad = {};
  win.ScrollAfterImageLoad.create = create;

  if (typeof win.$docsify === "object") {
    win.$docsify.plugins = [].concat(create(), $docsify.plugins);
  }
})(window);

@zhangtian512
Copy link

Took quite a while to wait proposed PR to be merged, I end up creating a plugin to overcome this issue Just include this script tag like the other default Docsify plugins (search, emoji, etc). Put it after Docsify script tag.

<script src="https://cdn.jsdelivr.net/gh/rizdaprasetya/docsify-fix-pageload-scroll@master/index.js"></script>

or add this on your $docsify.plugins declaration:

function (hook, vm) {
    hook.ready(function () {
        // true = show debug log
        let dd = false 
        let TARGET_QUERY = 'id'
        let SCROLL_DELAY = 2000 // in milisecond
        let location = window.location

        dd&&console.log('custom scroll plugin called!')
        let currentUrlWithoutHash = new URL(
            location.origin+location.pathname+
            location.search+location.hash.substring(1)
        )
        let urlQueryParam = currentUrlWithoutHash.searchParams
        let isUrlHasIdQuery = urlQueryParam.has(TARGET_QUERY)
        if(isUrlHasIdQuery){
            dd&&console.log('url has id, will scroll to element')
            let urlId = urlQueryParam.get(TARGET_QUERY)
            // run delayed, to make sure everything loaded
            setTimeout(function() {
                dd&&console.log('will scroll now!')
                try{
                    document.querySelector('#'+urlId)
                        .scrollIntoView()
                } catch(e){ dd&&console.log('custom scroll failed',e) }
            }, SCROLL_DELAY);
        }
    })
},

Incase anyone interested. Ugly maybe, but it simply works for me ¯_(ツ)_/¯

worked for me. thanks

@stdword
Copy link

stdword commented Jul 6, 2024

Hello! In 2024 this issue still exists for plugins. I've faced this one in docsify-tabs. And agree with @jhildenbiddle — it should be handled by docsify with something like:

hook.beforeScrollToAnchor(function (path, anchor) {
    // detect the height of the content and calculate the correct position for scrolling
});

Here is my solution for docsify-tabs. And I combined it with my version of scroll-finisher:

function fixTabs() {
  const uriComponent = window.location.hash || window.location.search;
  const anchorID = (uriComponent.match(/(?:id=)([^&]+)/) || [])[1]
  if (!anchorID)
    return

  const anchorElement = document.querySelector('#' + decodeURIComponent(anchorID));

  function adjust(treshold = 3, interval = 20, pixelDelta = 4) {
    if (adjust.state !== null) {
      if (window.pageYOffset == adjust.state) {
        adjust.settledCount++
        if (adjust.settledCount > treshold) {
          if (Math.abs(window.pageYOffset - anchorElement.offsetTop) > pixelDelta)
            window.scrollTo({top: anchorElement.offsetTop, behavior: 'smooth'});
          else return
        }
      }
    }

    if (adjust.state === null || adjust.settledCount <= treshold)
      setTimeout(adjust, interval)
    adjust.state = window.pageYOffset
  }
  adjust.settledCount = 0
  adjust.state = null

  if (anchorElement)
    adjust()
}

function docsifyTabsFix(hook, vm) {
  hook.doneEach(function () {
    const hasTabs = document.querySelector(`.docsify-tabs__tab`);
    if (hasTabs)
      fixTabs()
  });
}

window.$docsify = window.$docsify || {};
window.$docsify.plugins = [].concat(window.$docsify.plugins || [], docsifyTabsFix);

@jhildenbiddle jhildenbiddle added this to the 5.x milestone Jul 6, 2024
@jhildenbiddle jhildenbiddle self-assigned this Jul 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants