2016-11-24 75 views
4

我在做一个相当简单的事情在JS中:我测试如果一个元素(基于类名)包含一个字符串。JS不能在第一次加载 - 在刷新后工作

我认为它不工作的原因是因为该元素通过单独的onload事件的HTTPS请求在页面上呈现。 (有点像嵌入/ iFrame类型的东西)。我有脚本的

例子:

(function($) { 

//Only run on a specific page. 
if(window.location.href.indexOf("SpecificPageImRunningOn") > -1) { 

    //Wait for 3 seconds before running this script, to allow content to load 
    setTimeout(function(){ 

     //Check if a class contains a string "Foobar" 
     if($('.aSpecificClass').text().indexOf('Foobar') != -1){ 
      alert("Yes!"); 
     } 
     else{ 
      alert("No!"); 
     } 

    }, 3000); 

} 

})(jQuery); 

当我测试这第一次轮(新鲜清除浏览器的缓存),它并没有达到预期效果。

一旦我刷新,它工作得很好。

我试过手动触发函数(通过点击一个按钮后,一切都加载),它仍然没有任何不同的行为。它在第一次加载时根本不起作用。

我也尝试过通过设置一个cookie来进行一次强制刷新,这似乎没有任何区别。

我想我错过了一些明显的东西!

Test

回答

0

通过在运行动作之前每隔100ms检查一次window.model(我们定位的框架内加载的内容)来解决此问题。

示例代码:

(function($) { 

//Only run on a specific page. 
if(window.location.href.indexOf("SpecificPageImRunningOn") > -1) { 

    function holdOnRecheck() { 
     //check if window.model has been defined and that it is not Null before running code. If conditions are not met, wait for 100ms then run the function holdOnRecheck again. 
     if (window.model !== undefined && window.model !== null) 
     { 
      //window model has loaded - good. Now check if the content we are targetting in particular within the model has loaded (judging by its length). If not, wait for 100ms then run the function holdOnRecheck again. 
      if (window.model.ABC.length > 0) 
      { 
       //If you got this far, it's safe to assume that the content has loaded within the model, so you can run whatever you want on the content and it should do something. 
       if($('.aSpecificClass').text().indexOf('Foobar') != -1){ 
        alert("Yes!"); 
       } 
       else{ 
        alert("No!"); 
       } 
       //finish by hiding loading spinner 
       document.getElementById("loading").style.display = "none"; 
      } 
      else 
      { 
       window.setTimeout(holdOnRecheck, 100); 
      } 
     } 
     else 
     { 
      window.setTimeout(holdOnRecheck, 100); 
     } 
    } 

} 
})(jQuery); 
4

你不应该依赖超时等因素,以准备就绪。第一次运行它时,元素当时还没有准备好,而第二次是因为它在第一次运行后被缓存了。

在关闭body标记之前,将脚本放在页面的底部,或者在DOM准备就绪后使用$(document).ready()回调来运行一次。

+0

谢谢,我已经试过$(文件)。就绪(),不幸的是这并没有改变行为。我期望这是因为我正在研究的元素是外部资源。 – Tim

+3

哦,这是外在的,对不起,我错过了。在这种情况下,您需要在该extenal元素上使用侦听器,而不是文档(如'$('iframe')。ready()')。你永远不应该依靠一次超时。 – Shomz

+0

其实,上面的评论可能并非如此,基于文档(但我可以发誓,我很久以前使用它,它的工作):''作为jQuery 3。0,只推荐第一种语法;其他语法仍然有效,但不推荐使用。这是因为选择与.ready()方法的行为没有关系,这是低效的,可能会导致对方法行为的错误假设。例如,第三种语法与不选择任何内容的“文档”一起工作。第四种语法等待文档准备就绪,但意味着(不正确)它等待图像准备就绪。“' – Shomz

0

正如@Shomz指出的那样,setTimeout不是一个很好的方法来做你想做的事。有两种可能的方法,我建议:

使用jQuery文档准备事件

//Only run on a specific page. 
if(window.location.href.indexOf("SpecificPageImRunningOn") > -1) { 
    $(function() { 
     //Check if a class contains a string "Foobar" 
     if($('.aSpecificClass').text().indexOf('Foobar') != -1){ 
     alert("Yes!"); 
     } 
     else { 
     alert("No!"); 
     } 
    }); 
} 

使用窗口加载事件

这是当准备功能无法正常工作,就像当你正试图验证该元素是否为外部资源为图像:

//Only run on a specific page. 
if(window.location.href.indexOf("SpecificPageImRunningOn") > -1) { 
    $(window).on("load", function() { 
     //Check if a class contains a string "Foobar" 
     if($('.aSpecificClass').text().indexOf('Foobar') != -1){ 
     alert("Yes!"); 
     } 
     else { 
     alert("No!"); 
     } 
    }); 
} 
+1

你为什么要重复我的问题dy说? – Shomz

+0

使用窗口加载区别于其他方式。 –

相关问题