Avatar of rascal
rascalFlag for United States of America

asked on 

Invoking Fancybox via Javascript fails, but ok with JQuery?

Hi Experts,
We created a page that shows videos using FancyBox via JQuery and it all works fine. We set an onclick handler on each video link. You can see the page working here: http://www.globalpartnerships.org/learn-more/videos/

However, we also wanted to be able to pass the YouTube video ID to the page via a querystring and have the page display that video, so we set up a Javascript function to invoke FancyBox. But this doesn't work and we can't figure out why! Here is the link to page using the querystring: http://www.globalpartnerships.org/learn-more/videos/?v=05zozOAqjBM

(Note that the v= parameter will only work if the video id passed is one already contained on the page. The one in the example above is the first video on the page).

We tried tracing with Firebug and it showed a message of "TypeError: loading is undefined" and it shows loading.hide as the function in error. I suppose that's FancyBox's "loading" animation but I have no idea how this error comes into effect or even why.

The function CustomPageInitContent() is where all our code is that relates to FancyBox.

Any ideas or help would be greatly appreciated!

Thanks experts!
jQuery

Avatar of undefined
Last Comment
Gary
Avatar of Scott Fell
Scott Fell
Flag of United States of America image

Why don't you either read the query string with php or in jquery you could grab it this way.  http://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html


// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

var v = getUrlVars()["v"];
// from here run the videos as on your first link

Open in new window

Avatar of rascal
rascal
Flag of United States of America image

ASKER

Getting the parameter is no problem, the problem is that when I invoke the FancyBox manually via javascript, it fails with the error: "TypeError: loading is undefined"

further, once it fails with that error, the original code's Fancybox fails as well.
Avatar of Scott Fell
Scott Fell
Flag of United States of America image

I don't think you need to completely rewrite your jquery based on a querystring or not.

Using what is working now and just adding an if statement checking for the querystring you could do below although I have not tested.  If it works correctly, I would also add some type of error trapping in case a querystring is used that does not match a video.
//***********************************
// ShowVideo
//***********************************
function ShowVideo(sHref,sTitle)
{
	$.fancybox({
		'type' : 'iframe',
		// hide the related video suggestions and autoplay the video
		'href' : sHref.replace(new RegExp('watch\\?v=', 'i'), 'embed/') + '?rel=0&autoplay=1',
		'overlayShow' : false,
		'centerOnScroll' : true,
		'speedIn' : 100,
		'speedOut' : 50,
		'width' : 640,
		'height' : 480,
		'titlePosition' : 'inside',    //  'float', 'outside', 'inside' or 'over'
		'title' : sTitle,
		'swf': {'allowfullscreen':'true', 'wmode':'transparent'}
	}); // $.fancybox
}

// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

var v = getUrlVars()["v"];
if (v.length>0){
	ShowVideo(document.URL,'some title')
}



//***********************************
// CustomPageInitContent
//***********************************
function CustomPageInitContent()
{
	$('a.videogallery').on('click', function(event) {
		event.preventDefault();
		$.fancybox({
			'type' : 'iframe',
			// hide the related video suggestions and autoplay the video
			'href' : this.href.replace(new RegExp('watch\\?v=', 'i'), 'embed/') + '?rel=0&autoplay=1',
			'overlayShow' : false,
			'centerOnScroll' : true,
			'speedIn' : 100,
			'speedOut' : 50,
			'width' : 640,
			'height' : 480,
			'titlePosition' : 'inside',    //  'float', 'outside', 'inside' or 'over'
        	'title' : $(this).attr('rel'),
			'swf': {'allowfullscreen':'true', 'wmode':'transparent'}
		}); // $.fancybox
	}); // $('a.more')
	
	// auto invoke the video if passed in a querystring
	}

Open in new window

Avatar of rascal
rascal
Flag of United States of America image

ASKER

@padas - your code is essentially what my code does - it detects a querystring value and if found, invokes the ShowVideo() function. The problem is that it doesn't work. When there is no call to ShowVideo, then the original code works fine. But when I introduce a separate function (the ShowVideo() function) and try to call it manually, it fails with the error message and after that, not even the main fancybox calls work.
Avatar of Gary
Gary
Flag of Ireland image

You're calling the fancybox function outside the document.ready but you are initing the fancybox setup in a document.ready.
Avatar of rascal
rascal
Flag of United States of America image

ASKER

@Gary - we are actually calling fancybox from within our document.ready:

document.ready calls CustomPageInitContent() which calls our fancybox.

