javascript - 当页面位于 iframe 中时,无法使用 javascript 选择单选按钮
问题描述
我在包含第二页的第一页上有一个 iframe。iframe 没有 id,所以我必须使用 javascript 为其分配一个。分配 ID 后,我尝试使用 javascript 单击其中包含值“女性”的单选按钮。但是,当我这样做时,我在控制台中收到一条错误消息:“错误:执行脚本'分类面孔'失败!无法读取属性'click' of null”。我究竟做错了什么?
var myframe = document.getElementsByTagName("iframe")[0];
myframe.id = "newID";
document.getElementById("newID").contentWindow.document.querySelector("input[value='female']").click();
第一页:
<iframe src="http://chatwithibot.com/test2.php"></iframe>
第二页:
<form action="/testx.php" method = "POST">
<input type="radio" name="gender" value="male"> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<input type="radio" name="gender" value="other"> Other
<input type="submit" value="Submit">
</form>
解决方案
window.frames
, .contentDocument
, &.contentWindow.document
页面加载时存在 iframe(非动态)
见演示 1
假设我们引用页面上的第一个(或唯一一个)iframe:
window.frames[0] document.getElementsByTagName('iframe')[0].contentDocument; // interchangeable document.querySelector('iframe').contentWindow.document; // interchangeable
将上面示例中的三行中的任何一行存储到一个变量中,然后将该变量视为document
.
var iframeDoc = window.frames[0]; var iframeInput = iframeDoc.querySelector('#input2');
简而言之,就是如何通过 iframe 以编程方式将标签从父页面访问到子页面。如果涉及用户的交互,例如用户单击子页面的单选按钮,则 iframe 的文档应使用.addEventListener()
或Oneevent 属性注册到单击事件。
iframeDoc.addEventListener('click', eventHandler);
事件处理iframeDoc
程序是单击时调用的函数。
function eventHandler(event) { console.log(event.target.value); }
eventHandler()
传递事件对象,然后引用属性Event.target。event.target
是对点击标签的直接引用(例如单选按钮)。该.value
属性后缀为event.target
获取点击标签的值。
iframe 被动态插入 DOM
见演示 2
当标签被动态添加到 DOM 时,它不能注册到任何事件。一种解决方法是通过注册动态标签(例如 iframe)的祖先标签(例如正文)来使用事件委托模式。eventHandler 必须从父页面上的祖先标记“深入”到 iframe 文档。有关可怕的细节,请参见演示 2。
演示 1
静态 iframe
注意:由于 SO 的安全措施,iframe 被削弱。此演示中的 iframe用于srcdoc
粗略表示 OP(原始帖子)代码的内容。
var xFrame = window.frames[0];
xFrame.onclick = extractValue;
function extractValue(e) {
console.log(e.target.value);
}
<iframe srcdoc='<form action="/testx.php" method="POST"><input type="radio" name="gender" value="male"> Male<br><input type="radio" name="gender" value="female"> Female<br><input type="radio" name="gender" value="other"> Other<br><br><input type="submit" value="Submit"></form>'></iframe>
普朗克
演示 2
动态 iframe
注意:可以在此Plunker上查看工作演示
/*
|| This is to simulate the iframe being dynamically inserted into the DOM.
|| This is not required for OP (Original Post) specific circumstance.
*/
document.body.insertAdjacentHTML('afterbegin', `<iframe src='test2.html'></iframe>`);
/* BEGINNING OF REQUIRED CODE */
/*
|| Register the body to the click event
|| function extractValue() is the event handler called when body is clicked.
*/
document.body.addEventListener('click', extractValue);
/* Event Handler */
/*
|| Reference the Document Object inside iframe
|| Reference the form tag inside Document Object of iframe
|| Reference all radio buttons name='gender' in the form tag
|| Reference the selected radio button
|| Log the selected radio button's value
*/
function extractValue(e) {
var xFrame = window.frames[0];
var xForm = xFrame.forms[0];
var xRads = xForm.elements['gender'];
var selected = xRads.checked;
console.log(selected.value);
}
推荐阅读
- visual-studio - 如何在 Visual Studio 中获得集成控制台?(如 CLion/IntelliJ)
- angular - 对导入的 scss 文件的更改不会触发重建
- sql-server - SQL Server Integration Services - 以编程方式选择要导入的文件
- powerbi - PowerBI 中的滚动平均值不包括当前月份
- r - 根据R中字符串变量的部分匹配过滤
- php - PHP将最后插入的行放入会话
- javascript - 带有 DynamoDB 解析器的 GraphQL - 一对多关系解决方案
- node.js - 如何通过 GitHub API 访问 Private Repository?
- unit-testing - 用 Jest 模拟 ApolloClient 的 client.query 方法
- java - 使用自定义 URL 在 Spring Boot 中创建一个肥皂端点