【问题标题】:jquery datepicker not working on dynamically created htmljquery datepicker不适用于动态创建的html
【发布时间】:2012-03-27 06:48:42
【问题描述】:

我正在动态创建几个带有内部控件的 div。其中两个控件应该是日期选择器。但由于某种原因,它们没有显示(仅显示输入文本) 如果我创建静态 html,它就可以工作,但当我使用动态 html 时就不行。

这是我用来生成 HTML 的代码(我可以看到 div)

var ShowContainerDiv = document.createElement('DIV');

var btnShowDiv = document.createElement('DIV');
btnShowDiv.id = 'btnShowDiv ';
btnShowDiv.title = 'Change';
btnShowDiv.index = 120;

var lblShow = document.createElement('label')
lblShow.htmlFor = "btnShowDiv";
lblShow.appendChild(document.createTextNode('Show'));
btnShowDiv.appendChild(lblShow );
btnShowDiv.onclick = function () {
    dropdown.style.visibility = "visible";
};

var dropdown = document.createElement('DIV');
dropdown.style.backgroundColor = 'white';
dropdown.style.borderStyle = 'solid';
dropdown.style.borderWidth = '2px';
dropdown.style.cursor = 'pointer';
dropdown.style.textAlign = 'left';
dropdown.style.width = '150px';

var chkRed = document.createElement("input");
chkRed.type = "checkbox";
chkRed.id = "chkRed";
chkRed.value = "Red";
chkRed.checked = false;
var lblRed = document.createElement('label')
lblRed.htmlFor = "chkRed";
lblRed.style.color = "#F00";
lblRed.appendChild(document.createTextNode('Red'));

var chkYellow = document.createElement("input");
chkYellow.type = "checkbox";
chkYellow.id = "chkYellow";
chkYellow.value = "Yellow";
chkYellow.checked = false;
var lblYellow = document.createElement('label')
lblYellow.htmlFor = "chkYellow";
lblYellow.style.color = "#FF0";
lblYellow.appendChild(document.createTextNode('Yellow'));

var chkGreen = document.createElement("input");
chkGreen.type = "checkbox";
chkGreen.id = "chkGreen";
chkGreen.value = "Green";
chkGreen.checked = false;
var lblGreen = document.createElement('label')
lblGreen.htmlFor = "chkGreen";
lblGreen.style.color = "#0F0";
lblGreen.appendChild(document.createTextNode('Green'));

var dateFrom = document.createElement("input");
dateFrom.id = "txtDateFrom";
dateFrom.type = "text";
dateFrom.className = "datepicker";
dateFrom.style.width = "70px";
dateFrom.readonly = "readonly";
var lblDateFrom = document.createElement('label')
lblDateFrom.htmlFor = "txtDateFrom";
lblDateFrom.appendChild(document.createTextNode('From'));

var dateTo = document.createElement("input");
dateTo.id = "txtDateTo";
dateTo.type = "text";
dateTo.className = "datepicker";
dateTo.style.width = "70px";
dateTo.readonly = "readonly";
var lblDateTo = document.createElement('label')
lblDateTo.htmlFor = "txtDateTo";
lblDateTo.appendChild(document.createTextNode('To'));

var btnDone = document.createElement("input");
btnDone.type = "button";
btnDone.name = "btnDone";
btnDone.value = "Done";
btnDone.onclick = function () {
    dropdown.style.visibility = "hidden";
};

dropdown.appendChild(chkRed);
dropdown.appendChild(lblRed);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(chkYellow);
dropdown.appendChild(lblYellow);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(chkGreen);
dropdown.appendChild(lblGreen);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(dateFrom);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(dateTo);
dropdown.appendChild(document.createElement("BR"));
dropdown.appendChild(btnDone);

ShowContainerDiv.appendChild(btnShowDiv);
ShowContainerDiv.appendChild(dropdown);

g.event.addDomListener(btnShowDiv, 'click', function () {
    dropdown.visible = true;
    dropdown.style.visibility = "visible";
});

g.event.addDomListener(btnDone, 'click', function () {
    dropdown.visible = false;
    dropdown.style.visibility = "hidden";
});

map.controls[g.ControlPosition.TOP_RIGHT].push(ShowContainerDiv);

然后在一个 .js 文件中我有这个(我检查并包含该文件)

$(document).ready(function () {
    $(".datepicker").datepicker({
        dateFormat: 'yy/m/d',
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        showOn: 'both',
        autosize: true,
        buttonText: "Select date",
        buttonImage: '../Content/images/calendar.png',
        buttonImageOnly: true
    });
});

为什么没有显示日期选择器?

