无法使用JavaScript访问自定义HTML标记内的DOM元素
我有几个后端Salesforce(SF)页面,有很长的下拉列表(比如多达1000个选项),我想在Chrome书签中使用JS代码向页面上的任意选择添加一个过滤器框(下面的代码)。我认为问题在于,我想要访问的节点位于一个名为无法使用JavaScript访问自定义HTML标记内的DOM元素,javascript,html,dom,iframe,Javascript,Html,Dom,Iframe,我有几个后端Salesforce(SF)页面,有很长的下拉列表(比如多达1000个选项),我想在Chrome书签中使用JS代码向页面上的任意选择添加一个过滤器框(下面的代码)。我认为问题在于,我想要访问的节点位于一个名为force aloha page的自定义HTML元素中 在我的例子中,我想要访问的第一个元素是自定义元素中的IFRAME。(这不是一个跨站点的安全问题,因为即使源代码不好,JS仍然会获得IFRAME,只是其中没有任何内容。) 例如,我可以检查代码并查看自定义HTML元素、ifra
force aloha page
的自定义HTML元素中
在我的例子中,我想要访问的第一个元素是自定义元素中的IFRAME。(这不是一个跨站点的安全问题,因为即使源代码不好,JS仍然会获得IFRAME,只是其中没有任何内容。)
例如,我可以检查代码并查看自定义HTML元素、iframe,以及页面上iframe的内容。如果我只是将节点转储到控制台中,它会显示JS无法访问的DOM元素:
document.getElementsByTagName(“FORCE-ALOHA-PAGE”)[0]
…代码>
force aloha页面
元素中看到div
和iframe
。但是,如果我尝试访问iframe,会发生以下情况:
document.getElementsByTagName('IFRAME')
0
document.querySelectorAll(“iframe”)
0
document.getElementsByTagName(“FORCE-ALOHA-PAGE”)。长度
1
document.getElementsByTagName(“FORCE-ALOHA-PAGE”)[0].childNodes.length
0
document.getElementsByTagName(“FORCE-ALOHA-PAGE”)[0]。innerHTML
”
<html>
<body>
<select>
<option value="1">1</option>
<option value="10">10</option>
<option value="2">2</option>
<option value="20">20</option>
</select>
<br /><br />
<select>
<option value="Apples">Apples</option>
<option value="Berries">Berries</option>
<option value="Candies">Candies</option>
<option value="Danishes">Danishes</option>
</select>
<br /><br />
<iframe src="testpage2.html"></iframe>
</body>
</html>
1.
10
2.
20
苹果
浆果
糖果
丹尼斯
testpage2.html
<html>
<body>
<select>
<option value="3">3</option>
<option value="30">30</option>
<option value="4">4</option>
<option value="40">40</option>
</select>
<br /><br />
<select onchange="selectChange(this)">
<option value="Eclaires">Eclaires</option>
<option value="Frozen Custard">Frozen Custard</option>
<option value="Grapes">Grapes</option>
<option value="Heath Bar">Heath Bar</option>
</select>
<script type="text/javascript">
function selectChange(el) {
console.log("Select value: " + el.value);
}
</script>
</body>
</html>
3.
30
4.
40
埃克莱利斯
冷冻奶油冻
葡萄
健康酒吧
功能选择更改(el){
控制台日志(“选择值:+el.value”);
}
书签代码(扩展以提高可读性):
javascript:(函数(){
//返回主页面或iframes中所有选择的数组
变量选择=函数(d){
变量a=[],
s=d.getElementsByTagName('SELECT'),
b=d.getElementsByTagName('IFRAME');
对于(var i=0;i,下面的代码片段应该可以工作
//查询DOM中的所有iframe
var iframesNodes=document.queryselectoral(“iframe”);
//将节点列表转换为数组
var iframes=Array.prototype.slice.call(iframesNodes);
控制台日志(iframes);
//循环遍历所有iframe
map(函数(iframe){
//获取当前iframe的文档
var innerDoc=iframe.contentDocument | | iframe.contentWindow.document;
/*…然后对iframe文档执行任何您想要的操作*/
innerDoc.body.style.backgroundColor=“#ff0000”
});
强制aloha页面的元素可能是一个,这可能解释了为什么不能访问内部DOM,因为它是一个
尝试使用shadowRoot
属性访问它,如下所示:
class ForceAlohaPage扩展HtmleElement{
构造函数(){
超级();
这是阿塔奇沙多({
模式:“打开”
}).innerHTML='';
}
}
自定义元素。定义(“强制aloha页面”,强制ALOHAPAGE);
log(document.getElementsByTagName('iframe').length);
console.log(document.getElementsByTagName(“force aloha page”)[0].childNodes.length);
log(document.getElementsByTagName(“force aloha page”)[0].innerHTML);
console.log(document.getElementsByTagName('force-aloha-page')[0].shadowRoot.childNodes[0]);
谢谢您的建议。不幸的是,document.querySelectorAll(“iframe”)
仍然返回一个0长度的数组,而我可以从源代码和DOM检查器中清楚地看到文档中有一个iframe。我对force aloha页面的工作原理知之甚少,但我的直觉告诉我这可能是一个时间问题,在您尝试访问其内容时,它仍然是空的,所以您得到的是什么ck是准确的。您可以尝试在大约5秒钟的超时时间内包装对querySelector的调用,以检查该理论。这是假设force aloha page正在异步执行某些操作。@ThomasPreston我正在执行的代码来自一个Chrome书签,每当我单击该书签时该书签都会运行。上面显示的控制台代码示例我是r在Chrome控制台中运行。我在页面完全加载后运行良好,它们都应该可以完全访问页面上的任何DOM元素。force-aloha页面
是web组件吗?您可以检查其构造函数
属性,该属性应该类似于class-ForceAlohaPage-extensed-HTMLElement
或HTMLUnknown元素
。您还可以检查是否在DOM(在强制aloha页面
内)Boom!shadow DOM FTW中看到#shadow root
。在控制台中运行此命令:文档。getElementsByTagName('force-aloha-page')[0]。shadowRoot.childNodes[0]。childNodes[0]
。在回复中得到了这样的信息:
同样,我不太确定它是否能让我在IFRAME中获得任何东西,但这对于另一篇文章来说是个问题:-)很高兴它有帮助!
javascript:(function(){
//return an array of all selects in the main page or in iframes
var selects=function(d){
var a=[],
s=d.getElementsByTagName('SELECT'),
b=d.getElementsByTagName('IFRAME');
for(var i=0;i<s.length;i++)
a.push(s[i]);
for(var i=0;i<b.length;i++){
try{
a=a.concat(selects(b[i].contentWindow.document));
}catch(e){
console.log(e);
}
}
return a;
},
//makes the SELECT border blink and scrolls it into view
blink=function(els,i){
if(i>=els.length)return;
var el=els[i],s=el.style,t=200,
nb='3px solid blue',eb=s.border+'';
el.scrollIntoView();
s.border=nb;
setTimeout(function(){s.border=eb;},t);
setTimeout(function(){s.border=nb;},t*2);
setTimeout(function(){
s.border=eb;
if(confirm("This one?")){
filter(el);
}else{
blink(els,i+1);
}
},t*3);
},
//helper for creating options on a select
opt=function(v,t,p){
var y=document.createElement('OPTION');
y.value=v;
y.text=t;
p.appendChild(y);
},
//creates the new filter input and adds it to the page
filter=function(el){
console.log('Filtering...');
var d=document,c=d.createElement('INPUT'),o=[];
c.type='text';
c.placeholder='Filter list';
c.style.width=el.style.width;
c.style.display='block';
el.parentNode.insertBefore(c,el);
//filters the option list when something is typed
c.onkeyup=function(ev){
var j=c.value+'',h=el.options,x=0;
if(o.length==0){
for(var e=0;e<h.length; e++){
with(h[e]){
o.push({'v':value,'t':text});
}
}
}
for(var g=h.length-1;g>=0;g--)el.remove(g);
for(var i=0;i<o.length; i++){
if(j.length==0){
opt(o[i].v,o[i].t,el);
}else{
if(match(o[i].t,j)){
if(x==0) opt('','',el);
opt(o[i].v,o[i].t,el);
x++;
}
}
}
if(x>0) el.options[0].text='<'+x+' Match(es) Found>';
};
},
//determines if the option text matches the filter criteria, with wildcard support
match=function(a,b){
a=(a+'').toLowerCase();
b=(b+'').toLowerCase();
if(b.indexOf('*')<0){
return a.indexOf(b)>=0;
}else{
var r='.*',c=b.split('*');
for(var i=0;i<c.length;i++){
r+='.*'+(c[i].length>0?'('+c[i]+')':'');
}
r+='.*';
return (new RegExp(r)).test(a);
}
},
d=document,s=selects(d),v=[];
//gets only SELECTs that are visible on the page
for(var i=0;i<s.length;i++){
if (window.getComputedStyle(s[i]).display !== 'none')
v.push(s[i]);
}
console.log('SELECTs: '+s.length);
console.log('Visible SELECTs: '+v.length);
//Begin.
blink(v,0);
})();