2010-01-08 26 views
8

我將iframe中的body元素的html設置爲一個字符串str,然後我想在下一行訪問該內容(這裏只是使用alert調用來顯示內容),但是html和append函數避難所在警報聲明被調用之前完成。如何讓你的代碼等待html()和append()函數來完成?

$(function(){ 
.... 
$("#notes-tab span.add_draft").bind("click", function(e){ 
    var str = ''; 
    $(this).parent().siblings(".tab-content").children(".para").each(function(ind) { 
     str += $(this).find('div:first').html(); 
    }); 
    var curr = $("#content_rte").contents().find("body").html(); 
    if (curr == ' ' || curr == '<br>') { 
     $("#content_rte").contents().find("body").html(str); 
    } 
    else { 
     $("#content_rte").contents().find("body").append(str); 
    } 
    alert($("#content_rte").contents().find("body").html()); 
}); 
}); 

當然,html和append函數都沒有回調函數。

有人能告訴我一個人在繼續之前是如何正常完成等待DOM更改的嗎?

+0

這是從你的$(document).ready()函數中調用嗎? – 2010-01-08 21:17:38

回答

-7

有真正爲等待的時間超過設置任意超時等你嘗試檢索HTML之前沒有直接的方法。這樣做的代碼是:

// wait for 250 ms, then try and retrieve contents 
setTimeout(function() { 
    alert($("#content_rte").contents().find("body").html()); 
}, 250); 

你應該嘗試做超時小到足以被忽視,但大到足以允許內容更新,所以你可以比250ms的少得多脫身。

+3

不好的答案,你永遠不會知道在這裏選擇什麼樣的價值。這將適用於99%的客戶,並且只有1%實際上帶來了大部分現金...... – 2011-08-16 18:45:51

+3

是的,可怕的答案,儘管它可能適用於大多數情況。競賽狀況如何? (http://en.wikipedia.org/wiki/Race_condition) – 2013-02-27 16:50:41

+0

考慮https://api.jquery.com/load-event/ – talabes 2015-07-23 19:23:41

0

您應該嘗試使用$(window).load(function())而不是document.ready,並且您可以隨時在附加後觸發事件。這樣事件將只在附加成功呈現後才運行。

window.load只在dom加載後運行,然後運行dom中的所有內容。

如果這不適合你,那麼你可以總是有一個setTimeout()運行在document.ready或window.load上,並把你的函數/事件放在那裏,它會在特定的秒數之後加載。

你可以嘗試:

$(document).ready(function(){ 
    var curr = $("#content_rte").contents().find("body").html(); 
    if (curr == ' ' || curr == '<br>') { 
     $("#content_rte").contents().find("body").html(str); 
    } 
    else { 
     $("#content_rte").contents().find("body").append(str); 
    } 
}); 
$(window).load(function(){ 
    alert($("#content_rte").contents().find("body").html()); 
}); 
2

htmlappend都呼叫domManip,這是一個同步方法,所以alert甚至不應該執行,直到這些調用完成。

您確定您期望的值被複制到您期望的位置嗎?

+0

同意。 @Craig,追加是否成功? 此外,append()返回jQuery。您可以在不搜索第二次的情況下獲取html內容。 – 2010-01-08 21:29:12

+0

是的,附加和html寫入成功,在警報顯示空白後成功。 我沒有意識到append返回任何東西。 – Craig 2010-01-09 00:28:44

+0

@Craig,你能發佈一個公共鏈接到你的頁面或重現問題的頁面版本嗎? – 2010-01-09 03:43:52

1

你需要等待DOM加載事件,這樣的iframe有時間來完成加載:

$(document).ready(function(){ 
    var str = '<div>HelloWorld</div>'; 
    var curr = $("#content_rte").contents().find("body").html(); 
    if (curr == ' ' || curr == '<br>') { 
     //$("#content_rte").contents().find("body").html(str); 
     $("#content_rte").contents().find("body").append(str); 
    } 
    else { 
     $("#content_rte").contents().find("body").append(str); 
    } 
    alert($("#content_rte").contents().find("body").html()); 
}); 
+0

你可能不得不聽iframe的ready事件(「#content_rte」)。contents()。ready(fuction(){...}); – jjacka 2010-01-08 21:06:18

+0

它不會準備好它會加載準備好定義DOM元素的完整呈現加載是DOM和DOMS元素都是他們需要的 – 2010-01-08 21:20:55

0

您需要使用$(document).ready(function(){ })$(function(){ })但與iframe的文檔元素。

要做到這一點,你可以把你的腳本到iframe的HTML

theIframeHTMLContent += '<script type="text/javascript" src="jquery.js"></script>' + 
         '<script type="text/javascript">' + 
          '$(function(){ alert("I\'m ready!"); });' + 
         '</script>'; 

$('body').append('<iframe id="cool"></iframe>'); 
$('#cool').html(theIframeHTMLContent); 

或者你可以嘗試做新追加的iframe的DOM元素本身,而是從父框架。這在瀏覽器中是不同的,但下面的例子應該工作。

$('body').append('<iframe id="cool"></iframe>') 
var theFrame = $('#cool')[ 0 ]; 
var docEl = theFrame.contentDocument || theFrame.contentWindow || theFrame.document; 
$(docEl).ready(function(){ /* ready stuff */ }); 

告訴我,如果我錯了,就像我說的,沒有測試過這個。

11

如果您使用的是jQuery,您可以依靠.closest()來確定您剛剛創建的元素是否具有父標body標記,如果是,則表示它已被添加到DOM。您可以編寫一個函數,如下面,讓你真正做一些事情時,你的元素準備就緒:

callWhenReady: function (selector, callback, scope) { 
    var self = this; 
    if ($(selector).closest('body').length) { 
     callback.call(scope); 
    } else { 
     setTimeout(function() { 
      self.callWhenReady(selector, callback, scope); 
     }, 1); 
    } 
} 
+0

我喜歡這個!在選擇器不匹配任何元素時,應該在開始處添加「if(!$(selector).length)return;'」以避免無限循環。 – flu 2013-05-30 09:29:53

0

我跟着grancalavera的答案,但我用lengh因爲我的選擇已經在體內存在。 ..所以:

var finalLength = $(selector).html().length + data.length; 
$(selector).html(data); //or $(selector).append(data); 
//... 
callWhenReady: function (selector, callback, finalLength, scope) { 
    var self = this; 
    if ($(selector).html().length === finalLength) { 
     callback.call(scope); 
    } else { 
     setTimeout(function() { 
      self.callWhenReady(selector, callback, scope); 
     }, 1); 
    } 
}