fancyapps / fancybox

jQuery lightbox script for displaying images, videos and more. Touch enabled, responsive and fully customizable.
http://fancyapps.com/
7.28k stars 1.78k forks source link

Hash detection is inexact and causes navigation loops. #2572

Open garretwilson opened 3 years ago

garretwilson commented 3 years ago

Currently the hash parser attempts to parse out a hash in the form foo-X, where foo is the gallery name and X is some integer. But the parsing isn't exact enough and gets some false positives, which can cause loops.

Let's say I have this HTML:

<div id="gallery">
  <a data-fancybox="gallery" href="image1.jpg">…
  <a data-fancybox="gallery" href="image1.jpg">…
  <a data-fancybox="gallery" href="image1.jpg">…
<div>

Without Fancybox, I can navigate to the start of the gallery using page.html#gallery. But when Fancybox is used, Fancybox sees the #gallery and thinks it is one of the gallery images, but it can't find the image number, so it navigates to the first one #gallery-1.

The problem occurs when I hit Esc to exit Fancybox. The URL reverts back to #gallery, but Fancybox sees it and again thinks the hash is referring to a gallery image, so it brings back #gallery-1. This I can't exit Fancybox by hitting Esc because it goes in a loop.

The only way to break out of this is to hit the "Back" button twice, because the first time will go back to #gallery but stay in the Fancybox lighbox. The next press of "Back" will finally take me out (but navigate me away from the #gallery URL, which I didn't want to do).

The bug here seems to be in an inexact hash matching. Fancybox should not think #gallery indicates a gallery image, only #gallery-1 and the like.

The code is probably in parseUrl():

rez = hash.split("-"),
      index = rez.length > 1 && …

If we are detecting a hash in the form of foo-X, then the length of rez should be at least 2. The code seems to be too lenient and falls back to an image of 1 if there is a problem. But the match shouldn't have occurred in the first place if the hash didn't in fact match.

mjcampagna commented 3 years ago

I think you can prevent this by assigning a data-fancybox value other than the id of your container (in this case, "gallery").

Something like:

<div id="gallery">
<a data-fancybox="slideshow">...</a>
<a data-fancybox="slideshow">...</a>
<a data-fancybox="slideshow">...</a>
</div>
garretwilson commented 3 years ago

I think you can prevent this by assigning a data-fancybox value other than the id of your container (in this case, "gallery").

Yes, that is a workaround to this bug. In fact that's what I'm forced to do currently on my site. But hopefully the bug will be fixed so I won't have to use a workaround.