Javascript/Jquery回调函数用于Fancybox的是“是”、“否”、“确认”。

3
我正在尝试实现一个漂亮的是/否确认框,但出现了回调未按预期工作的问题。下面的示例使用Fancybox v2
以下代码存在问题:"do_something"函数在单击HREF为"Test"时被调用,而不是在用户单击"#fancyConfirm_ok"时被调用。
function fancyConfirm(msg,callback) {
    var ret;
    jQuery.fancybox({
        'modal' : true,
        'content' : "<div style=\"margin:1px;width:240px;\">"+msg+"<div style=\"text-align:right;margin-top:10px;\"><input id=\"fancyconfirm_cancel\" style=\"margin:3px;padding:0px;\" type=\"button\" value=\"Cancel\"><input id=\"fancyConfirm_ok\" style=\"margin:3px;padding:0px;\" type=\"button\" value=\"Ok\"></div></div>",
        'afterShow' : function() {
            jQuery("#fancyconfirm_cancel").click(function() {
                ret = false;
                //jQuery.fancybox.close();
                $.fancybox.close();
            })
            jQuery("#fancyConfirm_ok").click(function() {
                ret = true;
                jQuery.fancybox.close();
            })
        },
        'afterClose' : function() { 
            if (typeof callback == 'function'){ 
                callback.call(this, ret); 
            } else {
                var callback_type = typeof callback;
                alert(callback_type);
            }
        }
    });
}
<a href="#" onclick="fancyConfirm('Are you sure you want to delete?',  do_something('a', 'b') );return false;">Test</a>

2
请问您能提供一个jsfiddle吗? - Neysor
2个回答

11

当用户点击链接时,您的方法"do_something('a', 'b')"将被执行,并且返回的结果将作为第二个参数传递给"fancyConfirm"方法。这就是为什么您的参数"callback"始终为"undefined"的原因。

fancyBox也存在一个问题-"afterClose"回调在打开和关闭之前都会被调用(这将在下一个版本中更改)。

我建议在链接上绑定一个点击事件,并在用户单击其中一个按钮时调用回调函数,例如- http://jsfiddle.net/xcJFY/1/


感谢您的回答。我会测试并回复。 - Paul Benbow
这有点误导人,未定义是由函数中定义的 var ret 行引起的。当调用 callback.call(this, ret) 时,它已经超出了作用域。请参见下面的工作示例 - user692942

2
不是特别喜欢双重回调方法(对不起Janis)。 因此,在尝试自己找到解决方案时,我尝试了类似的代码,并发现只要我的返回值未在函数范围内定义,它就可以正常工作。当我的返回值在函数内部被定义时,我会得到奇怪的行为,它会有一段时间工作,然后恢复为未定义状态。实际上,返回值需要在函数范围之外,全局,闭包等范围内定义。
$(document).ready(function() {
    $(".fancybox").on("click", function(e){   
        e.preventDefault();
        confirm("Do you wish to continue?", true, function(resp) {
            alert("You clicked " + resp);
        });
    });
});

function confirm(msg, modal, callback) {
    $.fancybox("#confirm",{
        modal: modal,
        beforeShow: function() {
            $(".title").html(msg);
        },
        afterShow: function() {
            $(".confirm").on("click", function(event){
                if($(event.target).is(".yes")){
                    ret = true;
                } else if ($(event.target).is(".no")){
                    ret = false;
                }
                $.fancybox.close();
            });
        },
        afterClose: function() {
            callback.call(this, ret);
        }
    });  
}

这里是一个示例:jsfiddle

感谢 Francisco DiazGoogle Groups FancyBox forum 上的 post,指导我正确方向。

更新:

现在我已经扩展了我的示例,使用动态构建的按钮和自定义返回值,因此您不仅仅局限于真和假。

$(document).ready(function() {
    $(".fancybox").on("click", function(e){   
        e.preventDefault();
        confirm("Do you wish to continue?", {
                /* 
                Define your buttons here, can handle multiple buttons 
                with custom title and values
                */
                buttons: [
                    { class: "yes", type: "button", title: "Yes", value: "yes" },
                    { class: "no", type: "button", title: "No", value: "no" },
                    { class: "maybe", type: "button", title: "Maybe?", value: "maybe" }
                ],
                modal: true
            }, 
            function(resp) {
                alert("You clicked " + resp);
            }
        );
    });
});

function confirm(msg, options, callback) {
    $.fancybox("#confirm",{
        modal: options.modal,
        beforeShow: function() {
            this.content.prepend("<p class=\"title\"></p>");
            $(".title").html(msg);

            for (i = 0; i < options.buttons.length; i++) {
                this.content.append($("<input>", { 
                    type: "button", class: "confirm " + options.buttons[i].class, 
                    value: options.buttons[i].title
                  }).data("index", i));
            }
        },
        afterShow: function() {
            $(".confirm").on("click", function(event){
                ret = options.buttons[$(event.target).data("index")].value;
                $.fancybox.close();
            });
        },
        afterClose: function() {
            this.content.html("");
            callback.call(this, ret);
        }
    });
}

添加了jsfiddle的示例。

你的第一个基本示例正是我想要做的,感谢您的发布!在您的工作jsfiddle示例中,我遇到了一些问题,因为它看起来像您正在使用jQuery 1.7 (.on),而我猜测是fancybox 2(modal:modal而不是modal:true,并且显然选择器“#confirm”作为fancybox的第一个参数,我不知道该如何处理)。我们的网站使用的是jQuery 1.4.3和fancybox 1.3.4,但我一直无法让它工作。您有任何想法如何进行后期适配吗?还是这个功能只能在更新的版本中使用? - sootsnoot
1
@sootsnoot 我刚试着修改了脚本以适应你的需求,但我得出结论,最好将你的jquery版本升级至至少1.7,并使用fancybox2。原因如下:1. 你无法将选择器传递给fancybox。在示例中,我使用了 "#confirm",这是我的div元素的 id,因为1.3.4依赖于 href 来传递包含元素,所以这样做行不通。2. 所需的事件不可用,而1.3.4中现有的事件不起作用。 - user692942
你的第一个例子很好用。我在网页上尝试了同样的操作,但是点击“是”或“否”后没有任何反应。jQuery版本是否有影响?注意:我正在使用fancybox2旧版本的应用程序。 - Jnanaranjan
1
@Jnanaranjan,老实说,我不确定。我得自己试着测试一下(因为我已经有一段时间没用过这个了),然后再回复你。你试过附带的JSFiddle吗? - user692942
1
正如我之前提到的,jsfiddle运行得很好。但是一旦我在网站上尝试代码,就会出现这种情况。没有警告或错误提示。我只是想问你或其他人是否知道是否有其他脚本会产生冲突。我会尝试修复它并在成功后发布。 - Jnanaranjan
使用了此代码 https://gist.github.com/6ui11em/2642954 并将 onComplete 和 onClose 分别替换为 afterShow 和 afterClose。它起作用了。但有一个问题,函数调用后的任何警报都无法工作,只有控制台日志可以工作。谢谢! - Jnanaranjan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接