Javascript 如何在运行脚本之前检查页面上是否加载了元素?
因此,我在我的公司模板中创建我的页面,这只允许我们访问页面的主体。我们没有访问head标签的权限,页面下部加载了一些脚本,我们没有访问权限。其中一个脚本会将元素动态加载到页面上。我需要在该元素上运行另一个脚本,但由于该元素在脚本运行之前不会加载到页面上,因此我无法访问该元素。在运行脚本之前,是否有办法检查页面上是否已经加载了该元素 如果我需要更好地解释,请告诉我Javascript 如何在运行脚本之前检查页面上是否加载了元素?,javascript,jquery,html,Javascript,Jquery,Html,因此,我在我的公司模板中创建我的页面,这只允许我们访问页面的主体。我们没有访问head标签的权限,页面下部加载了一些脚本,我们没有访问权限。其中一个脚本会将元素动态加载到页面上。我需要在该元素上运行另一个脚本,但由于该元素在脚本运行之前不会加载到页面上,因此我无法访问该元素。在运行脚本之前,是否有办法检查页面上是否已经加载了该元素 如果我需要更好地解释,请告诉我 <head>Don't have access</head> <body> <!-
<head>Don't have access</head>
<body>
<!--Needs to manipulate the element created by the companyScript.js-->
<script src="myScript.js"></script>
<!--Script that runs after mine, which I don't have access too-->
<script src="companyScript.js">
/*Dynamically adds <div class="element"></div> to page*/
</script>
</body>
没有访问权限
/*动态添加到页面*/
这将检查元素是否以每秒10倍的速度存在,一旦存在,它将立即执行您的代码
2020版,有承诺
/**
*在解析承诺之前等待元素
*@param{String}querySelector-要等待的元素的选择器
*@param{Integer}timeout-超时前等待的毫秒数,或0表示无超时
*/
函数waitForElement(querySelector,超时=0){
const startTime=new Date().getTime();
返回新承诺((解决、拒绝)=>{
常量计时器=设置间隔(()=>{
const now=new Date().getTime();
if(document.querySelector(querySelector)){
清除间隔(计时器);
解决();
}else if(timeout&&now-startTime>=超时){
清除间隔(计时器);
拒绝();
}
}, 100);
});
}
waitForElement(“#idOfElementToWaitFor”,3000)。然后(函数(){
警报(“元素已加载..执行任务”);
}).catch(()=>{
警报(“元件在3秒内未加载”);
});
原始答案
听起来像是一份工作
MutationObserver
类似于事件侦听器:您可以将其附加到任何DOM元素以侦听更改:
var observer = new MutationObserver(function (mutationRecords) {
console.log("change detected");
});
回调传递一个MutationRecord
s数组,其中包含添加/删除/修改的节点的不同列表
然后,我们将观察者附加到任何节点:
observer.observe(document.body, {childList: true});
// second argument is a config: in this case, only fire the callback when nodes are added or removed
注:(惊喜,惊喜)仅适用于IE 11。(不过,Edge支持它。)
下面是关于检测DOM更改的另一个问题:
片段:
document.querySelector(“按钮”).addEventListener(“单击”),函数(){
document.body.appendChild(document.createElement(“span”);
});
var观察者=新的变异观察者(函数(m){
如果(m[0]。已添加节点[0]。节点名称==“SPAN”)
document.querySelector(“div”).innerHTML+=“检测到更改
”;
});
observer.observe(document.body,{childList:true})代码>
点击
我建议不要使用MutationObserver。这种方法有很多缺点:页面加载速度慢,浏览器支持差。在某些情况下,这是解决手头问题的唯一方法
更好的方法是使用onload DOM事件。此事件适用于iframe和img等标记。对于其他标记,这是您可以从中获得灵感的伪代码:
已加载函数(事件){
警报(event.target.previousSibling.previousSibling.id);
}
这是一个示例div,用于观察它的加载
这里有一个用ClojureScript编写的函数,它在满足条件时调用某个函数
(需要“[cljs.core.async:作为:参考[
然后你可以做类似的事情
等待条件((id)=>document.getElementById(id),()=>警报(“它发生了”))
或
(等待条件#)(js/document.getElementById)
#(js/alert“它发生了”)
:频率250
:超时(10)
扩展@i-graffled-a-bear-once的解决方案。
有了这个js代码,当目标组件不再存在于DOM中时,我们也可以禁用弹出窗口
它可以用于您请求的文件输入,并且在他完成请求后不想显示文件的情况
// Call this to run a method when a element removed from DOM
function waitForElementToUnLoad(querySelector) {
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(!document.querySelector(querySelector)) {
clearInterval(timer);
resolve();
}
}, 1000);
});
}
// Call this to run a method when a element added to DOM, set timeout if required.
// Checks every second.
function waitForElementToLoad(querySelector, timeout=0) {
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(document.querySelector(querySelector)){
clearInterval(timer);
resolve();
}else if(timeout && now - startTime >= timeout){
clearInterval(timer);
reject();
}
}, 1000);
});
}
// Removing onclose popup if no file is uploaded.
function executeUnloadPromise(id) {
waitForElementToUnLoad(id).then(function(){
window.onbeforeunload = null;
executeLoadPromise("#uploaded-file");
});
}
// Adding onclose popup if a file is uploaded.
function executeLoadPromise(id) {
waitForElementToLoad(id).then(function(){
window.onbeforeunload = function(event) {
return "Are you sure you want to leave?";
}
executeUnloadPromise("#uploaded-file");
});
}
executeLoadPromise("#uploaded-file");
我想知道如何改进此功能。编写一个脚本,将脚本附加到页面底部,以便在If($('.element').length)之后加载
使用添加元素的代码来运行会影响该元素的代码。需要更好地理解问题,以获得更高质量的答案和更少的错误guessing@johnny5这与是否存在动态添加的元素无关。是的,我看到我在事后删除了它!;-)如此简单…但却有效!唯一一段代码有效地在Angular上工作:调用ngAfterViewInit()上的函数
就这样!谢谢!我喜欢你的2020代码,你能解释一下waitForElement函数中的if语句吗?这是一个非常好的代码,需要一些解释,但是这段代码做的是检测元素是否被加载,然后做一些事情,这段代码没有做的是在加载元素时做一些事情@Mathew-承诺就是这样做的,它让你在等待其他事情的时候做一些事情。if
语句只是检查元素是否存在。如果你遵循这种方法,这个特定的问题可以通过多种方式解决,比如你可以观察脚本标记的加载,然后使用javascript动态加载另一个脚本。
// Call this to run a method when a element removed from DOM
function waitForElementToUnLoad(querySelector) {
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(!document.querySelector(querySelector)) {
clearInterval(timer);
resolve();
}
}, 1000);
});
}
// Call this to run a method when a element added to DOM, set timeout if required.
// Checks every second.
function waitForElementToLoad(querySelector, timeout=0) {
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(document.querySelector(querySelector)){
clearInterval(timer);
resolve();
}else if(timeout && now - startTime >= timeout){
clearInterval(timer);
reject();
}
}, 1000);
});
}
// Removing onclose popup if no file is uploaded.
function executeUnloadPromise(id) {
waitForElementToUnLoad(id).then(function(){
window.onbeforeunload = null;
executeLoadPromise("#uploaded-file");
});
}
// Adding onclose popup if a file is uploaded.
function executeLoadPromise(id) {
waitForElementToLoad(id).then(function(){
window.onbeforeunload = function(event) {
return "Are you sure you want to leave?";
}
executeUnloadPromise("#uploaded-file");
});
}
executeLoadPromise("#uploaded-file");