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

BUG: goto (scroll to selected element) broken when no-shadow enabled #82

Closed
alifeee opened this issue Jun 22, 2023 · 2 comments · Fixed by #83
Closed

BUG: goto (scroll to selected element) broken when no-shadow enabled #82

alifeee opened this issue Jun 22, 2023 · 2 comments · Fixed by #83
Labels

Comments

@alifeee
Copy link
Contributor

alifeee commented Jun 22, 2023

Working example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js"
    ></script>
  </head>

  <body>
    <zero-md
      src="https://raw.githubusercontent.com/zerodevx/zero-md/master/README.md"
    ></zero-md>
  </body>
</html>

Broken example

The difference is that no-shadow is provided to the <zero-md> element.

<!DOCTYPE html>
<html lang="en">
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@2/dist/zero-md.min.js"
    ></script>
  </head>

  <body>
    <zero-md
      src="https://raw.githubusercontent.com/zerodevx/zero-md/master/README.md"
      no-shadow
    ></zero-md>
  </body>
</html>

Expected behaviour:

go to https://URL#basic-usage. Page should scroll to that heading.

Actual behaviour

console error:

Uncaught TypeError: this.root.getElementById is not a function
    goto index.js:153
    t index.js:66
    setTimeout handler*t/< index.js:66
    promise callback*t index.js:66
    <anonymous> index.js:330
index.js:153:27

Environment

I am using Firefox.

Code

The problem is with the goto function.

zero-md/src/index.js

Lines 151 to 158 in 5a627f2

goto(id) {
if (id) {
const el = this.root.getElementById(id.substring(1))
if (el) {
el.scrollIntoView()
}
}
}

this.root does not have getElementById if no-shadow is true. this.root is set in the constructor() function:

this.root = this.hasAttribute('no-shadow') ? this : this.attachShadow({ mode: 'open' })

The issue appears to be because getElementById is only defined on the document object. See MDN web docs.

@zerodevx
Copy link
Owner

@alifeee Hi! I just saw your sponsorship - much appreciated, thank you! 🙏

A bit of background regarding this issue - native browser behaviour performs page scroll to an element id in 2 areas:

  • URL hash on page load (eg. https://example.com/#header-id)
  • Clicks on anchor links pointing to URL hash (eg. <a href="#header-id">link</a>

This however doesn't work in the context of a custom element, hence the need to shim it (with the goto() function) in this project.

Nice catch that this doesn't work when no-shadow is used. Originally, no-shadow is a bit "experimental" - most of the time <zero-md> is intended to work within its own sandbox (the shadow dom). It's a simple enough fix I think. I'll add comments to your PR and see if we can take it from there.

Thanks once again!

@alifeee
Copy link
Contributor Author

alifeee commented Jun 23, 2023

You have made a good library! It aligns to my opinions regarding simplicity and web content well.

You may see by my other issue (#84) why I am using no-shadow. I would like to use the shadow DOM, but it seems libraries like Mermaid/AnchorJS just don't work with it, currently. I would prefer to use the shadow DOM, it is a nice concept and I like it.

Thanks for the quick comment. :)

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

Successfully merging a pull request may close this issue.

2 participants