jQuery 递归

发布于 2024-11-19 12:46:20 字数 1747 浏览 6 评论 0原文

我的代码有问题,当我在其中递归调用同一函数时,某些代码不起作用。它必须与 myGalleria = Galleria.get(0); 相关,但我不知道如何使其全部正常工作。

文档就绪(只是为了显示当我第一次调用函数时,第一次一切正常)

$(document).ready(function(){
    $.getJSON('getImages.php', {
        cat: "123"
    }, function(imgData){
        createGallery(imgData);
    });
});

现在函数本身,请注意,当我单击调用相同函数的 .galleria-menuButtons span 时,什么都没有工作,好吧,画廊本身正在创造,但没有别的。

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
        });
    });
}

我在 window.resize 上有类似的功能,并且在递归调用后也不起作用。

$(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();
});

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();
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝眼泪 2024-11-26 12:46:20

仅供参考 - 这实际上并不是传统意义上的递归,因为您从点击处理程序调用 createGallery ,该处理程序会启动 JSON 请求,然后在成功时调用 createGallery ,两者其中将在上一次调用 createGallery 完成后发生。

但是你确实有幸存的函数闭包,这可能会造成混乱或导致问题。一种猜测是,您可能希望确保您希望成为局部变量的内容(例如 myGalleria 前面有一个 var ,因此它们确实是局部变量,而不是可能作用于更高级别并受此调用的先前版本影响或影响尚未完成的早期调用的变量

var myGalleria = Galleria.get(0);

然后,假设 imgData 是某种数据结构,例如。数组或对象,你必须确保该数据结构要么只有一个永远不会更改的全局版本,要么每次调用 createGallery 都有该数据结构的适当的单独副本(如果在此过程中发生更改),则对 的后续调用。 >createGallery 可能无法获取他们想要的数据如果它是只读数据结构(您不更改它),那么您可能对此没问题

,让我们来讨论一下伪代码 什么的。

  1. 。这是做 页面准备就绪,您将获得一些 JSON 图像数据。
  2. 成功后,您可以使用该图像数据调用 createGallery
  3. createGallery 调用在 DOM 中执行某种操作(可能是动画)
  4. ,然后调用: myGalleria = Galleria.get(0); 因为 myGalleria 前面没有 var,所以这是一个全局变量变量声明(递归和闭包的坏消息)
  5. 然后,您使用 myGalleria 数据结构对 DOM 进行一些更改(添加菜单和菜单项)。
  6. 然后,您在一组非常通用的 CSS 类上添加一个 .live 单击处理程序(您可能已在此处多次添加此单击处理程序)。
  7. 然后,您再次获取一些 JSON 图像数据。
  8. 获取图像数据后,您可以通过调用 createGallery 重新启动整个过程。

总结

我发现的两个潜在问题是,myGalleria 不是本地变量,但可能应该是本地变量,并且您可能会添加重复的点击处理程序。

如果这些都不能完全解决问题,那么我们可能需要有关 Galleria.get(0) 正在做什么的更多信息。

仅供参考,调整大小的 clickHandler 看起来可能与不使用 var 使变量声明成为局部变量有同样的问题。

第二轮

好的,这里有一些更多的观察结果。

  1. 当您使用此代码块添加菜单和菜单按钮时,您没有为 addElement 或appendChild 函数提供任何唯一标识符(您为两者提供“menu”和“menuButtons”)。因此,我不知道如何在后续的点击事件中唯一地连接到​​它们。就您的代码而言,所有菜单项看起来都相同,并且没有一个具有唯一的状态。我不知道 Galleria 代码,但我假设有人必须为这些新项目创建唯一标识符,以便您可以在后续点击处理程序中唯一地标识它们。

    //添加菜单和菜单按钮
    myGalleria.addElement("菜单").appendChild("容器", "菜单");
    myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");

  2. 当您设置点击处理程序来处理这些菜单项的点击时,您正在使用确切的每次都使用相同的CSS选择器,因此这个点击处理程序不可能被唯一地分配给新创建的菜单项(这就是我假设你想要的)。我不知道 Galleria 代码,但我假设您应该创建某种唯一 ID,将其传递到新创建的菜单项的 addElement 和appendChild 中,然后在安装单击处理程序时引用该唯一标识符。同样,此函数需要唯一地定位您使用唯一标识符创建的菜单按钮 myGalleria.$("menuButtons").html(data);

  3. 最后,我建议您更改变量之一的名称只是为了避免混淆。在您的点击处理程序中,将出现的三个 imgData 更改为 data,这样就不会混淆闭包和 imgData 的值。

第三轮

最终的修复之一是(嵌入评论中):

我认为如果您只在 createGallery 函数之外安装一次 .live 点击处理程序而不是每次都调用它,它可能会起作用。由于它是 .live ,它将自动适用于您将来创建的所有按钮,因此您应该只调用它一次。我建议将其放在 $(document).ready 功能块中。

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.

  1. On page ready, you get some JSON image data.
  2. When that succeeds, you call createGallery with that image data.
  3. The createGallery call does some sort of operation in the DOM (perhaps an animation)
  4. 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)
  5. You then use the myGalleria data structure to make some changes to the DOM (adding menus and menu items).
  6. 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).
  7. You then fetch some JSON image data again.
  8. 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.

  1. 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");

  2. 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);

  3. 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 just data 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文