henrygd / bigger-picture

JavaScript lightbox gallery for images, video, audio, iframes, html. Zoomable, responsive, accessible, lightweight.
https://biggerpicture.henrygd.me
MIT License
231 stars 17 forks source link

500 matchMedia is not defined #5

Closed JVariance closed 2 years ago

JVariance commented 2 years ago

Hi, I don't get BiggerPicture to work in my Svelte setup.

If I import it like so import BiggerPicture from 'bigger-picture/src/bigger-picture.js'; I get a 500 line must be greater than 0 (lines start at line 1)-Error somewhere in Vite. If I import like so import BiggerPicture from ../Components/external/bigger-picture/src/bigger-picture.js';, I get the following Error:

ReferenceError: matchMedia is not defined
    at /src/Components/external/bigger-picture/src/stores.js:6:0
    at async instantiateModule (...
henrygd commented 2 years ago

Thanks, I'll have a fix out later today

henrygd commented 2 years ago

Let me know if it still doesn't work for you in 1.0.5

JVariance commented 2 years ago

This error is gone, but now I get [HMR][Svelte] Unrecoverable HMR error in <Bigger-picture>: next update will trigger a full reload and Uncaught (in promise) TypeError: target.insertBefore is not a function

henrygd commented 2 years ago

What does your import statement look like now? target.insertBefore is from svelte/internal so I'm not sure why that would be causing an error.

Are you using SvelteKit? Any info about your setup would be very helpful.

JVariance commented 2 years ago

Yeah, I use SvelteKit. My import looks like

<script lang="ts">
...
import BiggerPicture from 'bigger-picture/src/bigger-picture.js';
...
</script>
henrygd commented 2 years ago

Tested in SvelteKit and it's working: https://bpsveltekit.vercel.app/

Here's what I did. Obviously there are other ways to do it depending on what you need.

I think what may be happening is that you're initializing with the BiggerPicture function outside the browser context (hence why target.insertBefore is not a function). You don't really need to do that, since it doesn't need to be in the dom on page load.

Instead, just wait to initialize it until you need it, in response to user action in the browser (or in onMount or a use action).

import BiggerPicture from "bigger-picture/src/bigger-picture.js";

let bp: any;

function openBiggerPicture(e: MouseEvent) {
  e.preventDefault();
  if (!bp) {
    bp = BiggerPicture({
      target: document.body,
    });
  }
  bp.open({
    items: (<HTMLElement>e.currentTarget).parentElement!.children,
    el: e.currentTarget,
  });
}
{#each items as item}
  <a
    on:click={openBiggerPicture}
    href={item.href}
    data-img={item.img}
    data-thumb={item.thumb}
    data-height={item.height}
    data-width={item.width}
    data-alt={item.alt}
  >
    <img src={item.thumb} alt={item.alt} />
  </a>
{/each}

Alternative onMount example:

import BiggerPicture from "bigger-picture/src/bigger-picture.js";
import { onMount } from "svelte";

let bp: any;

function openBiggerPicture(e: MouseEvent) {
  e.preventDefault();
  bp.open({...});
}

onMount(() => {
  bp = BiggerPicture({
    target: document.body,
  });
});

Let me know what happens. I may add something in the docs about this.

JVariance commented 2 years ago

Oh man, I had it in onMount already, but now I found the cause. VisualStudio Code said that 'target' expects a string, so I passed in the id as string instead of the element. Now it works! Sorry for the hassle and thanks for your help!!

henrygd commented 2 years ago

Ah, that's my fault -- for some reason I had target specified as a string in a jsdoc comment. I'll clean it up for the next release. Glad you got it working and thanks for pointing that out!

JVariance commented 2 years ago

~I stumbled upon a problem again. I want to include an inline gallery. So I created an instance and passed the right attributes to the open function (inline: true, items array also with right attributes and working links), but the gallery opens as full page gallery instead of inline. Also the images just show up if I include one of the images as img element inside the target div.~

~It's exactly like the example on your website~

I had to set the position to relative with css 😃 maybe you could add this information in the docs ☝🏼