子页面和dialog案例

子页面和dialog案例 !DOCTYPE htmlhtmllangzh-CNheadmetacharsetUTF-8metanameviewportcontentwidthdevice-width, initial-scale1.0title子HTML弹窗 与 弹框 传参demo单文件/titlestyle:root{--primary:#4f6ef7;--primary-dark:#3b55d9;--bg:#f4f6fb;--card:#ffffff;--text:#1f2430;--text-secondary:#6b7280;--border:#e5e7eb;--success-bg:#eafaf0;--success-text:#1a7f4e;--radius:14px;}*{box-sizing:border-box;}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;background:var(--bg);color:var(--text);padding:40px 20px;}.container{max-width:760px;margin:0 auto;}h1{font-size:24px;font-weight:600;margin:006px;}.subtitle{color:var(--text-secondary);font-size:14px;margin:0032px;}.grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;}media(max-width:640px){.grid{grid-template-columns:1fr;}}.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:24px;display:flex;flex-direction:column;gap:14px;box-shadow:0 1px 3px rgba(0,0,0,0.04);}.card h2{font-size:16px;margin:0;display:flex;align-items:center;gap:8px;}.card p{font-size:13px;color:var(--text-secondary);margin:0;line-height:1.6;flex:1;}.badge{display:inline-block;font-size:11px;padding:3px 8px;border-radius:999px;background:#eef1ff;color:var(--primary-dark);width:fit-content;}button.action{background:var(--primary);color:#fff;border:none;border-radius:10px;padding:10px 16px;font-size:14px;cursor:pointer;transition:background .15s ease, transform .1s ease;}button.action:hover{background:var(--primary-dark);}button.action:active{transform:scale(0.98);}.result-box{margin-top:28px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:20px 24px;}.result-box h3{font-size:14px;margin:0012px;color:var(--text-secondary);font-weight:500;}.result-item{display:none;align-items:center;gap:10px;background:var(--success-bg);color:var(--success-text);padding:10px 14px;border-radius:10px;font-size:13px;margin-bottom:8px;}.result-item.show{display:flex;}.result-empty{font-size:13px;color:var(--text-secondary);}/* ---- 弹框模态对话框样式 ---- */ dialog{border:none;border-radius:16px;padding:0;width:min(380px,92vw);box-shadow:0 20px 60px rgba(0,0,0,0.18);}dialog::backdrop{background:rgba(20,20,30,0.35);}.modal-inner{padding:24px;}.modal-inner h3{margin:004px;font-size:17px;}.modal-inner .modal-sub{font-size:13px;color:var(--text-secondary);margin:0018px;}.field{margin-bottom:14px;}.field label{display:block;font-size:12px;color:var(--text-secondary);margin-bottom:6px;}.field input{width:100%;padding:9px 12px;border:1px solid var(--border);border-radius:8px;font-size:14px;outline:none;}.field input:focus{border-color:var(--primary);}.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:20px;}button.ghost{background:transparent;border:1px solid var(--border);border-radius:10px;padding:9px 16px;font-size:14px;cursor:pointer;color:var(--text);}button.ghost:hover{background:#f3f4f6;}/* ---- 代码片段展示 ---- */ pre.code{background:#1e2230;color:#e3e6f0;border-radius:10px;padding:14px 16px;font-size:12.5px;line-height:1.6;overflow-x:auto;margin:0;font-family:SFMono-Regular,Consolas,Courier New,monospace;}pre.code .kw{color:#7aa2f7;}pre.code .fn{color:#c0caf5;}pre.code .str{color:#9ece6a;}pre.code .com{color:#6b7280;}/style/headbodydivclasscontainerh1主页面单文件demo/h1pclasssubtitle演示两种向主页面传参的方式弹出子HTML窗口 vs 页内弹框全部写在同一个 html 文件里/pdivclassgriddivclasscardspanclassbadgewindow.open/spanh2① 打开子HTML页面/h2p点击后用 Blob 动态生成一个独立子页面并以弹出窗口形式打开不是新标签页。在子页面填写信息提交后通过 postMessage 把数据传回本页面随后子窗口自动关闭。/pbuttonclassactionidopenChildBtn打开子页面/buttonpreclasscodespanclasscom// 子页面打开弹出窗口/spanspanclasskwconst/spanurlURL.createObjectURL(blob);spanclassfnwindow.open/span(url,spanclassstrchildWindow/span,spanclassstrwidth380,height380/span);spanclasscom// 子页面把数据传回主页面/spanwindow.opener.spanclassfnpostMessage/span({type:spanclassstrCHILD_SUBMIT/span, payload: data},spanclassstr*/span);spanclasscom// 主页面接收数据/spanwindow.spanclassfnaddEventListener/span(spanclassstrmessage/span, e{spanclasskwconst/spandatae.data.payload;});/pre/divdivclasscardspanclassbadgelt;dialoggt;/spanh2② 打开弹框/h2p点击后在当前页面内弹出模态对话框不产生新窗口。填写并提交后直接调用主页面函数拿到数据。/pbuttonclassactionidopenModalBtn打开弹框/buttonpreclasscodespanclasscom// HTML弹框本体与主页面同属一个DOM/spanlt;spanclasskwdialog/spanidspanclassstrmyModal/spangt;...lt;/spanclasskwdialog/spangt;spanclasscom// 打开弹框/spanmodal.spanclassfnshowModal/span();spanclasscom// 提交时直接读取同页面的表单值/spanform.spanclassfnaddEventListener/span(spanclassstrsubmit/span, e{spanclasskwconst/spannamenameInput.value;spanclasscom// 无需跨窗口通信直接使用/span});/pre/div/divdivclassresult-boxh3接收到的数据/h3divclassresult-itemidchildResult/divdivclassresult-itemidmodalResult/divpclassresult-emptyidemptyTip暂无数据试试上面两个按钮/p/div/div!-- 弹框模态对话框本体与主页面同属一个DOM --dialogidmyModaldivclassmodal-innerh3填写信息弹框/h3pclassmodal-sub提交后数据直接传回主页面不会离开当前页面/pformidmodalFormmethoddialogdivclassfieldlabel姓名/labelinputtypetextidmodalNamerequiredplaceholder请输入姓名/divdivclassfieldlabel备注/labelinputtypetextidmodalNoteplaceholder选填/divdivclassmodal-actionsbuttontypebuttonclassghostidcancelModal取消/buttonbuttontypesubmitclassaction提交/button/div/form/div/dialogscriptvar emptyTipdocument.getElementById(emptyTip);var childResultdocument.getElementById(childResult);var modalResultdocument.getElementById(modalResult);functionshowResult(el, text){el.textContenttext;el.classList.add(show);emptyTip.style.displaynone;}// ---- ① 打开子HTML页面弹出窗口用 Blob 动态生成不需要单独的 html 文件 ---- document.getElementById(openChildBtn).addEventListener(click,function(){var childHtml[!DOCTYPE htmlhtml langzh-CNheadmeta charsetUTF-8,title子页面/title,style,body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;background:#fff;color:#1f2430;padding:22px;},h2{font-size:16px;margin:0 0 4px;},.sub{font-size:12px;color:#6b7280;margin:0 0 18px;},.field{margin-bottom:14px;},.field label{display:block;font-size:12px;color:#6b7280;margin-bottom:6px;},.field input{width:100%;padding:9px 12px;border:1px solid #e5e7eb;border-radius:8px;font-size:14px;box-sizing:border-box;outline:none;},.field input:focus{border-color:#4f6ef7;},.actions{display:flex;justify-content:flex-end;gap:8px;margin-top:20px;},button{border-radius:10px;padding:9px 16px;font-size:14px;cursor:pointer;border:1px solid #e5e7eb;background:#fff;color:#1f2430;},button.primary{background:#4f6ef7;color:#fff;border:none;},button.primary:hover{background:#3b55d9;},button:hover{background:#f3f4f6;},/style/headbody,h2我是子HTML页面/h2,p classsub这是一个独立的弹出窗口提交后会把数据传回打开它的主页面/p,form idchildForm,div classfieldlabel姓名/labelinput typetext idname required placeholder请输入姓名/div,div classfieldlabel邮箱/labelinput typeemail idemail required placeholder请输入邮箱/div,div classactionsbutton typebutton idcloseBtn取消/buttonbutton typesubmit classprimary提交并关闭/button/div,/form,script,document.getElementById(closeBtn).addEventListener(click, function(){ window.close(); });,document.getElementById(childForm).addEventListener(submit, function(e){, e.preventDefault();, var data { name: document.getElementById(name).value, email: document.getElementById(email).value };, if(window.opener){ window.opener.postMessage({ type: CHILD_SUBMIT, payload: data }, *); }, window.close();,});,\/script,/body/html].join();var blobnew Blob([childHtml],{type:text/html});var urlURL.createObjectURL(blob);// width/height 等参数是让浏览器以弹出窗口而非新标签页打开的关键 window.open(url,childWindow,width380,height380,left200,top150);});// 监听子窗口通过 postMessage 传回的数据 window.addEventListener(message, function(event){if(event.dataevent.data.typeCHILD_SUBMIT){var devent.data.payload;showResult(childResult,来自子页面: 姓名 d.name , 邮箱 d.email);}});// ---- ② 弹框模态对话框 ---- var modaldocument.getElementById(myModal);document.getElementById(openModalBtn).addEventListener(click,function(){modal.showModal();});document.getElementById(cancelModal).addEventListener(click,function(){modal.close();});document.getElementById(modalForm).addEventListener(submit, function(e){var namedocument.getElementById(modalName).value;var notedocument.getElementById(modalNote).value;showResult(modalResult,来自弹框: 姓名 name (note ?, 备注 note:));document.getElementById(modalForm).reset();});/script/body/html