Jquery functionality not working when opening the page via AJAX. - javascript

I am trying to open a HTML page with jquery functionality in it via AJAX.
The page I am trying to open is:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Slick Slide Up and Down Thumbnail Effect with jQuery</title>
<script type="text/javascript" src="../scripts/jquery-1.3.1.min.js"></script>
<script type="text/javascript" src="../scripts/jquery.easing.1.3.js"></script>
<script>
$(document).ready(function () {
// transition effect
style = 'easeOutQuart';
// if the mouse hover the image
$('.photo').hover(
function() {
//display heading and caption
$(this).children('div:first').stop(false,true).animate({top:0},{duration:200, easing: style});
$(this).children('div:last').stop(false,true).animate({bottom:0},{duration:200, easing: style});
},
function() {
//hide heading and caption
$(this).children('div:first').stop(false,true).animate({top:-50},{duration:200, easing: style});
$(this).children('div:last').stop(false,true).animate({bottom:-50},{duration:200, easing: style});
}
);
});
</script>
<style>.photo{position:relative;font-family:arial;overflow:hidden;border:5px solid #000;width:350px;height:233px;}.photo .heading,.photo .caption{position:absolute;background:#000;height:50px;width:350px;opacity:0.6;}.photo .heading{top:-50px;}.photo .caption{bottom:-50px;left:0px;}.photo .heading span{color:#26c3e5;top:-50px;font-weight:bold;display:block;padding:5px 0 0 10px;}.photo .caption span{color:#999;font-size:9px;display:block;padding:5px 10px 0 10px;}</style>
</head>
<body>
<div class="photo">
<div class="heading"><span>Telephoto Lens</span></div>
<img src="images/fall.jpg" width="350" height="233" alt=""/>
</body>
</html>
And the index.html page that is open this page via ajax has the code:
<script language="JavaScript" type="text/javascript">
//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest(); //Not IE
} else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP"); //IE
} else {
//Display your error message here.
alert("Your browser doesn't support the XmlHttpRequest object. Better upgrade.");
}
}
//Get our browser specific XmlHttpRequest object.
var receiveReq = getXmlHttpRequestObject();
//Initiate the asyncronous request.
function init(){
sayHello(1);
}
window.onload=init;
function sayHello(x) {
//If our XmlHttpRequest object is not in the middle of a request, start the new asyncronous call.
if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
receiveReq.open("GET", 'pages/mobile.html', true);
//Set the function that will be called when the XmlHttpRequest objects state changes.
receiveReq.onreadystatechange = handleSayHello;
//Make the actual request.
receiveReq.send(null);
}
}
//Called every time our XmlHttpRequest objects state changes.
function handleSayHello() {
//Check to see if the XmlHttpRequests state is finished.
if (receiveReq.readyState == 4) {
document.getElementById('span_result').innerHTML = receiveReq.responseText;
}
}
And the HTML part for you to look at:
<div id="nav">
<table class="nav">
<tr><th>&nbsp</th></tr>
<tr><td id="selected">Distinguished Techonologist Program</td></tr>
<tr><td>Mobile Solution</</td></tr>
<tr><td>HTML5 Canvas</td></tr>
<tr><td>Doamin Expertise</td></tr>
</table>
</div>
<div id="carousel">
<span id="span_result"></span>
</div>
Kindly help..
Thanks in advance
Regards
Zeeshan

Scripts introduced by innerHTML won't be executed. You should use DOM methods, createElement, appendChild, to build the page. A simple example:
script = document.createTextNode("alert('Run')");
tag = document.createElement('script');
tag.appendChild(script);
div.appendChild(tag);

Related

Periodic refresh of a book's dynamic pages using turn.js

