【问题标题】:jQuery recursionjQuery 递归
【发布时间】:2011-07-08 17:30:00
【问题描述】:

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

文档就绪(仅在我第一次调用函数时显示,第一次一切正常)

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

现在函数本身,请注意,当我点击调用相同函数的.galleria-menuButtons span 时,没有任何工作,Galleria 本身正在创建,但没有别的。

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

【问题讨论】:

  • Galleria.get(0) Galleria 是什么?
  • 你能举一个活生生的例子吗?这个不是很清楚。
  • 是的,它确实会提醒 imgData。 Galleria 是一个图片库插件 - galleria.aino.se

标签: javascript jquery recursion galleria


【解决方案1】:

仅供参考 - 这实际上不是传统意义上的递归,因为您从一个单击处理程序调用 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) 正在做什么的信息。

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

第二轮

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

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

    // Adding menu and menu buttons myGalleria.addElement("menu").appendChild("container", "menu"); myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");

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

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

第三轮

最终的修复之一是(嵌入在 cmets 中):

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

【讨论】:

  • 好吧,似乎使它们成为局部变量并没有修复,我在调整大小时对其进行测试,因为它更容易测试。在它前面添加了 var 并且没有任何改变。 imgData 是一个简单的 JSON 数据数组,带有 img amd thumb 列。对我来说似乎是死路一条..
  • 对您的 myGalleria 变量进行更改,因为即使这不能解决问题,这也是一个问题,也许我们可以继续处理下一个问题。您能否分享有关 Galleria.get(0) 是什么以及返回的更多信息?您能否分享一个指向包含此代码的实际页面的链接,以便我们调试整个上下文?
  • 嗯,它只是获取 Galleria 本身的实例。我在这里读过它galleria.aino.se/docs/1.2/references/extending
  • 好吧,我通过使用他们提供的extend 选项修复了createGallery,但rescale 仍然是个问题。
  • 也通过在 extend 方法上创建全局实例然后在 window.resize 事件上使用它来修复。感谢您的帮助,您并没有完全解决我的问题,但您向我展示了更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
  • 2011-09-13
  • 2020-09-30
  • 2015-05-11
  • 2015-08-07
相关资源
最近更新 更多