javascript - jQuery 插件事件监听器未触发或绑定(bind)

标签 javascript jquery binding event-handling event-listener

我正在创建一个使用弹出窗口的 Web 应用程序。我在多个页面上使用相同的弹出窗口,但页面之间存在各种差异。这一切都是通过 JavaScript (jQuery) 控制的。

因此,我决定创建一个 jQuery 插件来轻松进行这些更改。问题是我在插件定义中创建的监听器不会在单击时触发,甚至不会显示为与检查器中的这些元素绑定(bind)。我不确定问题是什么,因为它应该与通过函数绑定(bind)事件没有什么不同。

这是我的代码:

(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"
 });

有什么想法吗?提前致谢。

最佳答案

不知何故,我忽略了一个简单的问题。

因为我的 JS 不在 $(document).ready(function() {}); 内, 它在 <script> 后立即运行。遇到标签,这是在页面上渲染 DOM 之前。

因此,JS 尝试绑定(bind)到页面上尚不存在的元素。

希望这可以帮助任何偶然发现此问题的人。始终确保您正在操作的 DOM 实际上位于页面上。

关于javascript - jQuery 插件事件监听器未触发或绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24658432/

相关文章:

java - 在 Spring MVC Controller 中使用 jquery 传递对象数组

javascript - 获取 Idless p 标签的值进行比较

wpf - 将列表绑定(bind)到 DataGrid

javascript - 通过暂停/播放循环寻呼机自动前进

javascript - 在单个 div 中滚动会导致重叠

JavaScript 代码未运行

javascript - 替换函数中的 _.each

c# - 绑定(bind)到静态属性的一种方法失败

c# - 将零数字添加到我的十进制值

javascript - 如何证明angular服务是单例的?