I have created an example of dynamically generated content to be viewed using turn.js using the sample provided here.
This is the part of the code that I have so far:
<body>
<div id="paper">
</div>
</body>
<script type="text/javascript">
$(window).ready(function() {
$('#paper').turn({pages: 12});
});
$('#paper').bind('turning', function(e, page) {
var range = $(this).turn('range', page);
for (page = range[0]; page<=range[1]; page++)
addPage(page, $(this));
});
function addPage(page, book) {
// Check if the page is not in the book
if (!book.turn('hasPage', page)) {
// Create an element for this page
var element = $('<div />').html('Loading…');
// Add the page
book.turn('addPage', element, page);
// Get the data for this page
$.ajax({url: "getPage?filename=abcd&page="+page})
.done(function(data) {
element.html(data);
});
}
}
</script>
getPage is a jsp that returns <div class="page"><img src="docs/local/abcd_1.png" alt="" /></div> or any other page number as per the ajax request.
The problem I have is that the png's requested may or may not be available on the web server at the time of the request. They will become available a few (or sometimes many) seconds later. So I would like to be able to display some default "Loading..." type content if a png is not available and refresh periodically (i.e. every x seconds) until the actual png becomes available. I don't have a problem changing the output of getPage if required.
I have managed to make this work myself by proceeding with the following changes:
getPage now returns <div class="loader"><img src="docs/local/ajax-loader.gif" alt="" /></div> if the png requested is not available.
In the calling page I have changed my code to check for the 'loader' string, and if found (which means the png is unavailable), then I call setTimeout, to retry getting the image after a given amount of time:
<body>
<div id="paper">
</div>
</body>
<script type="text/javascript">
$(window).ready(function() {
$('#paper').turn({pages: <s:property value='pages'/>});
});
$('#paper').bind('turning', function(e, page) {
var range = $(this).turn('range', page);
for (page = range[0]; page<=range[1]; page++)
addPage(page, $(this));
});
function addPage(page, book) {
// Check if the page is not in the book
if (!book.turn('hasPage', page)) {
// Create an element for this page
var element = $('<div />').html('Loading…');
// Add the page
book.turn('addPage', element, page);
// Get the data for this page
refreshPage(element,page);
}
}
function refreshPage( element, page )
{
$.ajax({url: "getPage?filename=<s:property value='filename'/>&page="+page})
.done(function(data) {
if( data.indexOf( "loader") > -1 )
{
setTimeout(function() {
refreshPage(element,page);
}, 5000);
}
element.html(data);
});
}
Maybe there is a better way to achieve this but at least it works.

An Iframe Inside Iframe. Can this be done?

