【问题标题】:How to bind jQuery Datepicker after Ajax refresh?Ajax刷新后如何绑定jQuery Datepicker?
【发布时间】:2013-07-27 21:53:57
【问题描述】:

我有一个非常适合我的 jQuery 日期选择器,但当我通过 ajax 更新内容时,我会丢失日期选择器。据我所知,我应该使用 jQuery on() 将其绑定到输入,但我似乎找不到将其绑定到的正确事件。

第一次有效,但在随后的刷新时无效:

$("[id^=startPicker]").datetimepicker({
        showOn: "button",
        buttonImage: "/img/calendar_icon.png",
        buttonImageOnly: true,
        dateFormat: 'mm/dd/yy',
        timeFormat: 'hh:mm tt',
        stepMinute: 1,
        onClose: function (dateText, inst) {

            var selectedDate = $(this).datepicker("getDate"); //Date object

            $.ajax({
                url: "/url",
                dataType: "json",
                method: 'post',
                data: {
                    value: selectedDate.toDateString() + ' ' + selectedDate.toTimeString()
                },
                beforeSend: function () {
                    $("#loading").fadeIn();
                },
                success: function (data, textStatus) {
                    $("#content").html(data);
                },
                complete: function () {
                    $("#loading").fadeOut();
                }
            });
        }
    });

第一次或后续刷新时不绑定:

$('#content').on('ready', "[id^=startPicker]", function () {
        $(this).datetimepicker({
            showOn: "button",
            buttonImage: "/img/calendar_icon.png",
            buttonImageOnly: true,
            dateFormat: 'mm/dd/yy',
            timeFormat: 'hh:mm tt',
            stepMinute: 1,
            onClose: function (dateText, inst) {
    
                var selectedDate = $(this).datepicker("getDate"); //Date object
    
                $.ajax({
                    url: "/url",
                    dataType: "json",
                    method: 'post',
                    data: {
                        value: selectedDate.toDateString() + ' ' + selectedDate.toTimeString()
                    },
                    beforeSend: function () {
                        $("#loading").fadeIn();
                    },
                    success: function (data, textStatus) {
                        $("#content").html(data);
                    },
                    complete: function () {
                        $("#loading").fadeOut();
                    }
                });
            }
        });
    });

【问题讨论】:

  • 您不能通过开箱即用的.on() 事件委派此插件。您需要在 .success() 回调中的元素上重新实例化插件。
  • ready 事件仅用于文档,即使您可以将其绑定到任何其他元素。但是使用 .on() 语法,这不会在 ready 事件完成后触发,不像使用别名 $().ready()

标签: jquery ajax datepicker jquery-events


【解决方案1】:

jQuery .on() 函数用于延迟事件处理,但不适用于插件初始化。

它适用于事件,因为 DOM 模型将事件从 DOM 元素传播到其父元素,一直传播到顶部。因此,当您单击链接时,您还单击了包含该链接的任何内容(例如 div),包含该容器的任何内容,依此类推,一直到 body 标记,最后是 @987654325 @ 本身。 .on() 通过绑定到公共父元素而不是动态子元素的单击事件来利用这一点,因此可以添加/删除子元素而不会丢失父元素上的事件处理程序。

但是,插件初始化不能以这种方式工作。为了在目标元素上初始化插件,必须在元素本身上完成,这意味着该元素当时需要在 DOM 中。因此,当您动态添加新元素时,您需要定位这些新元素并在其上初始化插件。因此,来自 AJAX 调用的 success 函数需要这样做。

请注意,由于您的 AJAX 调用本身就在您的初始化内部,因此您需要将其中的一些拆分为单独的函数以供重复使用。否则,这种重新初始化将无限期地嵌套在自身内部。

可能是这样的:

var datePickerClose = function (dateText, inst) {

    var selectedDate = $(this).datepicker("getDate"); //Date object

    $.ajax({
        url: "/url",
        dataType: "json",
        method: 'post',
        data: {
            value: selectedDate.toDateString() + ' ' + selectedDate.toTimeString()
        },
        beforeSend: function () {
            $("#loading").fadeIn();
        },
        success: function (data, textStatus) {
            $("#content").html(data);
            $("#content").find("[id^=startPicker]").each(function () {
                bindDatePicker(this);
            });
        },
        complete: function () {
            $("#loading").fadeOut();
        }
    });
};

var bindDatePicker = function(element) {
    $(element).datetimepicker({
        showOn: "button",
        buttonImage: "/img/calendar_icon.png",
        buttonImageOnly: true,
        dateFormat: 'mm/dd/yy',
        timeFormat: 'hh:mm tt',
        stepMinute: 1,
        onClose: datePickerClose
    });
};

$("[id^=startPicker]").each(function() {
    bindDatePicker(this);
});

当然,这是未经测试的徒手代码,只是为了演示这个概念。它可能需要稍作调整,并且可能有更优雅的方式来完成相同的逻辑。

【讨论】:

  • 感谢您的详尽回答!我快到了!
  • 感谢您的详尽回答!我快到了! $("[id^=startPicker]").each(function() { bindDatePicker(this); }); 非常适合在页面加载时进行绑定,但是:$("#content").find("[id^=startPicker]").each(function () { bindDatePicker(this); }); 似乎没有执行,至少根据 firefox ddebugger 而言。我也尝试过从其他 ajax 函数成功调用它并得到同样的结果。
  • @richj:AJAX调用成功返回了吗?如果调用了success 处理程序,那么它应该到达那行代码。
  • 看来,即使该函数有效,即更新日期并返回页面的 html 并且没有错误,成功处理程序也不会触发。我什至尝试为成功添加一个简单的警报来测试它,但没有结果。如何验证 ajax 调用的结果? Firefox 说:'GET url... 200 OK'
  • 我将绑定移动到完整的处理程序并且它正在工作,但我认为将完整的处理程序用于该功能是一种不好的形式?
【解决方案2】:

您不能委托插件,委托仅用于事件侦听器。添加目标元素后,使用成功回调函数并重新初始化 datepicker 插件

success: function (data, textStatus) {
    $("#content").html(data).find('[id^=startPicker]').datepicker({...});
},

【讨论】:

    【解决方案3】:

    我有一个类似的问题:在重新加载 ajax 页面后,我无法使用 $(element).datepicker() 设置新的日期选择器。因为Datepicker只做一次干净的初始化,我只是在ajax成功后直接设置:

    $.datepicker.initialized = false;
    

    现在下一个 $(element).datepicker() 将导致新的初始化。这会影响旁边的所有日期选择器,因此您可能在 ajax 容器之外重置了 datpicker。

    【讨论】:

      【解决方案4】:

      实际上,我发现执行此操作的最简单方法是将绑定代码简单地放在成功函数中,如下所示:ELEMENT.datepicker();

      例如:$('.datepicker').datepicker();

      完整代码:

      $('#loaddetails').on('click',function(){
                      //Run ajax fetch here
                          $.ajax({
                             type: "POST",
                             url: "yourlink",
                             data: $('form').serialize(), // serializes the form's elements.
                             dataType: 'json',
                             beforeSend: function () {
                               console.log('Form serialised');
                               $('#status').html('<img src="../img/spinner.gif" width="16" height="16">');
                               },
                             success: function(data)
                             {
                              $('#status').html(data);
                              $('.datepicker').datepicker();
                                },
                                error: function (xhr, ajaxOptions, thrownError) {
                                  alert(xhr.status);
                                  alert(thrownError);
                                }
                           });
                      console.log("All ok");
                      return false;
                  });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-14
        • 2012-07-19
        • 2013-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多