I have a problem with my code, some code does not work when I call recursive call of same function inside it. It has to be something with myGalleria = Galleria.get(0);
, but I have no idea how to make it all work.
Document Ready (just to show when I call function for the first time, everything works fine for first time)
$(document).ready(function(){
$.getJSON('getImages.php', {
cat: "123"
}, function(imgData){
createGallery(imgData);
});
});
Now function itself, note that when I click on .galleria-menuButtons span
that calls same function nothing is working, well galleria itself is creating, but nothing else.
function createGallery(imgData){
$("#gallery").galleria({
image_margin: 30,
clicknext: true,
transition: "fade",
dataSource: imgData
});
myGalleria = Galleria.get(0); // I don't think this works after recursive call
// Adding menu and menu buttons
myGalleria.addElement("menu").appendChild("container", "menu");
myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");
$.ajax({
url: "menuButtons.php",
success: function(data){
myGalleria.$("menuButtons").html(data);
}
});
// Menu button click events
$('.galleria-menuButtons span').live(开发者_高级运维'click', function(){
alert(this.id);
// Getting jSon data
$.getJSON('getImages.php', {
cat: this.id
}, function(imgData) {
alert(imgData);
createGallery(imgData); // <- Recursive call
});
});
}
I have similar function on window.resize and it also does not work after recursive call.
$(window).resize(function(){
$(".galleria-container").css("width", $(window).width());
$(".galleria-container").css("height", $(window).height());
galleriaRescale = Galleria.get(0);
galleriaRescale.rescale(); // <- this is not working either
//sizeBG();
});
FYI - this isn't actually recursion in the traditional sense because you're calling createGallery
from a click handler which launches a JSON request which then calls createGallery
when that succeeds, both of which will occur after the previous call to createGallery
finishes.
But you do have surviving function closures which could be confusing things or causing problems. One guess is that you may want to make sure that things you expect to be local variables (like myGalleria
have a var
in front of them so they really are local variables and not variables that might be scoped to a higher level and be influenced by a previous incarnation of this call or be influencing an earlier call that hasn't yet completed.
var myGalleria = Galleria.get(0);
Then, assuming imgData
is some sort of data structure like an array or object, you have to make sure that there's either only one global version of that data structure that never changes or that each call of createGallery
has the appropriate separate copy of that data structure. If it's getting changed along the way, then subsequent calls to createGallery
may not be getting the data they want. If it's a read-only data structure (you don't change it), then you're probably OK on that one.
OK, let's talk through the pseudo code for what this does.
- On page ready, you get some JSON image data.
- When that succeeds, you call
createGallery
with that image data. - The createGallery call does some sort of operation in the DOM (perhaps an animation)
- It then calls:
myGalleria = Galleria.get(0);
Because there is no var in front of myGalleria, this is a global variable declaration (bad news for recursion and closures) - You then use the myGalleria data structure to make some changes to the DOM (adding menus and menu items).
- You then add a .live click handler on a pretty generic set of CSS classes (it's possible you have added this click handler more than once here).
- You then fetch some JSON image data again.
- When that image data is fetched, you start the whole process over again by called
createGallery
.
Summary
The two potential problems I see are that myGalleria
is not a local variable and probably should be and you may be adding duplicate click handlers.
If neither of these fully solve the issue, then we probably need more information about what Galleria.get(0)
is doing.
FYI, the resize clickHandler looks like it may have the same issue with not using var to make your variable declaration a local variable.
Round 2
OK, here are some more observations.
When you add the menu and menu buttons with this block of code, you aren't providing any unique identifiers to either the addElement or appendChild functions (you're providing "menu" and "menuButtons" to both). As such, I don't know how you can uniquely hook up to them in the subsequent click event. As far as your code looks, all the menu items look identical and none have unique state. I don't know the Galleria code, but I assume somebody has to make unique identifiers for these new items so that you can uniquely identify them in your subsequent click handler.
// Adding menu and menu buttons myGalleria.addElement("menu").appendChild("container", "menu"); myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");
When you set up a click handler to presumably handle the clicks for just these menu items, you are using the exact same CSS selector every time so there's no way that this click handler is going to be uniquely assigned to just the newly create menu items (which is what I assume you want). I don't know the Galleria code, but I assume that you should create some sort of unique ID that you pass into addElement and appendChild for the newly created menu items and then reference that unique identifier when you install the click handler. Likewise, this function needs to uniquely target just the menu buttons you created by using unique identifiers
myGalleria.$("menuButtons").html(data);
Lastly, I'd suggest you change the name of one of your variables just to avoid confusion. In your click handler, change the three occurrences of
imgData
to justdata
so there can be no confusion about closures and the value of imgData.
Round 3
Ultimately one of the fixes was this (embedded in the comments):
I think it might work if you just only install the .live click handler once outside the createGallery function rather than call it each time. Since it's .live it will automatically work for all future buttons you create so you should only call it once. I'd suggest putting it in the $(document).ready function block.
精彩评论