jQuery Datepicker在新打开的空白窗口中无法正常工作
解决window.open新窗口中jQuery Datepicker报错问题
问题场景
尝试在window.open打开的空白新窗口中应用jQuery Datepicker,点击按钮创建元素并调用datepicker()时出现错误,将新窗口设置为_parent时功能正常。
原代码
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Datepicker - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css"> <link rel="stylesheet" href="/resources/demos/style.css"> <script src="https://code.jquery.com/jquery-3.6.0.js"></script> <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script> </head> <body> </body> </html> <script> const button = document.createElement('button'); button.id = 'button'; document.body.appendChild(button); $('#button').on('click', function() { newWindow = window.open('', '_blank', 'width=700, height=1000'); var div = newWindow.document.createElement('div'); div.style.textAlign = "center"; div.id = "div_riaszt_kuldes"; newWindow.document.body.appendChild(div); input2 = $('<input id="datepicker" type="text">', [,newWindow.document.body]); $(input2).appendTo(newWindow.document.body); $(input2).datepicker(); }); </script>
报错信息
jquery-3.6.0.js:6401 Uncaught TypeError: Cannot read properties of null (reading 'defaultView') at getStyles (jquery-3.6.0.js:6401:33) at curCSS (jquery-3.6.0.js:6585:25) at Function.css (jquery-3.6.0.js:6996:10) at jquery-3.6.0.js:7145:12 at access (jquery-3.6.0.js:4203:15) at jQuery.fn.init.css (jquery-3.6.0.js:7127:10) at datepicker_getZindex (jquery-ui.js:7333:19) at HTMLInputElement._showDatepicker (jquery-ui.js:8130:31) at HTMLInputElement.dispatch (jquery-3.6.0.js:5430:27) at elemData.handle (jquery-3.6.0.js:5234:28)
错误核心表现为elem.ownerDocument为null对象。
问题根源
- 新窗口资源缺失:空白新窗口未加载jQuery和jQuery UI脚本/样式,父窗口的jQuery跨窗口操作元素时,上下文不匹配导致DOM属性识别异常。
- DOM未就绪:直接创建元素后立即调用
datepicker(),新窗口的DOM可能还未完全初始化。 - jQuery上下文错误:创建input时的上下文参数写法错误,未正确关联新窗口的document。
解决方案
方案1:写入完整HTML到新窗口(推荐)
打开新窗口后,直接写入包含jQuery、jQuery UI资源的完整HTML结构,等待窗口加载完成后初始化datepicker:
$('#button').on('click', function() { const newWindow = window.open('', '_blank', 'width=700, height=1000'); // 写入新窗口的完整HTML,包含必要的依赖资源 newWindow.document.write(` <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-3.6.0.js"></script> <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script> </head> <body> <div id="div_riaszt_kuldes" style="text-align:center"></div> <input id="datepicker" type="text"> </body> </html> `); newWindow.document.close(); // 关闭文档写入流 // 监听新窗口加载完成事件,初始化datepicker newWindow.addEventListener('load', function() { newWindow.$('#datepicker').datepicker(); }); });
方案2:动态注入依赖资源到新窗口
如果不想重写整个HTML,可以动态向新窗口注入jQuery、jQuery UI的脚本和样式,确保上下文正确:
$('#button').on('click', function() { const newWindow = window.open('', '_blank', 'width=700, height=1000'); const newDoc = newWindow.document; // 创建并添加div const div = newDoc.createElement('div'); div.style.textAlign = "center"; div.id = "div_riaszt_kuldes"; newDoc.body.appendChild(div); // 创建input并添加到新窗口 const input2 = $('<input id="datepicker" type="text">', newDoc); input2.appendTo(newDoc.body); // 动态注入jQuery脚本 const jqueryScript = newDoc.createElement('script'); jqueryScript.src = "https://code.jquery.com/jquery-3.6.0.js"; newDoc.head.appendChild(jqueryScript); jqueryScript.onload = function() { // 注入jQuery UI脚本 const uiScript = newDoc.createElement('script'); uiScript.src = "https://code.jquery.com/ui/1.13.2/jquery-ui.js"; newDoc.head.appendChild(uiScript); // 注入jQuery UI样式 const uiCss = newDoc.createElement('link'); uiCss.rel = "stylesheet"; uiCss.href = "//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css"; newDoc.head.appendChild(uiCss); // 等待UI脚本加载完成后初始化datepicker uiScript.onload = function() { newWindow.$('#datepicker').datepicker(); }; }; });
关键说明
- 必须确保新窗口拥有独立的jQuery和jQuery UI环境,避免跨窗口上下文冲突。
- 等待新窗口的DOM或资源加载完成后再调用
datepicker(),确保元素的ownerDocument正常可用。
内容的提问来源于stack exchange,提问作者Csirmaz Kalman
相关产品推荐
相关产品推荐

