HTML5 Audio events not triggering on Chrome - javascript

I'm trying to have a load progress bar in my game, and I have a function assigned to the onloadeddata attribute on my audio, but it is not triggering in Chrome. It works in other browsers. I also tried many other events such as oncanplay, oncanplaythrough, onloadedmetadata, etc. None of them trigger.
I think it might have to do with the caching. Tried looking around and there was some reports of this from 2-3 years ago but nothing recent.
Is there any other way I could detect if the audio is loaded, or make these events work?
EDIT: Here's a quick example: http://jsfiddle.net/3vxCu/1/
Works in Opera and Firefox, but not in Chrome. It should give an alert when sound if finished loading.

It seems that the onloadeddata property does not work for some reason. But attaching an event handler through addEventListener (or via jQuery) works: http://jsfiddle.net/3vxCu/4/
bgSound = new Audio();
bgSound.src = "http://www.ehsankia.com/hawkthorne/audio/level.ogg";
bgSound.preload = "auto";
// Standard browsers (not IE before version 9):
// bgSound.addEventListener("loadeddata", testFunction, false);
// jQuery:
$(bgSound).on("loadeddata", testFunction);
function testFunction () {
alert("Data loaded");
}

If the attached jsfiddle is how you have implemented your code then I think I know what is wrong.
Your jsfiddle shows:
bgSound = document.createElement('audio');
bgSound.src = "http://www.ehsankia.com/hawkthorne/audio/level.ogg";
bgSound.onloadeddata = testFunction;
function testFunction(){
alert("Data loaded");
}
It should be like this:
bgSound = document.createElement('audio');
bgSound.onloadeddata = testFunction; // Event listener is attached _before_ loading the resource
bgSound.src = "http://www.ehsankia.com/hawkthorne/audio/level.ogg";
function testFunction(){
alert("Data loaded");
}
Basically, you are attaching the event listener after the src is specified. Specifying the source should be the last thing you do since it sets everything in motion. Chrome is probably already past the point of calling listeners for that event by the time it is attached in your code.

Related

Why does jQuery on('load', function(){}); not fire if the the image loads before the load is bound? IE and Localhost

