我正在创建一个可创建模式的javascript函数。功能如下:
function createModal(options) {
var self = this;
modalHeaderText = options.header;
modalBodyText = options.body;
$modal = $('<div />').addClass('modal').appendTo('body');
$modalOverlay = $('<div />').addClass('modal-overlay').appendTo($modal);
$modalContainer = $('<div />').addClass('modal-container').appendTo($modal);
$modalHeader = $('<div />').addClass('modal-header').addClass(options.headerClass).html(modalHeaderText).appendTo($modalContainer);
$modalBody = $('<div />').addClass('modal-body').addClass(options.bodyClass).html(modalBodyText).appendTo($modalContainer);
if (options.buttons) {
$modalFooter = $('<div />').addClass('modal-footer').appendTo($modalContainer);
$.each(options.buttons, function(name, buttonOptions) {
$modalButton = $('<button />').addClass(buttonOptions.class).html(name).appendTo($modalFooter);
if(buttonOptions.callback) {
$modalButton.on('click', function() {
buttonOptions.callback();
});
} else {
$modalButton.on('click', function(e) {
$modal.remove();
});
};
});
};
$modal.addClass('active');
if (options.closeOnOverlayClick == true) {
$modalOverlay.on('click', function(e) {
$modal.remove();
});
};
};
这很好用,但是我希望能够在同一个函数中调用该函数,如下所示:
$('#modal').on('click', function(e){
e.preventDefault();
createModal({
header : 'Enter your name',
body : '<input type="text" class="name" />',
buttons : {
'OK' : {
class : 'btn btn-success',
callback : function() {
var name = self.$modalBody.find('.name').val();
if (!name) {
createModal({
header : 'Error',
body : 'You must provide a name',
buttons : {
'OK' : {
class : 'btn'
}
}
});
} else {
alert(name);
};
},
},
'Close' : {
class : 'btn btn-error'
}
}
});
});
我想要的是以下内容:当某人单击ID为“ modal”的按钮(因此为“ #modal”)时,将打开一个带有输入的模式。当按下OK按钮时,它将检查输入(“名称”)是否具有值。如果是这样,该值将显示在警报中。如果不是,则使用文本“您必须提供名称”对新模式进行开放式设置(在当前模式之上)。
如果输入名称,则可以使用。名称显示在警报中,并且关闭按钮也起作用。但是,如果我没有输入名称,并且显示了第二个模式,则该函数中的所有变量都将被覆盖。
如何保留第一个模态中的变量/元素,以便在显示(清除)第二个模态后,第一个模态中的按钮仍然有效。
我在这里创建了一个JSFiddle:https://jsfiddle.net/6pq7ce0a/2/
您可以像这样测试它:
1)点击“开放模式” 2)输入名称 3)点击“确定” 4)名称显示在警报中 ==>可行
问题在这里:
1)点击“开放模式” 2)不要输入名字 3)点击“确定” 4)显示了一个新的模态 5)在新(错误)模式中单击“确定” 6)第一个模式中的按钮(带有输入字段)不再起作用
提前谢谢!
如果我将功能更改为以下功能,则第一个模态根本不起作用。
function createModal(options) {
var self = this;
var modalHeaderText = options.header;
var modalBodyText = options.body;
var $modal = $('<div />').addClass('modal').appendTo('body');
var $modalOverlay = $('<div />').addClass('modal-overlay').appendTo($modal);
var $modalContainer = $('<div />').addClass('modal-container').appendTo($modal);
var $modalHeader = $('<div />').addClass('modal-header').addClass(options.headerClass).html(modalHeaderText).appendTo($modalContainer);
var $modalBody = $('<div />').addClass('modal-body').addClass(options.bodyClass).html(modalBodyText).appendTo($modalContainer);
if (options.buttons) {
var $modalFooter = $('<div />').addClass('modal-footer').appendTo($modalContainer);
$.each(options.buttons, function(name, buttonOptions) {
var $modalButton = $('<button />').addClass(buttonOptions.class).html(name).appendTo($modalFooter);
if(buttonOptions.callback) {
$modalButton.on('click', function() {
buttonOptions.callback();
});
} else {
$modalButton.on('click', function(e) {
$modal.remove();
});
};
});
};
$modal.addClass('active');
if (options.closeOnOverlayClick == true) {
$modalOverlay.on('click', function(e) {
$modal.remove();
});
};
};
问题在这里:
var name = self.$modalBody.find('.name').val();
如果我将'var'添加到所有元素中,则未定义$ modalBody。
答案 0 :(得分:3)
因此,除了上面关于不声明var
的注释之外,您还将对window
的引用存储在self变量中。为了避免所有这些,我在这个小提琴中走了一条路:https://jsfiddle.net/10fanzw6/1/。
快速解释。
this
分配给self
,因为this
是窗口self
对象以及本地var(以提高可读性)self
变量传递回任何按钮回调,使您可以访问所需模态的任何部分。对于后代,包括此处的更新功能:
function createModal(options) {
var self = {};
var modalHeaderText = options.header;
var modalBodyText = options.body;
var $modal = self.$modal = $('<div />').addClass('modal').appendTo('body');
var $modalOverlay = self.$modalOverlay = $('<div />').addClass('modal-overlay').appendTo($modal);
var $modalContainer = self.$modalContainer = $('<div />').addClass('modal-container').appendTo(self.$modal);
self.$modalHeader = $('<div />').addClass('modal-header').addClass(options.headerClass).html(modalHeaderText).appendTo($modalContainer);
self.$modalBody = $('<div />').addClass('modal-body').addClass(options.bodyClass).html(modalBodyText).appendTo($modalContainer);
if (options.buttons) {
var $modalFooter = self.$modalFooter = $('<div />').addClass('modal-footer').appendTo($modalContainer);
$.each(options.buttons, function(name, buttonOptions) {
var $modalButton = $('<button />').addClass(buttonOptions.class).html(name).appendTo($modalFooter);
if (buttonOptions.callback) {
$modalButton.on('click', function() {
buttonOptions.callback(self);
});
} else {
$modalButton.on('click', function(e) {
$modal.remove();
});
};
});
};
$modal.addClass('active');
if (options.closeOnOverlayClick == true) {
$modalOverlay.on('click', function(e) {
$modal.remove();
});
};
};
$('#modal').on('click', function(e) {
e.preventDefault();
createModal({
header: 'Enter your name',
body: '<input type="text" class="name" />',
buttons: {
'OK': {
class: 'btn btn-success',
callback: function(modal) {
var name = modal.$modalBody.find('.name').val();
if (!name) {
createModal({
header: 'Error',
body: 'You must provide a name',
buttons: {
'OK': {
class: 'btn'
}
}
});
} else {
alert(name);
};
},
},
'Close': {
class: 'btn btn-error'
}
}
});
});
答案 1 :(得分:0)
仅不使用var
变量前面的$modal
导致变量存储在窗口范围内。当下一个下一个$ modal关闭时,该变量引用的是一个已经删除的元素,因此在第一个模式的Close
按钮上单击时什么也没有发生。