Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用JavaScript访问自定义HTML标记内的DOM元素_Javascript_Html_Dom_Iframe - Fatal编程技术网

无法使用JavaScript访问自定义HTML标记内的DOM元素

无法使用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

我有几个后端Salesforce(SF)页面,有很长的下拉列表(比如多达1000个选项),我想在Chrome书签中使用JS代码向页面上的任意选择添加一个过滤器框(下面的代码)。我认为问题在于,我想要访问的节点位于一个名为
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
JS可以看到自定义元素:

  • document.getElementsByTagName(“FORCE-ALOHA-PAGE”)。长度
  • 1
但里面什么都没有:

  • document.getElementsByTagName(“FORCE-ALOHA-PAGE”)[0].childNodes.length
  • 0
尽管上述“节点转储”有效,但这并不:

  • document.getElementsByTagName(“FORCE-ALOHA-PAGE”)[0]。innerHTML
一旦进入iframe,我可能会遇到一个完全不同的问题,但我必须首先通过定制标记

我尝试过的

我在Chrome中创建了JS书签,它可以在主页和IFRAMEs中使用良好的XSS进行选择。但不适用于自定义标记内的选择。这是我在编写书签代码时使用的测试页面

testpage1.html

<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);
})();