The following code works just fine on a server, but when I pull it to my local environment (localhost) or on IE the load doesn't fire.
$(document).ready(function (){
$('#img').on('load', function(){
//do something
});
};
I solved the problem on IE by browser detection and the following code, but I'd like to use the same code for all browsers.
var firstBannerImgSrc = $('#img').attr('src');
var firstBannerImg = new Image();
firstBannerImg.src = firstBannerImgSrc;
firstBannerImg.onload = function(){
//do something
};
Can anyone see the problem?
You should stop the browser detecting and just use that same technique for all browsers since it is the safest of the two to use.
$(document).ready(function (){
var $img = $("#img"),
img = new Image();
$(img).on('load', function(){
$img.doSomething();
}).attr('src', $img.attr('src'));
});
If the image is done loading before you bind the event, it makes perfect sense for the event handler to not get executed because an event never happened once the event was bound to. The above code avoids that issue in all browsers, where as your solution would only avoid the issue if the image wasn't already cached (due to yet another IE bug) and hadn't already finished loading (which will happen in browsers that don't properly implement DOMContentLoaded such as oldIE.)

Javascript pauses on iPad when changing tab: is there a way to know when coming back?

I've the same problem depicted in iOS 5 pauses JavaScript when tab is not active thread.
My question is if I can be noticed when come back to the paused tab.
onfocus and onblur events don't work on to the to be paused tab.
The code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://code.jquery.com/jquery-1.7.1.min.js" ></script>
<script type="text/javascript">
window.onblur = function () {
console.log("blur");
$("#whatevent").append("blur<br/>");
}
window.onfocus = function () {
console.log("focus");
$("#whatevent").append("focus<br/>");
}
window.onunload = function () {
console.log("unload");
$("#whatevent").append("unload<br/>");
}
window.onload = function () {
console.log("load");
$("#whatevent").append("load<br/>");
}
</script>
</head>
<body>
<div id="whatevent"></div>
</body>
</html>
none but onload (but only the first time I load the page) events works on iPad when I switch tab.
Someone posed this very question over two years ago with this query. Unfortunately, it was met with only a couple of answers, one of which seems to be the only method to achieve this effect. Until Apple can implement the full Page Visibility API in mobile safari, I'm left with using this custom object I created that will use the API and fall back to a heart beat ticker if it's unavailable. However, as far as I can tell, there is no great way to check an imminent tab switch.
Here's a basic fiddle of the object demonstrating its only real method. It essentially just accepts a handler function for a focus event that gets fired whenever the browser returns the source tab. The fallback is hacky at best and will fire not just on a page re-entry but whenever scripting stops for longer than the timer threshold; which could be whenever the keyboard is visible, on scroll, or if a running script prevents the requestAnimationFrame from firing. Since scrolling is the most common behavior, I've added a handler that resets the last saved time so that the focus event refrains from firing.
This is the main portion of the script that includes the "hacky" method as described above:
_that.onFocus = function(handler, params) {
var hiddenProp = getHiddenProp();
console.log("Hidden prop: " + hiddenProp);
if (hiddenProp) {
var evtName = hiddenProp.replace(/[H|h]idden/, "") + "visibilitychange";
document.addEventListener(evtName, function(e) {
if (isHidden()) {
handler(e, params);
}
}, false);
}else {
var handlerObj = {"handler": handler};
if (params !== undefined) {handlerObj.params = params}
_handlers.push(handlerObj);
startLoop();
}
};
The rest may be read in the fiddle. In order to see the fallback you'll have to use a tablet (why else would you be needing this function without one?).
Note that the .onFocus method may accept an array of params for its second param that it will then pass to your event handler. This means that your event handler will always have an event object for it's first param (or null if the API is not supported) and your array of params as its second param.
Also not that this code has been tested for all of a couple hours so it may be prone to glitchiness. I would appreciate any constructive criticism to make it production worthy until Mobile Safari gets its butt in gear.

What event name use in Opera's userJS to trigger a function when page finished loading and has downloaded all its assets like img,script,css etc.?

This is my code:
document.addEventListener('load', function () {
alert(document.getElementsByTagName("DIV").length);
}, false);
//'load' event above doesn't show any response, alert isn't showing
alert(document.getElementsByTagName("DIV").length);
// this alert returns 0 it looks like it is called before the page DOM has loaded
window.onload = function() {
alert(document.getElementsByTagName("DIV").length);
};
//returns 0, what the... it seems DOM hasn't loaded also
// but only on some sites, here on stackoverflow and youtube it works,
//but on google.com and many other websites (pcworld.com) shows 0
The same situation in latest stable and alpha Operas.
I suggest you simply do
window.addEventListener('load', function(){}, false)
like you would in a normal script. You could use opera.addEventListener('BeforeEvent.load', ...) but that might not fire if the page's scripts do not listen for load events in some Opera versions.
Some other background reading:
window.onload vs document.onload
addEventListener("input", callback) doesn't work in opera?

ExternalInterface.addCallback doesn't work on firefox?

i'm trying to call a method inside a flash movie from js, every time the mouse leaves the "div".
It works on Internet Explorer, but not in firefox. any ideas?
here is the html script:
<script type="text/javascript">
window.onload = function(e){
init();
}
function init(){
document.getElementById('div').onmouseout = function(e) {
method();
}
}
function method(){
flashid.anothermethod();
}
</script>
and the flash script:
import flash.external.ExternalInterface;
function outdiv(){
//do something;
}
ExternalInterface.addCallback('anothermethod', outdiv);
Any ideas what's wrong?
EDIT: here is example of the problem, there is an alert for the js and the flash should be able to remove the swf (see a gray background? it works! see a image, flash didn't receive the call):
http://complexresponse.com/out/addcallback_ff.html
this should work with internet explorer / safari / chrome (pc/mac) only firefox seams to reject this.
the problem is that the event probably doesn't fire because of the flash. try to handle the mouseout event in the flash on your main movieclip and see if it fires
Ensure that you're embedding flash with wmode set to "transparent". If not you won't get JavaScript events for DOM objects behind the flash object.

img onload doesn't work well in IE7

I have an img tag in my webapp that uses the onload handler to resize the image:
<img onLoad="SizeImage(this);" src="foo" >
This works fine in Firefox 3, but fails in IE7 because the image object being passed to the SizeImage() function has a width and height of 0 for some reason -- maybe IE calls the function before it finishes loading?. In researching this, I have discovered that other people have had this same problem with IE. I have also discovered that this isn't valid HTML 4. This is our doctype, so I don't know if it's valid or not:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Is there a reasonable solution for resizing an image as it is loaded, preferably one that is standards-compliant? The image is being used for the user to upload a photo of themselves, which can be nearly any size, and we want to display it at a maximum of 150x150. If your solution is to resize the image server-side on upload, I know that is the correct solution, but I am forbidden from implementing it :( It must be done client side, and it must be done on display.
Thanks.
Edit: Due to the structure of our app, it is impractical (bordering on impossible) to run this script in the document's onload. I can only reasonably edit the image tag and the code near it (for instance I could add a <script> right below it). Also, we already have Prototype and EXT JS libraries... management would prefer to not have to add another (some answers have suggested jQuery). If this can be solved using those frameworks, that would be great.
Edit 2: Unfortunately, we must support Firefox 3, IE 6 and IE 7. It is desirable to support all Webkit-based browsers as well, but as our site doesn't currently support them, we can tolerate solutions that only work in the Big 3.
If you don't have to support IE 6, you can just use this CSS.
yourImageSelector {
max-width: 150px;
max-height: 150px;
}
IE7 is trying to resize the image before the DOM tree is fully rendered. You need to run it on document.onload... you'll just need to make sure your function can handle being passed a reference to the element that isn't "this."
Alternatively... and I hope this isn't a flameable offense... jQuery makes stuff like this really, really easy.
EDIT in response to EDIT 1:
You can put document.onload(runFunction); in any script tag, anywhere in the body. it will still wait until the document is loaded to run the function.
I've noticed that Firefox and Safari both fire "load" events on new images no matter what, but IE 6&7 only fire "load" if they actually have to get the image from the server -- they don't if the image is already in local cache. I played with two solutions:
1) Give the image a unique http argument every time, that the web server ignores, like
<img src="mypicture.jpg?keepfresh=12345" />
This has the downside that it actually defeats caching, so you're wasting bandwidth. But it might solve the problem without having to screw with your JavaScript.
2) In my app, the images that need load handlers are being inserted dynamically by JavaScript. Instead of just appending the image, then building a handler, I use this code, which is tested good in Safari, FF, and IE6 & 7.
document.body.appendChild(newPicture);
if(newPicture.complete){
doStuff.apply(newPicture);
}else{
YAHOO.util.Event.addListener(newPicture, "load", doStuff);
}
I'm using YUI (obviously) but you can attache the handler using whatever works in your framework. The function doStuff expects to run with this attached to the affected IMG element, that's why I call it in the .apply style, your mileage may vary.
Code for jQuery. But it's easy to make dial with other frameworks. Really helpful.
var onload = function(){ /** your awesome onload method **/ };
var img = new Image();
img.src = 'test.png';
// IE 7 workarond
if($.browser.version.substr(0,1) == 7){
function testImg(){
if(img.complete != null && img.complete == true){
onload();
return;
}
setTimeout(testImg, 1000);
}
setTimeout(testImg, 1000);
}else{
img.onload = onload
}
The way I would do it is to use jQuery to do something like:
$(document).load(function(){
// applies to all images, could be replaced
//by img.resize to resize all images with class="resize"
$('img').each(function(){
// sizing code here
});
});
But I'm no javascript expert ;)
setTimeout() may be a workaround if you are really stuck. Just set it for 2 or 3 seconds - or after the page is expected to load.
EDIT: You may want to have a look at this article - all the way at the bottom about IE mem leaks...
Edit: Due to the structure of our app,
it is impractical (bordering on
impossible) to run this script in the
document's onload.
It is always possible to add handlers to window.onload (or any event really), even if other frameworks, library or code attaches handlers to that event.
<script type="text/javascript">
function addOnloadHandler(func) {
if (window.onload) {
var windowOnload = window.onload;
window.onload = function(evt) {
windowOnload(evt);
func(evt);
}
} else {
window.onload = function(evt) {
func(evt);
}
}
}
// attach a handler to window.onload as you normally might
window.onload = function() { alert('Watch'); };
// demonstrate that you can now attach as many other handlers
// to the onload event as you want
addOnloadHandler(function() { alert('as'); });
addOnloadHandler(function() { alert('window.onload'); });
addOnloadHandler(function() { alert('runs'); });
addOnloadHandler(function() { alert('as'); });
addOnloadHandler(function() { alert('many'); });
addOnloadHandler(function() { alert('handlers'); });
addOnloadHandler(function() { alert('as'); });
addOnloadHandler(function() { alert('you'); });
addOnloadHandler(function() { alert('want.'); });
</script>
This answer has a slightly different version of my addOnloadHandler() code using attachEvent. But I discovered in testing that attachEvent doesn't seem to guarantee the handlers fire in the order you added them, which may be important. The function as presented guarantees handlers are fired in the order added.
Note that I pass evt into the added event handlers. This is not strictly necessary and the code should work without it, but I work with a library that expects the event to be passed to the onload handler and that code fails unless I include it in my function.
You can do something like :
var img = new Image();
img.src = '/output/preview_image.jpg' + '?' + Math.random();
img.onload = function() {
alert('pass')
}

Categories

Resources