Sweetalert2: Pressing Escape key to dismiss on Safari causes window to scroll to bottom of page

Created on 16 Oct 2020  ·  23Comments  ·  Source: sweetalert2/sweetalert2

Current behavior

Using Safari (v13.1.1) on Mojave (10.14.6) and also (on a completely separate Mac) the latest released versions of Mac OS and Safari, when I press the Escape key to dismiss a SweetAlert modal, it closes the modal correctly but then scrolls to the very bottom of the page.

Only seems to happen if an input is displayed (for example input: 'text')

There are no console messages and this behavior does not happen in Chrome or Firefox. Only Safari.

Pressing the "close" button closes the SweetAlert modal correctly without scrolling. Similarly, positive buttons do not affect the window's scroll position.

The odd behavior seems to be prevented by clicking. At first I thought it was the act of "blurring" or unfocusing the input but then I realized that tabbing focus to the button and back to the input still causes the issue to happen when hitting Escape.

The below fiddle uses latest jQuery at the time of writing (3.5.1) and latest SweetAlert2 at the time of writing (10.6.1).

Expected behavior

Not the above. Window should not scroll on pressing Escape to dismiss.

Live demo

https://jsfiddle.net/twistedpixel/e6ktzL51/

Edit 1: add video demonstrating the issue: Dropbox link

Safari

Most helpful comment

