Jump to content

Odd addEventListener() behavior - bug or user error?


jsc
 Share

Recommended Posts

This might be too much of an odd corner case to be of interest to anyone, but it's got me puzzled, so I thought I'd ask here to see if anyone might be able to help.

 

Here's a self-contained example program demonstrating the issue:

 



window.addEventListener("load", function() {
  var context = new (window.AudioContext || window.webkitAudioContext)();
  var request = new XMLHttpRequest();
  request.onload = function() {
    context.decodeAudioData(
      this.response,
      function() {
        console.log("Adding 'touchstart' listener");
        window.addEventListener("touchstart", function() {
          console.log("touchstart");
        }, false);
      }
    );
  };
  request.open("GET", "sound.m4a");
  request.responseType = "arraybuffer";
  request.send();
}, false);


 

The program loads a single sound using Web Audio. Note that in the decodeAudioData() callback, a 'touchstart' event listener is added to the window object. What's puzzling is that in iOS 9, the event listener is never called. Some additional information:

 

- If the listener is added to 'document' rather than 'window', it works.

- If you add a touch listener elsewhere (like at the beginning of the 'load' function), that listener works, and the one added in the decodeAudioData() callback works as well.

- The issue only seems to manifest in iOS 9. In iOS 7, the listener works no matter where you add it.

 

Obviously it's sort of an odd corner case and is easy to work around, but it does make me wonder if I'm doing something wrong somewhere.

 

Does anyone see any problems with the above code? Or does this seem like it might be an iOS bug?

Link to comment
Share on other sites

  • 2 weeks later...

Hmm interesting case. Your code seems legit so looks like some iOS9 safari specific issue. It also works fine in chrome for iOS. Also interesting that if you change some element's property in the decodeAudioData() callback like:

    var el = document.querySelector('.display');    request.onload = function() {        context.decodeAudioData(this.response, function(buffer) {            window.addEventListener("touchstart", function() {                console.log('touchstart');            });            el.style.height = '5px';        });    };

No matter before binding to 'touchestart' or after it starts to work in safari as well... :D

 

EDIT 1:

It also starts to work with your code after you switch screen orientation. So it seems like screen reflow involved here somehow. Anyway if binding to 'touchstart' in exactly this way is critical I think harmles way to overcome this issue is by adding something like this in decodeAudioData callback:

document.body.style.webkitTransform = 'scale(1)';

Hope this helps. GLHF!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...