THE QUESTION
Interesting one that probably has a simple solution. With the help of #jessegavin I've added a jQuery function to my page that controls the playback of HTML5 audio elements on the page. The code is beautiful and works correctly on a jsFiddle, but not when put into the context of my page.
I've thrown time to the wind and methodically stepped through this to try and isolate my mistake, but with no avail. Really, I went Aristotle on this one and applied the scientific method. Please forgive me for the heft of this question. It's really my last resort.
THE NITTY GRITTY
Here are my findings: All the JavaScript functions for the page work correctly in context of the jsFiddle. After specifically adding the functions one at a time I can say that they each work appropriately, and that all except for the HTML5 audio playback work on both the jsFiddle and the live page. That is to say ONLY the HTML5 audio playback is not working on the live page.
All the HTML is 100% validated, all the CSS is 100% validated. Both groups are code are added into the jsFiddle in their entirety.
The page heading loads (in this order) an external CSS document, jQuery 1.5.1 and jQuery UI 1.8.8 (same on jsFiddle, except for UI, which is 1.8.9) via Google's onload command, an external JavaScript document (where ALL functions for the site reside), and finally a Google Analytics function.
The JavaScript is wrapped in a document ready framework.
My guess is that the discrepancy lies somewhere in the head, but I cant imagine what exactly it is. All the external links work correctly, evidenced by the JavaScript functions working correctly (except for the new audio controller).
THE POST SCRIPT
P.S.- Only works in Chrome and Safari as of yet.. The server I'm hosting the two audio files off of doesn't have the correct ht-access file declaring OGG as a correct MIME type. I'll start a question for that too.
RESOURCES
jsFiddle: http://jsfiddle.net/66FwR/3/
HTML (heading only, body is in jsFiddle)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8>
<meta name="description" content="Fernando Garibay- Producer, Songwriter, Artist, Multi-Instrumentalist, and Programmer" />
<meta name="keywords" content="Fernando Garibay, Music, Producer, Songwriter, Artist, Mutli-Instrumentalist, Programmer." />
<title>Fernando Garibay - Music</title>
<link rel="icon" type="image/png" href="http://www.fernandogaribay.com/favicon.ico" />
<link href="../styles/fernando.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="https://www.google.com/jsapi?key=ABQIAAAAqfg-jHFfaMB9PWES0K_8ChTCwkclEZER8BG2IP57SKkFV1O9hxSZkzKYPDs-3mbhEluKXjbKUAB7sQ"></script>
<script type="text/javascript">
google.load("jquery", "1.5.1");
google.load("jqueryui", "1.8.8");
</script>
<script type="text/javascript" src="../scripts/fernando.js"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<!--Copyright 2011, Fernando Garibay, Inc-->
<!--Developed by Minimal +-->
</head>
<body onload="message()">
JavaScript (the function that works on jsFiddle, but not in a live page)
$(function() {
$(".playback").click(function(e) {
e.preventDefault();
var song = $(this).next('audio').get(0);
if (song.paused)
song.play();
else
song.pause();
});
});
I see two JavaScript errors on your live page (in both Chrome and Firefox):
Uncaught TypeError: Object [object Object] has no method 'fancybox'
Uncaught ReferenceError: message is not defined
You reference fancybox() in fernando.js, and message in the <body onload="message()">. Those errors are most likely stopping your audio control code from running.
The URL is http://fiddle.jshell.net/66FwR/3/show/ look at that.
It includes jQuery UI too. You could copy the source and use that.
Related
I have intergrated a third party code into my website, and suddenly the setTimeout and setInterval stopped working: Before the third party is loaded, everything works fine. setTimeout and setInterval that were scheduled to run after the third party is loaded, do not dun at all.
After removing the 3rd party code snippet they supplied, everything work.
My question is - how can it be? what can the third pary do that can stop my schedules?
I renamed any pointers to the returned value of the setTimeout function; I tried to play with the place where I put the snippet and / or the setTimeout code.
Nothing work.
It doesn't make any sense. and I don't know how to start debugging it.
Here is a simplified html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>My Demo</title>
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico"/>
<!--<link href="css/style.css" rel="stylesheet" type="text/css">-->
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body>
<script>
<!-- the alert pops up only when I remove the 3rd party snippet -->
setTimeout(function(){
alert("done");
}, 5000);
</script>
<!-- This is the 3rd party code -->
<script type="text/javascript">
var $P; var prefix = ('https:' == document.location.protocol ? 'https://' : 'http://'); var _P = _P || [];
_P.push(['setId', '123']);
var PPP = document.createElement('script');
PPP.type = 'text/javascript'; PPP.src = prefix + 'thethirdpartyIuse.com/functions.js';
var s = document.getElementsByTagName('script');
var lastScriptTag = s[s.length - 1];
lastScriptTag.parentNode.insertBefore(PPP, lastScriptTag);
</script>
</body>
</html>
Any help & guideness is appriciated!
Are you sure? It works fine in liveweave: http://liveweave.com/OKMyjs
And indeed you should wrap your code in:
window.onload = function() {
//your stuff
}
May be the external code redefines alert as something else. To see if this is the issue try changing your code to:
(function(myalert){
setTimeout(function(){
myalert("done");
}, 5000);
})(alert);
If this doesn't work the only reason I can think to is that the external script goes into an infinite loop. Functions registered with setTimeout will be executed once the Javascript event loop starts after the synchronous execution of script tags in the page and this may never happen if any toplevel stript hangs.
You should however see in this case the loading is taking forever (loading animation in the browser) and after long enough the browser should signal that there is a problem loading the page.
Something redefines your alert function.
Possible solutions:
wrap your code in (function(alert) { /* your code */ }(alert))
Object.defineProperty(window, 'alert', { configurable: false, enumerable: true, value: alert, writable: false }); to protect your alert from redefining.
do not rely on alert (in 99% of cases modal or console.log are superior solutions - alert, prompt and confirm are three functions blocking code execution in JavaScript).
After a lot of debugging, I found the probelm:
The 3rd party did setTimeout(true)for some reason (I assume by mistake).
In chrome, it cancel all schedules (setTimeout & setInterva).
I report the problem.
I am trying to add a Google Plus button to my site, and keep getting JavaScript safety warnings, despite the fact that I am using Google's recommended code, on Chrome.
I have reproduced the errors with code copied straight from Google Webmaster's recommended code, with no other additions:
<html itemscope itemtype="http://schema.org/">
<head>
<meta itemprop="name" content="Title">
<meta itemprop="description" content="Description">
</head>
<body>
<g:plusone annotation="inline"></g:plusone>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')\[0\]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
Load this in Chrome (15 on Mac), and the developer console warns:
Unsafe JavaScript attempt to access frame with URL http://mydomain.com/
from frame with URL https://plusone.google.com/_/+1/fastbutton?url=http%3A%2F%2Fmydomain.com%2F&size=standard&count=true&annotation=inline&hl=en-US&jsh=m%3B%2F_%2Fapps-static%2F_%2Fjs%2Fwidget%2F__features__%2Frt%3Dj%2Fver%3Dt6mt7PFQYRQ.en_GB.%2Fsv%3D1%2Fam%3D!agWx4Vf_ACSIFA91ZQ%2Fd%3D1%2F#id=I1_1323174311773&parent=http%3A%2F%2Fmydomain.com&rpctoken=352111652&_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe.
Domains, protocols and ports must match.
Is the Google Webmaster recommended code simply unsafe? Or have I done something wrong?
This is a common warning thrown by social plugins. Twitter and Facebook plugins usually throw this warning too. You can safely ignore it.
I'm playing around with the new Google +1 button and I've attempted to set up a simple demo of it.
This is my code:
<html>
<head>
<title>Plus One</title>
</head>
<body>
<!-- Place this tag where you want the +1 button to render -->
<g:plusone callback="plus_one_callback" href="http://www.testurl.com/"></g:plusone>
<!-- Place this tag after the last plusone tag -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
function plus_one_callback(){
alert('callback');
}
</script>
</body>
</html>
However it does not render the button and there is no error message in my console.
Here is a screengrab of my firebug net panel:
Anyone know why this happens?
It won't work because as of Firefox 3 you can't run external JS scripts locally. Or to be more exact, you'll run into problems when firefox sees "file://" in the url. This question was also answered here. It probably would work if you used another browser.
If you really need this kind of stuff to work locally, however, there is a solution. You can install WAMP or XAMPP to run a local server.
I'm working on a single page app that will probably fire more than 1 conversion per pageload.
I need to fire the google conversion snippet, so I assumed that I could throw it in at run time. The snippet looks something like this:
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = XXXXXXXX;
var google_conversion_language = "en";
var google_conversion_format = "2";
var google_conversion_color = "ffffff";
var google_conversion_label = "XXXXXXXXXXXXXXX";
var google_conversion_value = 25.00;
/* ]]> */
</script>
<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion.js">
</script>
I have been using javascript to insert the snippet when a conversion has fired. I'm doing it like this:
function(id,url,content){
// add script
var script = document.createElement("script");
script.type = "text/javascript";
if(url) script.src = url;
if(content) script.text = content;
var bucket = document.getElementById(id);
bucket.appendChild(script);
debugger;
}
This works in all the browsers I've tried it in, except safari.
In safari, when the 2nd script tag is added, the entire body tag's content is replaced with a google iFrame. The whole dom is nuked in fact. The head's content is wiped out as well.
What the hell is happening in that google script, and how do I insert this without everything blowing up?!?
Update:
Looks like for some reason safari didn't like the way I was adding the script. To fix this, I added bucket.innerHTML = '' below the debugger line and it worked great in Safari. Unfortunately, that caused FF 3.6 to do what safari was previously doing and nuke the DOM.
To make it even more complicated, it seems AdWords was rejecting these conversions or something, they don't show up on the reporting end when injected to the page.
My current approach is to use htaccess and a little string parsing to generate a page with nothing but the conversion snippet on it, and iFrame it in. I'll report back on that.
Perhaps it might be easier to insert the Google Ads via an iFrame?
Such as like this:
<iframe src="/documents/adsense.htm" width="728px" height="90px" frameborder="0" marginwidth ="0px" marginheight="0px" scrolling="no"></iframe>
iFrame contains:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Google Adsense</title>
<base target="_parent">
</head>
<body>
<!--insert Google Adsense Code Here-->
</body>
</html>
Google will still know and track the parent page.
The below piece of code was working in IE6 & IE7 and almost all versions of FF. It just don't work in IE8. It doesn't work in the sense once I added the script tag in to HTML->HEAD element I don't see the script being loaded in the browser(the alerts in the script doesn't show up). I see the tags have been inserted in the HTML-HEAD though.
var head = document getElementsByTagName('head')[0];
// Check if the script is already loaded.
if (head ){
var script = document.createElement('script');
script.type = 'text/javascript';
script.language = 'JavaScript';
script.src = '/Tolven/scripts/' + jsFileName;
head.appendChild(script);
}
Does anybody have this issue? Or any clues to resolve this?
If this script is in <head> tag than head does not exists when this script is parsed and executed. So, of cource if (head) is false.
Your are using JS framework -- so feel free to use it's tools. And also do not forget to include Your framework, before using it.
<!-- if your are using mootools -->
<script type="text/javascript" src="mootools.js"></script>
<script type="text/javascript">
window.addEvent('domready', function() {
// Your code...
});
</script>
<!-- if your are using prototype -->
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
document.observe("dom:loaded", function() {
// Your code...
});
</script>
Consider using a library like RequireJS or LABjs that do the job of including scripts at runtime really well.
var head = document getElementsByTagName('head')[0];
should be
var head = document.getElementsByTagName('head')[0];
Script seems to work after this modification.
This is was actually working. There is was an error(it only happens in IE8) in one of the scripts that's inserted at runtime. Eventually it's not executing alerts in the pages loaded next. Thanks for your answers though.