Quick update @limonte, I gave up fixing it in renderInput.js because the workaround works well only with input: text. For the other types, a different character need to be used (and I wasn't able to find the correct one for password).

So I went back to debugging the issue and that's what i found so far. The issue is reproduced when you have all of the following conditions:

  • An external script loaded in the <head> of the page
  • A <div> with role="dialog" and aria-modal="true" within a <div> with absolute position.
  • An <input> inside the above <div>

I created a sample page with no Swal code here: https://nutritious-gem-order.glitch.me. In order to reproduce the issue:

I'll start from here to see if there is a way to fix it. I tried already removing the role and aria-modal from swal, but the issue is still reproduced. So there must be something else. @twistedpixel if you can five a try with the page I sent above, that'd confirm I don't have any _gremlins_ in my safari.

All 23 comments

Actually, tabbing focus to the button and not tabbing back to the input also prevents it... so it probably has nothing to do with clicking as I previously thought.

Can't reproduce in the latest Safari (v14)

Not ignoring your reply, just doing some more testing. I'm going to set up a clean install of Catalina and test again. I had a friend test the fiddle on his Mac running Catalina (up to date, Safari 14 up to date as well) and he confirmed it happened.

Ok so I set up a clean install of Catalina, didn't install anything at all, opened the Fiddle and it did exactly as I've described. I'm not sure why your machine is not reproducing the issue.

I'm sorry that this will sound very condescending but I'm just being thorough - did you do exactly the following:

• open Fiddle
• wait for Fiddle to fully load
• click the unstyled button in the top left of the preview
• wait for SweetAlert2 modal to open and fully complete animation
• do not interact with modal in any way
• press escape key once

And the result should be that the preview window scrolls to the bottom so that the text and button at the top are no longer visible.

Doing this on every Safari setup I've tested has reproduced the issue and if you look at the Fiddle, it's pretty barebones. The only included dependencies are SweetAlert2 and jQuery (I know, I know: everyone hates jQuery and I'm The Devil for using it).

I still can't reproduce following your steps. It would be great if anyone else can confirm the issue.

I still can't reproduce following your steps. It would be great if anyone else can confirm the issue.

Just one other thing that occurred to me - you don't have any extensions installed that would hijack native scrolling do you? Something to prevent "jumping" when ads load or anything? If so, they could be obscuring the bug.

I still can't reproduce following your steps. It would be great if anyone else can confirm the issue.

Just one other thing that occurred to me - you don't have any extensions installed that would hijack native scrolling do you? Something to prevent "jumping" when ads load or anything? If so, they could be obscuring the bug.

Nope, clean Safari v14. Could you maybe record a video which demonstrates the issue?

Nope, clean Safari v14. Could you maybe record a video which demonstrates the issue?

Of course, here you go (and I will edit the original post to include the link too) : Dropbox link

I'm confused about this issue since I can definitely see that it's happening for @twistedpixel but I can't reproduce it.

Can any macOS user confirm the issue or confirm the absence of the issue? cc @gverni @tiagostutz @zenflow

I'm confused about this issue since I can definitely see that it's happening for @twistedpixel but I can't reproduce it.

Can any macOS user confirm the issue or confirm the absence of the issue? cc @gverni @tiagostutz @zenflow

Yeah I’m not sure why your Mac isn’t doing it! I’ve seen it now happen on 4 Macs, 2 of which aren’t even mine.

Do you mind downloading Safari Tech Preview, enable Guest mode on your Mac, log in to Guest account and then test the fiddle once more in Tech Preview? I’m just trying to figure out a way that might avoid any conflicts because obviously you’re the best person to witness the bug!

@limonte @twistedpixel I can confirm I can see on my iMac (Catalina 10.15.7) using Safari (14.0). Let me do some investigation and get back to you both

I found an explanation for this _issue_.

First of all is not only connected to the use of esc. Same issue happens if you create a Swal with a timer. So that points to a missing interaction with the modal, rather than the use of a key to close it.

Second, it seems to be linked to the fact that the Swal's <div> is created at the bottom of the page. If you use prependChild() instead of appendChild() in the init() function, the issue is not observed. That also means that you can workaround this issue creating a new element next to the button, and use that as container of the swal, e.g.:

swal.fire({
  title: "TEST",
  input: "text",
  allowEscapeKey: true,
  target: document.getElementById('empty-container')
})

You can see that in action here: https://swal-safary-issue2088.glitch.me/.

Having said that, I suspect that what Safari does when a new element is created and then destroyed without the user interacting with it, is that it moves the focus to the element next to it. In this case since Swal is created to the bottom of the page, it moves the focus to the last element in the page.

I need more time to confirm this Safari behaviour, but with the workaround above, @limonte I don't think there is any need of any change to Swal code (yet).

@twistedpixel can you confirm the workaround works for you?

Thank you @gverni for the thorough investigation!! Safari sometimes is full of surprises!

I need more time to confirm this Safari behaviour

If this behaviour confirmed, it should be reported to the Safari bug tracker.

Indeed @gverni your workaround works, thank you for the help!

We should of course report to Safari bug tracker but perhaps still wise to implement some form of the workaround into SweetAlert2 since Apple is notorious for leaving bugs present for a very, very long time.

My main concern about using the workaround until a potential fix arrives in Safari is that if you have many different instances of SweetAlert2 across many different pages, it is a lot of work to implement the workaround for all of them. For example, I have close to 100 in a very large project I'm working on just now (all quite different). And of course once fixed, all of this workaround code would need to be reversed.

What do you think @limonte? Perhaps switch to prependChild() unless you have a particular reason for the current implementation? I'm happy to help test.

edit: I should also add that just because this thread is very quiet, does not mean that this is not present in many websites of developers who have not yet noticed the issue - not all of us are as diligent in testing cross-browser support.

@twistedpixel the prependChild() is not a proper fix because I suspect safari will likely scroll to the top of the page instead of the bottom. If we want to fix it, we need to find a better way. I have an idea that I want to experiment with. Keep you posted.

@twistedpixel I don't have a workaround / fix yet, but I have a better workaround you can apply to you code and avoid creating a container. The point here is to create a mixin that uses didOpen to change the value of the input (twice).

  function safariFix (popup) {
    let input = popup.getElementsByClassName('swal2-input')
    if (input.length) {
      let prevValue = input[0].value
      input[0].value = ' '
      input[0].value = prevValue
    }
  }

  swalForSafari = swal.mixin({
    didOpen: (popup) => {safariFix(popup)}
  })

    $(document).ready(function() {
        $('body').on('click', '.weirdness-test', function(e) {
      e.preventDefault()
            swalForSafari.fire({
                title: 'TEST',
                input: 'text',
                allowEscapeKey: true,
            })
        })
    })

Have a go and let me know if this is solving (at least temporarily) your issue.

Thank you for the further investigation @gverni!

The point here is to create a mixin that uses didOpen to change the value of the input (twice).

I have no idea why this helps with Safari, but if it does we can consider adding this workaround to the core, somewhere in renderInput.js preferrably.

@limonte I have no idea either, but I discovered that while investigating this _bug_. I haven't finished the investigation, and there may be a bette way of fix it. But since the above workaround is not too complex, I agree I can try to include it in the core. Let me give it a try.

Quick update @limonte, I gave up fixing it in renderInput.js because the workaround works well only with input: text. For the other types, a different character need to be used (and I wasn't able to find the correct one for password).

So I went back to debugging the issue and that's what i found so far. The issue is reproduced when you have all of the following conditions:

  • An external script loaded in the <head> of the page
  • A <div> with role="dialog" and aria-modal="true" within a <div> with absolute position.
  • An <input> inside the above <div>

I created a sample page with no Swal code here: https://nutritious-gem-order.glitch.me. In order to reproduce the issue:

I'll start from here to see if there is a way to fix it. I tried already removing the role and aria-modal from swal, but the issue is still reproduced. So there must be something else. @twistedpixel if you can five a try with the page I sent above, that'd confirm I don't have any _gremlins_ in my safari.

Sorry for the late reply guys.

@gverni Wow, thanks for your thorough investigation. I can confirm that your workaround works great so far (the mixin) and also the page you've asked me to verify is jumping to the bottom after around 2 or 3 seconds even without SWAL code present which is what you're experiencing (so no gremlins).

@limonte Are you still unable to reproduce this bug in any of the examples so far? How odd.

the page you've asked me to verify is jumping to the bottom after around 2 or 3 seconds even without SWAL code present which is what you're experiencing (so no gremlins).

This should be reported to Safari issue-tracker. We might or might not workaround it in SweetAlert2, but it'd be good to report it so Safari devs can decide what to do with it.

@limonte Are you still unable to reproduce this bug in any of the examples so far? How odd.

I haven't tested this one: https://nutritious-gem-order.glitch.me/ will test it in a couple of hours 👍

Thanks again @gverni for the amazing work here!

I haven't tested this one: https://nutritious-gem-order.glitch.me/ will test it in a couple of hours 👍

I am able to reproduce the issue on https://nutritious-gem-order.glitch.me/

Weirdly enough, I'm still unable to reproduce it on https://jsfiddle.net/twistedpixel/e6ktzL51/
Very strange issue!

FYI: still happening in Big Sur (macOS 11.0.1, Safari 14.0.1) in both tests.

Did anyone report to Safari devs? I don't mind doing it, I'm just not sure I fully understand what's happening enough to explain it in a bug report... other than describing it in layman's terms as I did in the OP.

Was this page helpful?
0 / 5 - 0 ratings