(there is an attempt to find any anchor tags with class="fancybox" in the document.ready() function, but there are none on the page, so that is ignored.
Avatar of Gary
Gary
Flag of Ireland image

sVideoID equals
http://www.youtube.com/embed/http://www.youtube.com/embed/05zozOAqjBM
(this is not a typo)
Caused by
if (sVideoID.toLowerCase().indexOf('05zozoaqjbm') > -1)
{
sVideoID = 'http://www.youtube.com/embed/' + sVideoID;
ShowVideo(sVideoID,sRel);
}


Maybe this is causing the burp
ASKER CERTIFIED SOLUTION
Avatar of Gary
Gary
Flag of Ireland image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of rascal
rascal
Flag of United States of America image

ASKER

I just stumbled on the solution: It's a timing thing. The manual call to ShowVideo() needs to take place after about 1 second to give time to <something> to initialize - whether it's giving time for fancybox to initialize, or giving time for the a.videogallery lick handler loop to complete (the code in the CustomPageInitContent() function).

See the code below - CustomPageInitContent() is called from my document.ready(). Note the setTimeout function at the bottom of CustomPageInitContent().

<script type="text/javascript">
//***********************************
// ShowVideo
//***********************************
function ShowVideo(sHref,sTitle)
{
	$.fancybox({
		'type' : 'iframe',
		// hide the related video suggestions and autoplay the video
		'href' : sHref.replace(new RegExp('watch\\?v=', 'i'), 'embed/') + '?rel=0&autoplay=1',
		'overlayShow' : false,
		'centerOnScroll' : true,
		'speedIn' : 100,
		'speedOut' : 50,
		'width' : 640,
		'height' : 480,
		'titlePosition' : 'inside',    //  'float', 'outside', 'inside' or 'over'
		'title' : sTitle,
		'swf': {'allowfullscreen':'true', 'wmode':'transparent'}
	}); // $.fancybox
}
//***********************************
// CheckQuerystring
//***********************************
function CheckQuerystring()
{
	// auto invoke the video if passed in a querystring
	<?php
	$sQSVideoID = strtolower(trim($_REQUEST['v']));
	if (strlen($sQSVideoID)>0) { 
	?>
			$('a.videogallery').each(function() {
				var sVideoID = $(this).attr('href');
				var sRel = $(this).attr('rel');
				
				if (sVideoID.toLowerCase().indexOf('<?php echo $sQSVideoID;?>') > -1)
				{
					ShowVideo(sVideoID,sRel);
					return false; // break out of the loop
				} // if (sVideoID.toLowerCase().indexOf('<?php echo $sQSVideoID;?>') > -1)
			}); // $('a.each')
	<?php
	} // if (strlen($sQSVideoID)>0)  
	?>

}
//***********************************
// CustomPageInitContent
//***********************************
function CustomPageInitContent()
{
	$('a.videogallery').on('click', function(event) {
		event.preventDefault();
		$.fancybox({
			'type' : 'iframe',
			// hide the related video suggestions and autoplay the video
			'href' : this.href.replace(new RegExp('watch\\?v=', 'i'), 'embed/') + '?rel=0&autoplay=1',
			'overlayShow' : false,
			'centerOnScroll' : true,
			'speedIn' : 100,
			'speedOut' : 50,
			'width' : 640,
			'height' : 480,
			'titlePosition' : 'inside',    //  'float', 'outside', 'inside' or 'over'
        	'title' : $(this).attr('rel'),
			'swf': {'allowfullscreen':'true', 'wmode':'transparent'}
		}); // $.fancybox
	}); // $('a.more')
	
	setTimeout('CheckQuerystring()',1000);
}
</script>

Open in new window

Avatar of Gary
Gary
Flag of Ireland image

Wouldn't it just be easier to simulate the click rather than repeating code...?
Avatar of Scott Fell
Scott Fell
Flag of United States of America image

I agree with GaryC123, that is what I was trying to get at. You shouldn't need to have to call it in multiple spots.
Avatar of rascal
rascal
Flag of United States of America image

ASKER

@Gary,
You can't use the .click() to emulate clicking on an <a> tag.
Avatar of Gary
Gary
Flag of Ireland image

Yes you can.
Avatar of Gary
Gary
Flag of Ireland image

Again 'Yes you can'.
What you cannot do is emulate someone clicking a link, that is as if someone really did click a link and for example the target being followed.

You can simulate a click and any event bound to it will be executed.
See this fiddle for an example
http://jsfiddle.net/9txPQ/2/
No user interaction but the anchor click function fires
Avatar of rascal
rascal
Flag of United States of America image

ASKER

I stand corrected :)
Avatar of rascal
rascal
Flag of United States of America image

ASKER

I've requested that this question be closed as follows:

Accepted answer: 0 points for rascal's comment #a39473857

for the following reason:

This is the solution to the problem - we had initially tried using the .click() but it failed with the error message listed in my original question posting.

What the problem was - was we called the .click() handler too soon (even though we called it from our document.read() function). Perhaps fancybox needed more time to initialize? At any rate, we deferred our code for 1 second by setting a setTimeout() of 1000 milliseconds to invoke our function, then it all worked fine.
Avatar of rascal
rascal
Flag of United States of America image

ASKER

Sorry, didn't mean to close this on my comment - I meant to close it on GaryC123's comment that we use the .click() handler and award points to GaryC123.

How can we adjust?
Avatar of rascal
rascal
Flag of United States of America image

ASKER

GaryC123 - this is what I meant when I said that you cannot invoke an <a> from the .click() handler: http://jsfiddle.net/9txPQ/4/
Avatar of Gary
Gary
Flag of Ireland image

Yes that's I thought you were thinking and why I thought I had clarified it in my comment.
Your click event in your jsfiddle is working and firing but there is nothing to do with the click, the href will not be followed because you cannot emulate a real click.
Click Request Attention under your initial question.
jQuery
jQuery

jQuery (Core) is a cross-browser JavaScript library that provides abstractions for common client-side tasks such as Document Object Model (DOM) traversal, DOM manipulation, event handling, animation and Ajax. jQuery also provides a platform to create plugins that extend jQuery's capabilities beyond those already provided by the library.

19K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo