如何用js操作iframe框架内的内容

问题概述

本周正在做一个自动识别题目的小工具,便于一键录入题目,使用了正则匹配和js操作input表单的操作,当中出现了一个问题,就是在浏览器console当中调试的时候,总是在一个document.querySelector("#textarea").value = optionA返回Cannot set property 'value' of null,但当我多点几次表单再执行js的时候又运行成功了,非常疑惑

问题思路

Cannot set property 'value' of null的意思是这个对象没有找到,所以不能赋值

可能是说明document内没有这个对象,仔细观察源码,发现使用了frame子框架架构导致不能直接document找到这个元素

问题解决

使用iframe.contentDocument这个js api来获取iframe的document对象即可

例子

var iframe = document.getElementById("iframe1");
var iwindow = iframe.contentWindow;
var idoc = iwindow.document;
console.log("window",iwindow);//获取iframe的window对象
console.log("document",idoc); //获取iframe的document
console.log("html",idoc.documentElement);//获取iframe的html
console.log("head",idoc.head); //获取head
console.log("body",idoc.body); //获取body

具体iframe父子关系如图

具体源码

这边顺便放个正则匹配内容的代码

//此处建议放一个input获取内容
var str = "37、财务业绩指标通常包括( )。 A:资本报酬率 B:经济增加值  C:客户保持率 D:客户盈利率 答案:AB "
//利用正则表达式匹配
var title = str.match("(?<=[0-9]、).*?(?=A)")[0];  
var optionA = str.match("(?<=A:).*?(?=B)")[0];  
var optionB = str.match("(?<=B:).*?(?=C)")[0];  
var optionC = str.match("(?<=C:).*?(?=D)")[0];  
var optionD = str.match("(?<=D:).*?(?=答案)")[0];  
var ans = str.split("答案:")[1]

//console.log(title); // "财务业绩指标通常包括( )。 "
//console.log(ans); // "AB "

//切换到框架内进行操作
var iframe = document.querySelector("html > frameset > frameset > frame")
var iwindow = iframe.contentWindow;
var idoc = iwindow.document;

//给对应表单赋值
idoc.querySelector("#qnTx").value = title
idoc.querySelector("input[name='qnS1']").value = optionA
idoc.querySelector("input[name='qnS2']").value = optionB
idoc.querySelector("input[name='qnS3']").value = optionC
idoc.querySelector("input[name='qnS4']").value = optionD
idoc.querySelector("input[name='qnSn']").value = ans
//是否是多选
idoc.querySelector("input[name='qnMC']").checked = (ans.length>1) ? true : false

然后就可以正常执行了

参考资料

  1. 利用JS对iframe父子(内外)页面进行操作的方法教程