We have a video (vimeo) link we would like our users to watch.
Each video is followed by a short questionnaire.
Our intent is to not make the questionnaire visible to the user until the user had clicked open the video for viewing.
I can only think of embedding the code below inside another iframe just to hide the link.
Is this possible?
Is there an alternative approach to this?
<!DOCTYPE HTML>
<html>
<head>
<meta name="google" value="notranslate" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Dog Smoking</title>
<style type="text/css">
body {
padding-top:0;
padding-bottom:0;
padding-left:0;
padding-right:0;
margin-top:0;
margin-bottom:0;
margin-left:0;
margin-right:0;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="javascript/froogaloop.js"></script>
<script src="javascript/froogaloop.min.js"></script>
<script type="text/javascript">
var iframe = $('#player1')[0],
player = $f(iframe),
status = $('.status');
// When the player is ready, add listeners for pause, finish, and playProgress
player.addEvent('ready', function() {
status.text('ready');
player.addEvent('pause', onPause);
player.addEvent('finish', onFinish);
player.addEvent('playProgress', onPlayProgress);
});
// Call the API when a button is pressed
$('button').bind('click', function() {
player.api($(this).text().toLowerCase());
});
function onPause(id) {
status.text('paused');
}
function onFinish(id) {
status.text('finished');
}
function onPlayProgress(data, id) {
status.text(data.seconds + 's played');
}
player.addEvent('ready', function() {
status.text('ready');
$("#survey_button").show(); // <-- or whatever
});
</script>
</head>
<body>
<iframe src="http://player.vimeo.com/video/4644119?api=1" width="400" height="375" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<a href="http://show.aspx?testid=27#activate"
target="target-iframe"
onclick="frames['target-iframe'].document.getElementById('activate')
.scrollIntoView();return false">Click</a>
</body>
</html>
I would use the JS API for video and use the event callbacks built into the player to make the questionnaire visible.
==UPDATE==
Ok - so that link is a step by step example of how to incorporate the JS controls and callbacks for the player. But... here we go..
step 1 is to add the "?api=1" after your initial embed code.
step 2 is to load their Froogaloop library so you can listen for events...
step 3 would be to set up a callback to handle whatever event you want to listen to... The example right from this page is fantastic:
var iframe = $('#player1')[0],
player = $f(iframe),
status = $('.status');
// When the player is ready, add listeners for pause, finish, and playProgress
player.addEvent('ready', function() {
status.text('ready');
player.addEvent('pause', onPause);
player.addEvent('finish', onFinish);
player.addEvent('playProgress', onPlayProgress);
});
// Call the API when a button is pressed
$('button').bind('click', function() {
player.api($(this).text().toLowerCase());
});
function onPause(id) {
status.text('paused');
}
function onFinish(id) {
status.text('finished');
}
function onPlayProgress(data, id) {
status.text(data.seconds + 's played');
}
So, depending on when you want your survey to show, you can just tap into one of those...
player.addEvent('ready', function() {
status.text('ready');
$("#survey_button").show(); // <-- or whatever
});
make sense?
============= ANOTHER UPDATE ================
here's a working fiddle: http://jsfiddle.net/QkGRd/10/. You may want to read a bit about embedding resources and how the jsfiddle works as well.
TL;DR Answer
Yes you can have an iframe inside an iframe. Though it's generally not a good idea in terms of performance.

how to know the webpage is loaded

i have a iframe and i am redirecting pages in iframe.
how to get the event for each page loading finish.
main.html
<html>
<body>
<iframe src="http://www.child.html" id="childframe" style="height:100px"></iframe>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(window).load(function(){
var Body = $("#childframe").contents().find("body");
var Element = Body.find("tag");
// page is redirecting to new page
$(Element[0].click());
window.setTimeout(reallyNext, 1000);
function reallyNext() {
//how to know inner page is loaded
var result= Body.find("#tag1");
//how to get element from anotherpage.html
$(result).bind('DOMSubtreeModified', function(event) {
//how to reach here
});
}
});
</script>
</body>
</html>
child.html
<html>
<head></head>
<body>
<p><br></p>
</body>
</html>
please tell me how to know the inner page of iframe has done loading?
You can use the onload paremeter inside the body tag, which runs after the page is loaded.
For example:
<body onload="myJavascriptFunction();" >
$('#childframe').ready(function() {
...
});
or
$('#childframe').load(function() {
...
});
<script language="javascript">
iframe = document.getElementById("frameid");
WaitForIFrame();
function WaitForIFrame() {
if (iframe.readyState != "complete") {
setTimeout("WaitForIFrame();", 200);
} else {
done();
}
}
function done() {
//some code after iframe has been loaded
}
</script>
This should work
You can hook on the onLoad javascript event of the <iframe /> element (like <iframe onLoad="myHandler" />, where myHandler is your js function), or, if using jQuery, with the following snippet:
$('#childframe').load(function() {
// your code handling the iframe loaded.
});
Note, that your code needs to be part of the page that holds the iframe not the page within it.

JWPlayer handle youtube errors

I would like to handle the youtube errors in the JWPlayer, so in case the video doesn't exists or is not available for the country show a message on the player, or with javascript, i am doing something like this...
var options = {
height: 330,
},
flashplayer: '/player.swf',
width: 560,
events:{
onError:function(obj){
alert('ERROR'+obj);
}
} ,
debug: 'console'
};
jwplayer("player").setup(options);
jwplayer("player").play();
but its not getting inside from the onError event, even though the video doesnt even exist... and i can see in the console.. LOG (Error loading preview image: Error #2036)
In the case of youtubes restriction country i cannot even see that in the console.
In any case the video just show the loading animation, which it makes belieave the user that it can be load in any time, which its not true.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<script type="text/javascript" src="#{facesContext.externalContext.requestContextPath}/assets/jwplayer.min.js"></script>
<script type="text/javascript" src="#{facesContext.externalContext.requestContextPath}/assets/swfobject.js"></script>
<div id="player"></div>
</body>
<script type="text/javascript">
//<![CDATA[
window.onload=createPlayer();
function createPlayer() {
var flashvars = {
file:"http://www.youtube.com/watch?v=pnEHsUWFuNM",
autostart:"true"
}
var params = {
allowfullscreen:"true",
allowscriptaccess:"always"
}
var attributes = {
id:"player1",
name:"player1"
}
swfobject.embedSWF("#{facesContext.externalContext.requestContextPath}/assets/player.swf", "player", "320", "196", "9.0.115", false, flashvars, params, attributes);
}
function loadPlayer() {
var options = {
height: 325,
flashplayer: '#{facesContext.externalContext.requestContextPath}/assets/player.swf',
width: 560,
events:{
onError:function(error){
alert('Error loading your link, please try another one');
}
} /* ,
debug: 'console'*/
};
options.file = 'http://www.youtube.com/watch?v=pnEHsUWFuNM';
options.events.onReady= function(){
jwplayer("player").play();
};
jwplayer("player").setup(options);
}
//]]>
</script>
loadPlayer to try with jwplayer.js and the createPlayer directly from SWFObject... that video exist just that it shouldnt be shown in germany, still its trying to load it.
and if i set any other unexisting URL let say "http://www.youtube.com/watch?v=ABC" still keeps trying to load the unexisting video.
It looks like JW5 doesn't support catching YouTube errors. However, the following setup with JW6 works:
<!DOCTYPE html>
<html>
<head>
<title>YouTube Test Page</title>
<script type="text/javascript" src="http://www.longtailvideo.com/jwplayer/jwplayer.js"></script>
</head>
<body>
<div id="player"></div>
<script type="text/javascript">
jwplayer("player").setup({
file: "https://www.youtube.com/watch?v=ABCD",
events:{
onError: function() {
jwplayer().load({file: "http://content.longtailvideo.com/videos/flvplayer.flv",duration: "27"});jwplayer().play()
}
}
});
</script>
</body>
</html>

Using Youtube's javascript API with jQuery

I'm currently trying to use the YouTube API as part of a jQuery plugin and I've run into a bit of a problem.
The way the YT api works is that you load the flash player and, when it's ready it will send a call back to a global function called onYouTubePlayerReady(playerId). You can then use that id combined with getElementById(playerId) to send javascript calls into the flash player (ie, player.playVideo();).
You can attach an event listener to the player with player.addEventListener('onStateChange', 'playerState'); which will send any state changes to another global function (in this case playerState).
The problem is I'm not sure how to associate a state change with a specific player. My jQuery plugin can happily attach more than one video to a selector and attach events to each one, but the moment a state actually changes I lose track of which player it happened in.
I'm hoping some example code may make things a little clearer. The below code should work fine in any html file.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="application/text+html;utf-8"/>
<title>Sandbox</title>
<link type="text/css" href="http://jqueryui.com/latest/themes/base/ui.all.css" rel="stylesheet" />
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.3.2");
google.load("jqueryui", "1.7.0");
</script>
<script type="text/javascript" src="http://swfobject.googlecode.com/svn/tags/rc3/swfobject/src/swfobject.js"></script>
<script type="text/javascript">
(function($) {
$.fn.simplified = function() {
return this.each(function(i) {
var params = { allowScriptAccess: "always" };
var atts = { id: "ytplayer"+i };
$div = $('<div />').attr('id', "containerplayer"+i);
swfobject.embedSWF("http://www.youtube.com/v/QTQfGd3G6dg&enablejsapi=1&playerapiid=ytplayer"+i,
"containerplayer"+i, "425", "356", "8", null, null, params, atts);
$(this).append($div);
});
}
})(jQuery);
function onYouTubePlayerReady(playerId) {
var player = $('#'+playerId)[0];
player.addEventListener('onStateChange', 'playerState');
}
function playerState(state) {
console.log(state);
}
$(document).ready(function() {
$('.secondary').simplified();
});
</script>
</head>
<body>
<div id="container">
<div class="secondary">
</div>
<div class="secondary">
</div>
<div class="secondary">
</div>
<div class="secondary">
</div>
</div>
</body>
</html>
You'll see the console.log() outputtin information on the state changes, but, like I said, I don't know how to tell which player it's associated with.
Anyone have any thoughts on a way around this?
EDIT:
Sorry, I should also mentioned that I have tried wrapping the event call in a closure.
function onYouTubePlayerReady(playerId) {
var player = $('#'+playerId)[0];
player.addEventListener('onStateChange', function(state) {
return playerState(state, playerId, player); } );
}
function playerState(state, playerId, player) {
console.log(state);
console.log(playerId);
}
In this situation playerState never gets called. Which is extra frustrating.
Edit:
Apparently calling addEventListener on the player object causes the script to be used as a string in an XML property that's passed to the flash object - this rules out closures and the like, so it's time for an old-school ugly hack:
function onYouTubePlayerReady(playerId) {
var player = $('#'+playerId)[0];
player.addEventListener('onStateChange', '(function(state) { return playerState(state, "' + playerId + '"); })' );
}
function playerState(state, playerId) {
console.log(state);
console.log(playerId);
}
Tested & working!
Im Using Jquery SWFobject plugin, SWFobject
It is important to add &enablejsapi=1 at the end of video
HTML:
<div id="embedSWF"></div>
Jquery:
$('#embedSWF').flash({
swf: 'http://www.youtube.com/watch/v/siBoLc9vxac',
params: { allowScriptAccess: "always"},
flashvars: {enablejsapi: '1', autoplay: '0', allowScriptAccess: "always", id: 'ytPlayer' },
height: 450, width: 385 });
function onYouTubePlayerReady(playerId) {
$('#embedSWF').flash(function(){this.addEventListener("onStateChange", "onPlayerStateChange")});
}
function onPlayerStateChange(newState) {
alert(newState);
}
onYouTubePlayerReady must be outside of $(document).ready(function() to get fired
I had this same problem and tried the accepted answer. This didn't work for me; the playerState() function was never called. However, it put me on the right path. What I ended up doing was this:
// Within my mediaController "class"
window["dynamicYouTubeEventHandler" + playerID] = function(state) { onYouTubePlayerStateChange(state, playerID); }
embedElement.addEventListener("onStateChange", "dynamicYouTubeEventHandler" + playerID);
// End mediaController class
// Global YouTube event handler
function onYouTubePlayerStateChange(state, playerID) {
var mediaController = GetMediaControllerFromYouTubeEmbedID(playerID);
mediaController.OnYouTubePlayerStateChange(state);
}
It's fairly nasty, but so is the current state of the YouTube JavaScript API.
Here is some other helpful/nasty code if you are using any kind of advanced prototyping patterns. This basically allows you to retrieve a "class" instance from the YouTube player ID:
// Within my mediaController "class"
// The containerJQElement is the jQuery wrapped parent element of the player ID
// Its ID is the same as the player ID minus "YouTubeEmbed".
var _self = this;
containerJQElement.data('mediaController', _self);
// End mediaController class
// Global YouTube specific functions
function GetMediaControllerFromYouTubeEmbedID(embedID) {
var containerID = embedID.replace('YouTubeEmbed', '');
var containerJQObject = $("#" + containerID);
return containerJQObject.data('mediaController');
}
function onYouTubePlayerReady(playerId) {
var mediaController = GetMediaControllerFromYouTubeEmbedID(playerId);
mediaController.OnYouTubeAPIReady();
}
Here's a nice article that goes through creating a class to wrap an individual player, including dispatching events to individual objects using a similar approach to that mentioned in a previous answer.
http://blog.jcoglan.com/2008/05/22/dispatching-youtube-api-events-to-individual-javascript-objects/
How about something like so:
var closureFaker = function (func, scope) {
var functionName = 'closureFake_' + (((1+Math.random())*0x10000000)|0).toString(16);
window[functionName] = function () {
func.apply(scope || window, arguments);
};
console.log('created function:', functionName, window[functionName]);
return functionName;
};
ytplayer.addEventListener("onStateChange", closureFaker(function () {
//place your logic here
console.log('state change', arguments)
}));

Categories