我正在创建一个利用弹出窗口的Web应用程序。我在几个页面上使用相同的弹出窗口,但页面之间存在各种差异。这一切都是通过JavaScript(jQuery)控制的。
所以,我决定创建一个jQuery插件来轻松地进行这些更改。问题是我在插件定义中创建的侦听器不会在单击时触发,甚至在检查器中显示为绑定到这些元素。我不确定问题是什么,因为它应该与通过函数绑定事件没有什么不同。
这是我的代码:
(function($) {
// Plugin Definition
$.fn.popup = function(options){
console.log("Popup Initializing");
// Override default settings with instance settings
var settings = $.extend({}, $.fn.popup.defaults, options);
console.log("Settings merged");
// Saving objects passed into function
var els = this;
console.log("Attaching Edit Event Listener");
// EDIT
//alert(settings.contentSelector + " " + settings.editButtonSelector);
$("#content").on("click", ".table .edit", function() {
console.log("Edit button clicked");
settings.isEdit = true; settings.isAdd = false;
row = $(this).parent();
header = row.siblings(settings.tableHeaderRowSelector);
headerCells = header.children();
titleCell = row.children(":first").text();
$(settings.popupHeaderSelector).html("Editing '" + titleCell + "'"); // set header
$(settings.popupOriginalIdSelector).val(row.children().eq(0).html());
$(settings.popupSubmitSelector).html("Update"); // set submit button text
// Generate and write form DOM to page
if (settings.autoGeneratePopupForm){
formContent = generateFormContent(headerCells, row); // Generate form inputs
optionsCurrentValues = formContent[1]; // Grab current option input values
$(settings.popupContentSelector).html(formContent); // write form contents to DOM
// set options to correct current settings
$.each(optionsCurrentValues, function(index, value) {
$("select[name='"+index+"']").val(value);
});
}
showPopup();
focusFirstEl();
});
console.log("Adding Add Event Listener");
// ADD
$(settings.contentSelector).on("click", settings.addButtonSelector, function() {
console.log("Add button clicked");
settings.isAdd = true; settings.isEdit = false;
headerCells = $(this).siblings();
row = $(this).parent().next(".row").children().not(".icon");
$(settings.popupHeaderSelector).html("Add New " + dataType); // set header
$(settings.popupSubmitSelector).html("Add " + dataType); // set submit button text
// Generate and write form DOM to page
if (settings.autoGeneratePopupForm){
formContent = generateFormContent(headerCells, row); // Generate form inputs
$(settings.popupContentSelector).html(formContent); // write form contents to DOM
}
showPopup();
focusFirstEl();
});
console.log("Adding Cancel Event Listener");
// CANCEL
$(settings.popupCancelSelector).click(function() {
hidePopup();
});
console.log("Adding User Enter Submission Prevention");
// PREVENT ENTER SUBMIT
$(settings.popupSelector + " form").keydown(function(event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13') {
event.preventDefault();
return false;
}
});
console.log("Finished Initializing");
console.log("");
console.log(settings);
// Ensures chainability
return this;
};
/**
Generates form inputs based on the passed parameters.
@param headerRow the header row of the associated DOM table.
Must be from PHP generated DOM. See ImgsrcUI->printTable
@param contentRow the row of the associated DOM table to generate
the form inputs from. Must be from PHP generated DOM
See ImgsrcUI->printTable
@returns an array. 1st index is of generated form DOM, 2nd index is of current values of the inputs
*/
function generateFormContent(headerCells, contentRow){
formContent = ""; // Empty string filled with generated DOM
contentRow.children().not(".icon").each(function(index) {
inputType = headerCells.eq(index).attr("data-inputtype"); // Get type of input this cell should be
inputLabel = headerCells.eq(index).attr("data-inputlabel"); // Get the text for the label for this cell
cellVal = settings.isEdit == true ? $(this).text() : ""; // Get current value of cell
name = inputLabel.replace(/ /g,''); // Removed spaces from input label to generate the name attr for the input
optionsCurrentValues = {}; // assoc array of input name and value so that it can be set after applied to DOM
switch (inputType){
case "text":
formContent += '<label>'+inputLabel+'</label> <input name="new'+name+'" type="'+inputType+'" value="'+cellVal+'">'
break;
case "select":
options = headerCells.eq(index).attr("data-selectoptions"); // get string version of var name
options = eval(options); // assign that var value to options
formContent += '<label>'+inputLabel+'</label> <select name="new'+name+'" id="">'+options+'</select>';
optionsCurrentValues["new"+name] = cellVal;
break;
case "textarea":
formContent += '<label>'+inputLabel+'</label> <textarea name="new'+name+'" ></textarea>';
break;
}
});
return [formContent, optionsCurrentValues];
}
// Shows the popup and darkens the background
function showPopup(){
$(settings.darkenBackgroundSelector).show();
$(settings.popupSelector).show();
};
// Hides the popup and lightens the background
function hidePopup(){
$(settings.darkenBackgroundSelector).hide();
$(settings.popupSelector).hide();
}
// Puts focus on the first form element in the popup
function focusFirstEl() {
//$(popupSelector+" form").children(":first").focus();
$(settings.popupSelector + " form :input:visible:enabled:first").focus();
};
// Default Settings
$.fn.popup.defaults = {
autoGeneratePopupForm: false, // If true, the contents of the popup will be overwritten with a generated form inputs based on the data you click "edit" on. If false, no content is overwritten.
dataType: "data", // The name of the data type (Ex "Users", "Albums"). Used in the header of the popup
// General Selectors
darkenBackgroundSelector: "#darken-page", // The selector to darken the page behind the popup
contentSelector: "#content", // The selector for the main content area
// DOM Table Selectors
tableHeaderRowSelector: ".heading",
editButtonSelector: ".table .edit",
addButtonSelector: ".table .heading .add",
// Popup Selectors
popupSelector: ".popup.edit",
//popupContentSelector: this.popupSelector + " .content",
popupHeaderSelector: this.popupSelector + " .header p",
popupOriginalIdSelector: this.popupSelector + " #originalId",
popupSubmitSelector: this.popupSelector + " .footer .submit",
popupCancelSelector: this.popupSelector + " .cancel",
// Utility options. Don't change.
isEdit: false,
isAdd: false,
};
$.fn.popup.defaults.popupContentSelector = $.fn.popup.defaults.popupSelector + " .content";
$.fn.popup.defaults.popupHeaderSelector = $.fn.popup.defaults.popupSelector + " .header p";
$.fn.popup.defaults.popupOriginalIdSelector = $.fn.popup.defaults.popupSelector + " #originalId";
$.fn.popup.defaults.popupSubmitSelector = $.fn.popup.defaults.popupSelector + " .footer .submit";
$.fn.popup.defaults.popupCancelSelector = $.fn.popup.defaults.popupSelector + " .cancel";
}(jQuery));
我在页面上调用它是这样的:
$("html").popup({
autoGeneratePopupForm: true,
dataType: "User"
});
有什么想法吗?提前谢谢。
答案 0 :(得分:1)
不知何故,我忽略了一个简单的问题。
由于我的JS不在$(document).ready(function() {});
范围内,
它在遇到<script>
标记后立即运行,这是在页面上呈现DOM之前。
因此,JS试图绑定到页面上尚未存在的元素。
希望这有助于任何偶然发现此问题的人。始终确保您正在操作的DOM实际上在页面上。