gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 02:20:14 25 4
gpt4 key购买 nike

我有几个后端 Salesforce (SF) 页面,其中包含非常长的下拉列表(例如多达 1,000 个选项),我想在 Chrome 书签中使用 JS 代码将筛选框添加到页面上的任意 SELECT(代码以下)。我认为这个问题是因为我想要访问的节点位于一个名为 force-aloha-page 的自定义 HTML 元素中。 .

在我的例子中,我想要访问的第一个元素是自定义元素中的 IFRAME。 (这不是跨站点安全问题,因为即使来源不好,JS 仍会获得 IFRAME,只是其中没有任何内容。)

例如,我可以检查代码并查看自定义 HTML 元素,查看 iframe,并且可以在页面上查看 iframe 的内容。如果我只是将节点转储到控制台,它会显示 JS 无法访问的 DOM 元素:

  • document.getElementsByTagName("FORCE-ALOHA-PAGE")[0]
  • <force-aloha-page data-data-rendering-service-uid=​"203" data-aura-rendered-by=​"505:​0" force-alohapage_alohapage-host>​<div force-alohapage_alohapage class=​"iframe-parent slds-template_iframe slds-card">​<iframe force-alohapage_alohapage height=​"100%" width=​"100%" scrolling=​"yes" allowtransparency=​"true" name=​"vfFrameId_1569557364522" title=​"Page Configuration" allowfullscreen=​"true" lang=​"en-US" allow=​"geolocation *;​ microphone *;​ camera *">​…​</iframe>​</div>​</force-aloha-page>​

我可以看到 diviframeforce-aloha-page里面元素。但是,如果我尝试访问 iframe,就会发生这种情况:

  • document.getElementsByTagName('IFRAME')
  • 0
  • document.querySelectorAll("iframe")
  • 0

JS可以看到自定义元素:

  • document.getElementsByTagName("FORCE-ALOHA-PAGE").length
  • 1

但里面什么也没有:

  • document.getElementsByTagName("FORCE-ALOHA-PAGE")[0].childNodes.length
  • 0

即使上面的“节点转储”起作用了,但这不起作用:

  • document.getElementsByTagName("FORCE-ALOHA-PAGE")[0].innerHTML
  • ""

进入 iframe 后,我可能会遇到其他问题,但我必须先通过自定义标记。

我尝试过的

我在 Chrome 中创建了 JS 书签,它适用于主页中的 SELECT 和具有良好 XSS 的 IFRAME 内部。但不适用于自定义标签内的 SELECT。这是我写书签代码时用的测试页。

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>

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>

书签代码(展开以提高可读性):

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

在我的 JS 代码中,我还尝试创建一个遍历所有子节点的递归函数,但是,正如我在上面发布的控制台示例所示,JS 为自定义元素返回 0 个子节点。

最佳答案

force-aloha-page 元素可能是一个 Web component ,这可能解释了为什么您无法访问内部的 DOM,因为它是一个 Shadow DOM。 .

尝试使用 shadowRoot 属性访问它,如下所示:

class ForceAlohaPage extends HTMLElement {

constructor() {
super();
this.attachShadow({
mode: 'open'
}).innerHTML = '<iframe force-alohapage_alohapage height="100%" width="100%" scrolling="yes" allowtransparency="true" name="vfFrameId_1569557364522" title="Page Configuration" allowfullscreen="true" lang="en-US" allow="geolocation *; microphone *; camera *"></iframe>';
}
}

customElements.define("force-aloha-page", ForceAlohaPage);

console.log(document.getElementsByTagName('iframe').length);

console.log(document.getElementsByTagName("force-aloha-page")[0].childNodes.length);

console.log(document.getElementsByTagName("force-aloha-page")[0].innerHTML);

console.log(document.getElementsByTagName('force-aloha-page')[0].shadowRoot.childNodes[0]);
<force-aloha-page></force-aloha-page>

关于javascript - 无法使用 JavaScript 访问自定义 HTML 标记内的 DOM 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58110847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com