2011-06-04 66 views
0

我想通过将网页加载到iframe中来解析网页的HTML,然后在DOM上进行一些搜索。下面的代码jQuery .find()偶尔找不到

function f(callback) { 
    var tmp = document.createElement('iframe'); 
    $(tmp).hide(); 
    $(tmp).insertAfter($('foo')); 
    $(tmp).attr('src', url); 

    $(tmp).load(function() { 
     var bdy = tmp.contentDocument.body; 
     callback(bdy); 
     $(tmp).remove(); 
    }); 
} 

在回调函数,如果我这样做了以下

function callback(bdy) { 
    alert($(bdy).find('bar').length); 
} 

有时它给了我正确的值,但有时它给了我而不是0。但是,如果我做了以下工作原理

var tmp = document.createElement('iframe'); 
$(tmp).hide(); 
$(tmp).insertAfter($('foo')); 
$(tmp).attr('src', url); 

$(tmp).load(function(tmp) { 
    setTimeout(function() { 
     var bdy = tmp.contentDocument.body; 
     callback(bdy); 
     $(tmp).remove(); 
    }, '100'); 
}); 

由于的setTimeout()取决于客户端的结束,我想知道是否有任何更好的方法来达到同样的目的。谢谢。

回答

0

检查this问题,以及其许多答案和相关问题。


更新;这里的一些代码,等待#bar获得加载:

function f(callback) { 
    var tmp = document.createElement('iframe'), 
     $tmp = $(tmp); 
    $tmp.hide() 
     .insertAfter($('foo')) 
     .attr('src', url); 

    $tmp.load(function() { 
     var bdy = tmp.contentDocument.body, 
      $bdy = $(bdy); // small optimization 

     var waitForBar = function() { 
      if($bdy.find('#bar').length > 0) { 
       callback(bdy); 
       $tmp.remove(); 
      } else 
       setTimeout(waitForBar, 50); 
     }; 
     waitForBar(); 
    }); 
} 
+0

我使用的是接受的解决方案,从那里,但它并没有解决我的问题。我注意到,即使我直接在网站上应用我的功能,而不是将其加载到iframe中,它也无法一直工作。 – nichehole 2011-06-04 13:26:00

+0

在你的回调中,如果你尝试'alert($(bdy))',你会得到什么结果?或者更好,如果你使用的是FireBug或Chrome,请执行'console.log($,bdy,$(bdy),$(bdy).find('#bar'))'并评论你的结果? – Simeon 2011-06-05 19:34:51

+0

如果我做'alert($(bdy))',它总会给我'[object HTMLBodyElement]'。使用铬,一个'console.log($,bdy,$(bdy),$(bdy).find('#bar'))'总是给我'功能(a,b){return new e.fn. init(a,b,h)}',然后在控制台中输入''节点,但是偶尔会给我一个包含'#bar''的节点。 我怀疑网页通过一些JavaScript将包含'##bar''的节点添加到DOM中,有时在它做到之前,jquery认为该页面已经完成加载了?行! – nichehole 2011-06-06 04:34:39