【问题讨论】:

    标签: javascript jquery jquery-plugins jquery-ui-datepicker


    【解决方案1】:

    当你写作时

    $(document).ready(function () {
        $(".datepicker").datepicker({...});
    });
    

    该片段在页面加载后立即执行。因此,您的动态日期选择器还不存在。您需要在每个新插入的元素上调用 $(aSuitableSelector).datepicker(...)。首先,使用 var 来保存您的选项:

    var datePickerOptions = {
        dateFormat: 'yy/m/d',
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        // ...
    }
    

    这让你可以写

     $(document).ready(function () {
        $(".datepicker").datepicker(datePickerOptions);
     });
    

    然后写

     // right after appending dateFrom to the document ...
     $(dateFrom).datepicker(datePickerOptions);
    
     //...
    
     // right after appending dateTo ...
     $(dateTo).datepicker(datePickerOptions);
    

    您还可以使用 JQuery 的listen to DOM changes 功能来避免将 JS 魔法应用于新插入的元素——但我认为这不值得。

    【讨论】:

    • 魔鬼在细节中!它通过使用创建的元素作为选择器(如您所示)而不是 $("#id") 来工作。我会尽快奖励赏金。
    • 实际上,它也可以与$(".datepicker") 一起使用...这是展示位置,而不是选择器在发挥作用。但是,将元素用作选择器可以避免将日期选择器重新应用于其他完全有效的日期选择器。
    • 感谢您的回答,非常有用!但是,您可以在最后一段中将“.datePicker”更改为“.datepicker”吗?函数名中没有大写的 p(“P”)。这看起来像是一个明显的语法错误,但我花了几分钟才弄清楚“TypeError: $(...)datePicker is not a function”是什么意思..
    • 即使将我的一段代码包装到$(window).load(function() { ...或$(document).ready(function() { ...我仍然无法使用选择器获取我的元素(使用$(“”),find( ), 伪类, ids, nth-child, ...)。结果的长度将始终为 0。
    • @Alex - 如果您要动态添加日期字段,则该新字段的选择器将无法工作直到添加该字段之后
    【解决方案2】:

    我发现为动态添加的多个输入字段添加日期选择器的最简单方法:

        $('body').on('focus',".datepicker", function(){
            $(this).datepicker();
        });
    

    【讨论】:

      【解决方案3】:

      你可以简单地使用它。

      $('body').on('focus',".date-picker", function(){
        $(this).datepicker();
      });
      

      【讨论】:

        【解决方案4】:

        我发现解决此问题的最简单方法是使用 livequery 插件:

        http://docs.jquery.com/Plugins/livequery

        您无需将日期选择器应用于特定类的所有对象,而是告诉 LiveQuery 将其应用于这些对象。 LiveQuery 将依次继续应用日期选择器,即使您的 DOM 稍后发生更改。

        usnig 时我没有看到性能下降,并且代码更改非常小(您需要将插件添加到页面并且只更改一行代码)。

        你会这样使用它:

        $(".datepicker").livequery(
                function(){ 
                    // This function is called when a new object is found. 
                    $(this).datepicker({ ...}});
                }, 
                function() { 
                    // This function is called when an existing item is being removed. I don't think you need this one so just leave it as an empty function.
                }
        ); 
        

        从那时起,每次你添加一个带有 datepicker 类的对象时,datepicker 插件都会自动应用到它。

        【讨论】:

        • 请注意,从 jQuery 1.7 开始,您可以通过委托事件处理程序 (api.jquery.com/on) 使用 .on() 方法。不过,如果您愿意,Livequery 仍然可以使用。
        【解决方案5】:

        绑定日期选择器的代码最好在您的 html 动态创建后立即执行。如果要将日期选择器初始化的代码保存在单独的文件中,我建议采用以下方法: 完成生成 html 后(我认为它是在准备好文档时生成的),使用

        $(document).trigger("customHtmlGenerated");
        

        并且在 datepicker 文件中,使用 $(document).bind("customHtmlGenerated", function(){...}); 代替 $(document).ready(function(){...})

        【讨论】:

          【解决方案6】:

          我把

          $( "#InstallDate" ).datepicker({
            showOn: "button",
              minDate: 0, // no past dates
            buttonImage: "../images/Date.png",
            buttonImageOnly: true,
            buttonText: "Select date",
            dateFormat: 'yy-mm-dd',
          }); 
          

          到脚本文件 DatePicker.js 中,然后在我生成的 Ajax Html 表单的末尾添加以下行

          <script type='text/javascript' src='/inc/DatePicker.js'></script> 
          

          【讨论】:

            【解决方案7】:
            $( ".datepicker" ).datepicker({inline: true,dateFormat: "dd-mm-yy"});
            

            【讨论】:

            • 在 jquery 中追加输入后使用的这一行和日期选择器工作正常
            • 此代码不适用于动态创建的 HTML!
            【解决方案8】:

            请在追加元素后添加以下代码。

            $(".datepicker").datepicker({
                    dateFormat: 'yy/m/d',
                    firstDay: 1,
                    changeMonth: true,
                    changeYear: true,
                    showOn: 'both',
                    autosize: true,
                    buttonText: "Select date",
                    buttonImage: '../Content/images/calendar.png',
                    buttonImageOnly: true
                });
            

            【讨论】:

              【解决方案9】:

              jQuery 代码在文档准备就绪时执行:这意味着页面的初始标记准备就绪时,而不是在您的 javascript 文件运行之后。

              我想你的初始化日期选择器的代码运行之前你的脚本创建元素,所以什么都没有发生。


              尝试在页面加载后使用.load() 而不是.ready() 执行您的jquery 代码。当所有资源(js、图片...)都加载完毕后,会触发 load 事件。

              $(window).load(function () {
                  $(".datepicker").datepicker({
                      ...
                  });
              });
              

              您也可以简单地使用 javascript 的执行方式。脚本按照它们在页面中出现的顺序执行。所以你可以:

              • 将脚本移动到结束正文标记 ```
              • 之前
              • 确保您的第一个脚本(创建元素)位于日期选择器代码之前
              • 删除日期选择器的 .ready() 处理程序。当您将脚本放在最后时,它们会在 DOM 准备好时隐式运行...

              【讨论】:

              • 同样的情况。我试过这个:(init 是创建 html 的函数) window.onload = function () { init(true); $(".datepicker").datepicker({...
              【解决方案10】:

              这可能是 javascript 被触发的顺序问题。试试把

              $(".datepicker").datepicker({
                  dateFormat: 'yy/m/d',
                  firstDay: 1,
                  changeMonth: true,
                  changeYear: true,
                  showOn: 'both',
                  autosize: true,
                  buttonText: "Select date",
                  buttonImage: '../Content/images/calendar.png',
                  buttonImageOnly: true
              });
              

              在创建 html 的 javascript 之后。

              【讨论】:

                猜你喜欢
                • 2015-08-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多