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

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

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 25 (15 by maintainers)

Most upvoted comments

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.

@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.

@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.

🎉 This issue has been resolved in version 11.0.14 🎉

The release is available on:

Your semantic-release bot 📦🚀

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?

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

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.