我在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来做一次强制刷新,这似乎没有任何区别。
我想我错过了一些明显的东西!
答案 0 :(得分:5)
您不应该依赖超时来等待元素准备就绪。第一次运行它时,元素当时没有准备好,而第二次是因为它在第一次运行后被缓存。
在关闭getBooks(): Observable<Book[]> {
return Observable.create(observer => {
const res: Book[] = [];
this._af.database
.list('/books').subscribe(books => {
books.map(book => {
this.getAuthor(book.author).subscribe(author => {
res.push(
new Book(book.$key, book.title, author.lastName, book.price, book.image)
);
if (res.length === books.length) {
observer.next(res);
}
})
});
});
});
}
标记之前将脚本放在页面底部,或者在DOM准备就绪后使用$(document).ready()
回调运行一次。
答案 1 :(得分: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!");
}
});
}
使用窗口加载事件
这就是当ready函数不能正常工作时,比如当你试图验证元素是否是一个外部资源作为图像时:
//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!");
}
});
}
答案 2 :(得分:0)
通过在运行操作之前每100毫秒反复检查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);