Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/76.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 如何在运行脚本之前检查页面上是否加载了元素?_Javascript_Jquery_Html - Fatal编程技术网

Javascript 如何在运行脚本之前检查页面上是否加载了元素?

Javascript 如何在运行脚本之前检查页面上是否加载了元素?,javascript,jquery,html,Javascript,Jquery,Html,因此,我在我的公司模板中创建我的页面,这只允许我们访问页面的主体。我们没有访问head标签的权限,页面下部加载了一些脚本,我们没有访问权限。其中一个脚本会将元素动态加载到页面上。我需要在该元素上运行另一个脚本,但由于该元素在脚本运行之前不会加载到页面上,因此我无法访问该元素。在运行脚本之前,是否有办法检查页面上是否已经加载了该元素 如果我需要更好地解释,请告诉我 <head>Don't have access</head> <body> <!-

因此,我在我的公司模板中创建我的页面,这只允许我们访问页面的主体。我们没有访问head标签的权限,页面下部加载了一些脚本,我们没有访问权限。其中一个脚本会将元素动态加载到页面上。我需要在该元素上运行另一个脚本,但由于该元素在脚本运行之前不会加载到页面上,因此我无法访问该元素。在运行脚本之前,是否有办法检查页面上是否已经加载了该元素

如果我需要更好地解释,请告诉我

<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");