// Post Div
<div id="post-1"><img src="art/image01.jpg" /></div>
<div id="post-2"><img src="art/image02.jpg" /></div>
<div id="post-3"><img src="art/image03.jpg" /></div>
// MYSQL Json Encode Generated Information
var allPosts = [{"type":"tumblr", "link":"www.blah.com"},
{"type":"instagram", "link":"blah.com"},
{"type":"tumblr", "link":"www.blah.com"}]
var postTotals = 3;
// Generates FancyBox Links for Clickable Post Div
function generateFancyBox(){
for(i=1;i<=postTotals;i++){
$("#post-"+i).click(function(){
alert(allPosts[i].link); // This alerts "www.blah.com" just fine.
$.fancybox({
"type" : "iframe",
"href" : allPosts[i].link // This Variable is always "Undefined".
});
});
}
}
I don't understand why href
: allPosts[i].link
- always becomes undefined
.
This code is a shorthand version of a larger project I'm working on. I have html DIVs that I need FancyBox to create clickable links.
I can not seem to get the allPosts[i].link
to print the URL
. However, right above it, when I alert(allPosts[i].link);
it prints the URL just fine.
What am I doing wrong?
Replace the $.fancybox call with an immediately executing function, which creates a additional closure.
(function () {
alert(i);
$.fancybox({
"type": "iframe",
"href": allPosts[i].link // This Variable is always "Undefined".
});
})();
2 problems:
1) In the click event handler, wrap the click handler assignment in an Immediately Invoked Function Expression (IIFE).
function generateFancyBox(){
for(i=1;i<=postTotals;i++){
(function (ii) {
$("#post-"+ii).click(function(){
console.log(allPosts[ii-1].link);
//$.fancybox({ "type" : "iframe", "href" : allPosts[ii-1].link });
});
}(i))
}
}
By the time the click handler (and fancybox) does it's job, i
is not what it was when it was passed, as a reference, to fancybox. Passing i
in as a parameter to the IIFE you're creating a new scope with a new variable ii
that gets locked in to the current value of the for
loop i
when it was passed to the click handler.
2) There's also a problem with the loop and DIV indexes not sync'ing with the image/link array. So I changed:
allPosts[ii]
to allPosts[ii-1]
Your loop and image DIVs start with "1" as in for(i=1;
and post-1
but your image/link array is zero-based, which means it starts with "0" as in allPosts[0]
. So when grabbing the image/link element, decrement counter by one.
The real problem is that you are creating closures inside a loop
. See this for further information.
What you have to do is to create the closure outside of the loop
and call it as the handler (or callback ) of your click
event , passing i
as argument , so
the closure :
function launchFancybox(i) {
return function () {
$.fancybox({
type: "iframe",
href: allPosts[i].link
});
}
}
Then bind the click
events to each div
inside your generateFancyBox()
function like :
function generateFancyBox() {
for (var i = 0; i < allPosts.length; i++) {
$("#post-"+(i+1)).click( launchFancybox(i) );
}
}
NOTES :
i
declaring it with var
(in strict
mode, it will return an undeclared variable
error if you don't) i
should always start with 0
, otherwise you will never have access to the first element of the allPosts
array . You need to use (i+1)
to refer to each div's ID though. var postTotals = 3;
since you can always refer to the length
of your allPosts
array See JSFIDDLE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.