javascript - 函数中的相同函数,保留变量/元素
问题描述
我正在创建一个创建模式的 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 按钮时,它会检查输入('name')是否有值。如果是这样,该值将显示在警报中。如果没有,一个新的模式是 openend(在当前模式之上),带有文本“你必须提供一个名称”。
如果我输入一个名字,它会起作用。该名称显示在警报中,并且关闭按钮也有效。但是如果我不输入名称,并且显示第二个模态,函数中的所有变量都会被覆盖。
如何保留第一个模式中的变量/元素,以便在显示(并清除)第二个模式后,第一个模式中的按钮仍然有效。
我在这里创建了一个 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。
解决方案
因此,除了上面关于不声明的评论之外,var
您还将引用存储window
在 self 变量中。为了避免所有这些,我在这个小提琴中走上了这条路:https ://jsfiddle.net/10fanzw6/1/ 。
快速解释。
- 首先不要按原样分配
this
给窗口self
this
- 其次将所有内容分配给空
self
对象以及本地变量(为了更好的可读性) - 第三次将
self
var 传递回任何按钮回调,让您可以访问您可能需要的模式的任何部分。
对于后代,包括此处的更新功能:
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'
}
}
});
});
推荐阅读
- php - WordPress 迁移问题。警告:PHP 启动:预期参数 1 是一个数组,布尔值在
- css - 在保持响应性的同时,无法在卡片中剪切文本以做出本机反应
- java - 如何使用在 IF 语句中创建的变量
- javascript - jQuery 包装所有以美元符号开头的单词
- python - Asyncio 上下文管理器后长时间暂停
- java - 如何将 Mono 错误与 Java 中的字符串进行比较
- python - IMAP COPY 命令在收件箱上不起作用 - Python
- flutter - flutter_inappwebview - 如何更新 URL?
- r - R中的分层循环
- openapi - 将项目作为项目中的模块移动后,打开 api swagger-ui 给出白标错误页面(404)