[英]mirror <details> and checkbox state across iframe
我有一个 iFrame 可以在其内部加载其父页面。 因此,同一页面的两个副本; iFrame 中的一个,一个不是。
我正在尝试在主页和 iFrame 之间镜像<input type="checkbox">
checked/unchecked
和<details>
open/closed
的 state。
我已经解决了每个部分(请参阅问题的// comments
),触发click
事件:
对于复选框,我有
let boxes = document.querySelectorAll('input[type="checkbox"]');
for (let box of boxes)) {
myIFrame.getElementById(box.id).checked = box.checked; // works
if (inIFrame) {parent.getElementById(box.id).checked = document.getElementById(box.id).checked; // doesn't work
}
(上面的条件inIFrame
只是测试检查页面是否加载到 iFrame 中的简写)
而对于<details>
let detailEls = document.querySelectorAll('details');
for (let i = 0; i < detailEls.length; i++) {
myIFrame.querySelectorAll('details')[i].open = querySelectorAll('details')[i].open; // works, but 1-click behind
}
但奇怪的是,这滞后了一个点击。 所以如果我点击,点击,点击打开主页上的详细信息A,B,C,只有A,B会在iFrame中打开——下一次点击,Z0D61F8370CAD1D412F80B84D143E12会打开。
如果不清楚,这是我的问题的摘要:
<details>
state 滞后? 这似乎与复选框的策略相同,但结果不同。谢谢!
这是一个演示您想要的行为的复制品,通常遵循您的模式:
https://stackblitz.com/edit/so-mirror-iframe?file=lib/script.js
没有完整的代码很难说,但这里有一些需要考虑的事情:
如果您在详细信息上使用click
事件,那可能会给您带来“滞后”行为。 事实证明,对于详细信息, click
事件发生在其open
属性更新之前。 当您的同步器运行时,您刚刚单击的那个总是读入错误的 state。
toggle
事件,在更新open
属性后触发。 假设它不是第一个代码块中的错字, parent
是对父window的引用,而不是它的document 。
parent.document.getElementById
。 好的,您使用的逻辑将无法按照您的意愿mirror vice-versa
,所以我将在WINDOW 和 IFRAME的click
基础上进行
这是我的回复,这是一个链接(请在新标签中打开)
这是概念:
iframe
和window 上mirrored
的元素的window
。 These arrays are made in the same way so that the keys/indexes
each relate to their equivalent in the separate window( window.boxes[0]
is the first box in window and childWindow.boxes[0]
is the first box in iframe )addEventListener
块中看到的async
部分。 你会看到我await
一个 promise 的timeout
,持续0 ms
,但是像这样的异步函数是如何工作的,它会等到它没有阻塞任何东西,然后 RUN 。 这就是为什么它忽略了detail
栏给出的滞后效应window.html
<html><h2>WINDOW</h2>
<iframe id="iframe" width="500" height="300" src="/"></iframe>
<details>.</details>
<details>..</details>
<details>...</details>
<details>....</details>
<details>.....</details>
<input type="checkbox">Hm</input>
<input type="checkbox">Hmm</input>
<input type="checkbox">Hmmm</input>
<input type="checkbox">Hmmmm</input>
<input type="checkbox">Hmmmmm</input>
<script>(async()=>{
window.iframe=document.getElementById('iframe') //iframe
window.childWindow=iframe.contentWindow //window to iframe
window.waitFinish=async function(){ //needful waiting
await new Promise(r=>setTimeout(r,0))
}
window.boxes = [...document.querySelectorAll('input[type="checkbox"]')] //checkboxes
window.details = [...document.querySelectorAll('details')] //details
//wait for iframe to finish loading(if you're doing this manually by the time you begin it'd be finished loading so no worries)
await new Promise(r=>{
let s=setInterval(()=>{
if(typeof childWindow.details=="object"){
clearInterval(s); return r(1)
}
},0)
})
//window to iframe
boxes.forEach((box,index)=>{
box.addEventListener("click",async(ev)=>{
await waitFinish()
childWindow.boxes[index].checked=box.checked
})
})
details.forEach((detail,index)=>{
detail.addEventListener("click",async(ev)=>{
await waitFinish()
childWindow.details[index].open=detail.open
})
})
//iframe to window
childWindow.boxes.forEach((box,index)=>{
box.addEventListener("click",async(ev)=>{
await waitFinish()
window.boxes[index].checked=box.checked
})
})
childWindow.details.forEach((detail,index)=>{
detail.addEventListener("click",async(ev)=>{
await waitFinish()
window.details[index].open=detail.open
})
})
})()</script>
</html>
iframe.html
<html><h2>IFRAME</h2>
<i><a target="_blank" href="https://iframe-mirror.paultaylor2.repl.co">Full Page</a></i>
<details>.</details>
<details>..</details>
<details>...</details>
<details>....</details>
<details>.....</details>
<input type="checkbox">Hm</input>
<input type="checkbox">Hmm</input>
<input type="checkbox">Hmmm</input>
<input type="checkbox">Hmmmm</input>
<input type="checkbox">Hmmmmm</input>
<script>
window.boxes = [...document.querySelectorAll('input[type="checkbox"]')] //checkboxes
window.details = [...document.querySelectorAll('details')] //details
</script>
</html>
你犯了一个小错误。 你的代码是:
for (let box of querySelectorAll('input[type="checkbox"]')) {
myIFrame.getElementById(box.id).checked = box.checked; // works
if (inIFrame) {parent.getElementById(box.id).checked = getElementById(box.id).checked; // doesn't work
}
什么时候需要
for (let box of querySelectorAll('input[type="checkbox"]')) {
myIFrame.getElementById(box.id).checked = box.checked; // works
if (inIFrame) {parent.getElementById(box.id).checked = document.getElementById(box.id).checked; // works now that it's fixed
}
您忘记了document
object 作为父级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.