我为网站开发了某种Jcrop初始化,我设法创建了自己的命名空间。我的问题是关于此关键字。每次我必须在任何回调函数中访问我的基础对象“aps”时,我必须将这个包装在一个变量中(我选择了这个一词) )。有没有更好的方法呢?例如,我可以使用调用或应用方法吗?这只是一个命名空间,所以我可以使用简单的 aps。 methodName 但是为了这个例子,请不要介意。这是我的源代码:
var aps;
$(function(){
aps = function(){
// private
// variables
var bgColor = '#f5f5f5';
var threshold = 370;
var threshold_width = 800;
return {
tmpl : $('#jcrop-template').html(),
upl_cont : {},
form : {},
logo_img : new Image(),
jcrop_api : null,
scaled_logo_url : '',
image_filename : '',
original_image_filename : '',
mime : '',
trueSize : '',
jcrop_init : function (oiFrameRes){
$('#logo_upload_form').find('img').hide();
this.scaled_logo_url = oiFrameRes.image_url;
this.logo_url = oiFrameRes.original_image_url;
this.original_image_filename = oiFrameRes.original_image_filename;
this.image_filename = oiFrameRes.image_filename;
this.mime = oiFrameRes.mime;
this.upl_cont = $('#facebox div#upload-container-d');
this.logo_img = new Image();
this.logo_img.that = this;
this.logo_img.name = 'logo';
this.logo_img.onload = function(){
this.true_width=this.width;
this.true_height=this.height;
this.that.resize_image();
this.that.resize_facebox();
this.that.display_image();
}
this.logo_img.src = this.logo_url;
},
resize_image : function(){
this.trueSize = '';
if(typeof (this.oSettings.trueSize)!=='undefined') delete(this.oSettings.trueSize);
if (this.logo_img.width > threshold){
if (this.logo_img.width > threshold_width){
this.trueSize = [ this.logo_img.width, this.logo_img.height ];
this.logo_img.height = this.logo_img.height / (this.logo_img.width / threshold_width);
this.logo_img.width = threshold_width;
}
}
},
resize_facebox : function(){
var width = (this.logo_img.width > threshold) ? this.logo_img.width : threshold ;
$('#facebox').css({
left : $(window).width() / 2 - width / 2
}).
find('div.change-size').css({'width': width+30});
},
display_image : function (){
if (this.jcrop_api === null) {
$logo_img = $(this.logo_img).css({'display':'block','margin-left':'auto','margin-right':'auto'})
if (this.upl_cont.find('#logo-container-d>img').length > 0){
if (this.upl_cont.find('#logo-container-d>img').attr('src').length > 0){
this.upl_cont.find('#logo-container-d').empty().append($logo_img);
}
}
else {
this.upl_cont.append(this.tmpl).find('#logo-container-d').append($logo_img);
}
var that = this;
if (typeof (this.upl_cont.find('#jcrop-menu1 a').data('events')) === 'undefined'){
this.upl_cont.find('#jcrop-menu1 a').click(function(){
if (this.href.indexOf('#crop')>-1){
$(this).closest('div').hide();
that.upl_cont.find('#jcrop-menu2').show();
that.setup_crop();
}
if (this.href.indexOf('#close')>-1){
manageIframeResponse();
}
location.hash = '';
return false;
});
}
}
else {
this.reset();
}
},
reset : function(){
$('#jcrop-menu2',this.upl_cont).find('a').unbind('click').end().hide();
$('#jcrop-coords-f',this.upl_cont).find('input[type="text"]').each(function(){this.value="";}).end().hide();
$('#jcrop-menu1',this.upl_cont).find('a').unbind('click').end().show();
this.jcrop_api.destroy();
this.jcrop_api=null;
this.display_image();
},
send_form : function (){
var sPost = $(this.form).find('input[name="image_filename"]').val(this.image_filename).end()
.find('input[name="original_image_filename"]').val(this.original_image_filename).end()
.find('input[name="mime"]').val(this.mime).end()
.find('input[name="user_url"]').val($('#logo_upload_base_url').val()).end()
.find('input[name="user_key"]').val($('#logo_upload_user_key').val()).end()
.serialize();
$.ajax({
url:'iframe_upload.php',
type:'POST',
data: sPost,
success : function(response){
manageIframeResponse();
},
dataType : 'json'
});
},
setup_crop : function (){
var that = this;
if (this.jcrop_api === null) {
this.form = this.upl_cont.find('form#jcrop-coords-f').get(0);
this.upl_cont.find('#jcrop-menu2>a').click(function(){ that.send_form();return false; });
this.updateForm = function (){
var c = arguments[0];
that.form.x1.value=c.x;
that.form.x2.value=c.x2;
that.form.y1.value=c.y;
that.form.y2.value=c.y2;
that.form.h.value=c.h;
that.form.w.value=c.w;
}
this.oSettings.onSelect = this.updateForm;
if (typeof (this.trueSize) !== 'string' && $.isArray(this.trueSize)){
$.extend(this.oSettings,{'trueSize':this.trueSize});
}
$('#facebox #logo-container-d>img').Jcrop( this.oSettings, function(){
that.jcrop_api = this;
var _x1 = (that.logo_img.true_width*0.1).toFixed();
var _y1 = (that.logo_img.true_height*0.1).toFixed();
var _x2 = (that.logo_img.true_width*0.9).toFixed();
var _y2 = (that.logo_img.true_height*0.9).toFixed();
that.jcrop_api.setSelect([0,0,that.logo_img.true_width,that.logo_img.true_height]);
that.jcrop_api.animateTo([_x1,_y1,_x2,_y2]);
});
}
},
updateForm : function (){},
oSettings : {
onSelect:'',
onChange:'',
keySupport: false,
bgColor:bgColor,
aspectRatio:1,
minSize:[0,0]
}
}
}();
$(document).bind('afterClose.facebox', function() {
if (aps.jcrop_api !=null) {
aps.jcrop_api.destroy();
aps.jcrop_api=null;
}
});
});
答案 0 :(得分:7)
无论何时使用函数调用* 调用函数,this
值都设置为全局变量(或严格模式下为undefined
) - 即使您调用了一种方法的功能。道格拉斯·克罗克福德实际上已将此描述为该语言的一个缺陷。
将this
值保存到函数可以访问的变量中是处理此问题的标准方法。
如果确实希望控制回调中this
的内容,则可以使用apply
或call
。两者都将您想要this
设置为的第一个参数。不同之处在于apply
期望所有函数的参数都作为数组传递,而call
期望您单独列出它们。
因此,如果在您的ajax回调中,您想要致电manageIframeResponse
,请将ajax调用的响应传递给它(我知道您的示例没有通过回复,我是' m只是说明你将如何做到这一点,并使其this
值与当前对象相同,你可以这样做:
var self = this;
$.ajax({
success : function(response){
manageIframeResponse.apply(self, [response]); //<--- apply wants your arguments in array form
}
});
或者,由于您的参数尚未采用数组形式,因此您可以更简单地使用call
var self = this;
$.ajax({
success : function(response){
manageIframeResponse.call(self, response); //<---call takes the arguments listed out one at a time
}
});
* 有不同的方法来调用函数。
函数调用意味着您只是调用恰好位于当前范围内的函数:
foo() //inside foo, this will be the global object (or undefined in strict mode)
方法调用表示您正在调用附加到对象的
的函数myObj.foo() //inside foo, this will be myObj
以下是一个例子,如果您不小心,这会让您感到沮丧。
function objCreator() {
var y = "There";
function privateFunc() {
alert(y); //alerts There as expected
alert(this.someField); //undefined: whoops - this is the global object,
} //so there's no someField
return {
x: "Hi",
someField: "blah",
foo: function () {
alert(this.x);
privateFunc();
}
};
}
答案 1 :(得分:2)
考虑一下:
var aps = (function () {
// private variables
var private1;
var private2;
var private3;
var aps = {}; // the core object
aps.setup_crop = function () {
// use "aps" to access the core object
if ( !aps.jcrop_api ) { // etc.
};
// define other methods analogously
return aps;
})();