对话框不是一个函数错误

3

我有这段JavaScript代码,用于显示问题对话框:

// Question Dialog
function deletedialog(button, a){      
    $("<div />", {
        text: a
    }).dialog({        
        width: 600,
        buttons: {
            "Ok": function() { 
                $(button).closest("form").find("[id$=deleterow]").click();
                $(this).dialog("close");
                button.value = "Processing...";
                button.disabled = true;                  
            }, 
            "Cancel": function(event) { 
                $(this).dialog("close");
                event.preventDefault();
                button.value = "Delete";
                button.disabled = false;
            } 
        }
    });         
}

但是出于某些我找不到的原因,我在Firebug中看到了这个错误:

TypeError: $(...).dialog is not a function  

这一行被突出显示。

"取消":function(event) {

当我在JSF头部添加以下内容以防止JQuery和Primefaces冲突时,就会出现此问题:

<script type="text/javascript">
    $.noConflict();
</script>

我该如何解决这个问题?

3
既然你正在使用noConflict,那么你是否尝试过使用“jQuery”代替“$”? - elclanrs
2个回答

6

问题

问题是使用$.noConflict()函数将$符号移除了。应该使用jQuery代替。

两种解决方案

这意味着您应该像这样编写函数调用:jQuery(this).dialog("close");而不是$(this).dialog("close");

要为更大的代码实现更改,可以像这样操作:

(function($){
    // ... old code using "$" instead of "jQuery"
})(jQuery);

解决方案1-多次替换-示例

$(...)调用替换为jQuery(...)的解决方案可能如下所示:

// Question Dialog
function deletedialog(button, a){      
    jQuery("<div />", {
        text: a
    }).dialog({        
        width: 600,
        buttons: {
            "Ok": function() { 
                jQuery(button).closest("form").find("[id$=deleterow]").click();
                jQuery(this).dialog("close");
                button.value = "Processing...";
                button.disabled = true;                  
            }, 
            "Cancel": function(event) { 
                jQuery(this).dialog("close");
                event.preventDefault();
                button.value = "Delete";
                button.disabled = false;
            } 
        }
    });         
}

解决方案2 - 将代码包含在匿名函数中 - 示例

这基于一个事实,你可以创建匿名函数并将jQuery传递给它,但将其赋值给名为$的参数 - 这将导致$符号在函数中可用,就像在$.noConflict()调用之前发生的一样:

(function($){
    // Question Dialog
    function deletedialog(button, a){      
        $("<div />", {
            text: a
        }).dialog({        
            width: 600,
            buttons: {
                "Ok": function() { 
                    $(button).closest("form").find("[id$=deleterow]").click();
                    $(this).dialog("close");
                    button.value = "Processing...";
                    button.disabled = true;                  
                }, 
                "Cancel": function(event) { 
                    $(this).dialog("close");
                    event.preventDefault();
                    button.value = "Delete";
                    button.disabled = false;
                } 
            }
        });         
    }
})(jQuery);

请问您能否更深入地解释一下您的想法? - Peter Penzov
@PeterPenzov: 你也可以将noConflict分配给一个变量,并使用它代替$。例如:var j = jQuery.noConflict(); j.dialog(...) - elclanrs
@elclanrs:这样也许是对的,但并不必要——jQuery变量仍然可以访问,而对于其他开发人员来说,阅读执行j = $.noConflict();j = jQuery的代码可能会更加复杂,相比之下,使用我提供的两个解决方案之一(只需使用jQuery或将代码封装在自调用匿名函数中,从而使$符号在匿名函数范围内再次可用)会更为简单。 - Tadeck
@PeterPenzov:完成了,请看一下。我通常更喜欢使用jQuery方法,因为它不会与其他框架(如MooTools)冲突,而且清晰易懂,JS缩小器仍然能够将其最小化。虽然对于旧代码以及某些其他情况,将代码封装在匿名函数调用中的方法可能更清晰。我已经看到过使用以下片段的示例:(function(window, $, undefined){ ... })(window, jQuery); - Tadeck
第二个例子是一个很好的说明,只是我认为函数“deleteddialog”在包含它的函数执行完后不会被定义。它要么需要在该包含函数内部调用,要么在某些API对象中返回。也许你可以添加一个注释(或函数调用),显示在这种情况下可以使用deleteddialog的位置。 - Paul Lynch

5

在使用$.noConflict();之前,$等同于jQuery

在使用$.noConflict();之后,$等于undefined

这会删除$作为jQuery的快捷方式,这就是为什么它不再是一个函数的原因。通常只有在添加另一个使用$的JavaScript库时才使用$.noConflict();。你有以下几个选项:

  1. 不使用$.noConflict();
  2. 使用$.noConflict();并用jQuery替换每个$
  3. 使用$.noConflict();并将你的代码包装在(function($){ ... })(jQuery)

如果你需要使用$.noConflict();,我建议使用第三种方法。通过将jQuery作为参数传递,它将$重新映射为jQuery。使用你发布的代码,可能会看起来像...

(function($){

    // Question Dialog
    function deletedialog(button, a){      
        $("<div />", {
            text: a
        }).dialog({        
            width: 600,
            buttons: {
                "Ok": function() { 
                    $(button).closest("form").find("[id$=deleterow]").click();
                    $(this).dialog("close");
                    button.value = "Processing...";
                    button.disabled = true;                  
                }, 
                "Cancel": function(event) { 
                    $(this).dialog("close");
                    event.preventDefault();
                    button.value = "Delete";
                    button.disabled = false;
                } 
            }
        });         
    }

})(jQuery)

1
Ryan,除了“_不使用$.noConflict();_”部分之外,你的答案(几秒钟前发布)和我的答案(17分钟前发布)有什么区别? - Tadeck
2
没什么区别。主要的不同是当我开始写我的回答时,你的回答还没有发布。 - Ryan Allred

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