2011-03-11 58 views
7

我有一個包含一些javascript的html組件。在(jQuery)ajax請求中獲取當前腳本DOM對象

該組件是一個模板引擎文件,因此它可以在整個HTML頁面

  • 通過Ajax請求呈現獨立的HTML元素的初始渲染使用

    的JavaScript應該在模板被應用到一個對象,即:

    <div class="grid" > 
        <div class="item" id="item_13"> 
         This is item 13 
        </div> 
        <div class="item" id="item_14"> 
         This is item 14 
        </div> 
    </div> 
    <script type="text/javascript"> 
        $(document).ready(function(){ 
         $(HOW_DO_I_GET_PREVIOUS_ELEMENT???).someEffect(params) 
        }) 
    </script> 
    

    我檢查了this similar question,但最好的答案似乎依賴於當前腳本是'腳本'變量中的最後一個,因爲下一個腳本尚未加載。如果我用ajax請求追加html和js,情況就不會如此。

    要100%清楚:問題是關於獲取前一個對象而沒有引用任何特定的屬性:沒有唯一的標識id,沒有隨機的id,理論上總是有機會顯示兩次,沒有唯一class屬性,因爲完全相同的組件可能會顯示在HTML文檔的另一部分中。

  • +0

    通過之前的元素,你的意思是$(「item_14」)?.如果是這樣,誰在創建這些ID?這聽起來像生成這些id的相同的東西可以很容易地告訴JavaScript插入它。 –

    +0

    由前面的元素我的意思是網格div。問題是關於引用前一個元素而不引用唯一id的可能性,因爲任何對象都可以在當前頁面的多個DOM對象中表示。對於這個問題,我通常將數字id引用放在class屬性中,而不是id。 id在這裏用於例子的緣故 –

    回答

    5

    涉及兩個步驟簡單的解決方案:

    1)找出哪些元素腳本標籤是

    2)發現,元素

    的代碼中的前一個兄弟:

    <div id="grid"> 
        <!-- ... --> 
    </div> 
    <script type="text/javascript"> 
        var scripts = document.getElementsByTagName("script"); 
        var current = scripts[scripts.length-1]; 
        var previousElement = current.previousSibling; 
        // there may be whitespace text nodes that should be ignored 
        while(previousElement!==null && previousElement.nodeType===3) { 
         previousElement = previous.previousSibling; } 
        if(previousElement!==null) { 
         // previousElement is <div id="grid"> in this case 
         $(document).ready(function(){ 
          $(previousElement).someEffect(params); 
         }); 
        } 
    </script> 
    

    這是不錯的網絡編程?不可以。您應該知道哪些元素應該根據您生成的內容對其應用效果。如果你有一個帶有id的div,那麼這個id是唯一的,你的生成器可以告訴如果它生成了div,它也必須生成爲其設置jQuery效果的js。

    但讓我們忽略它;它工作嗎?就像一個魅力。

    3

    如果你可以給你的<script/>塊一個Id,你可以很容易地撥打prev()獲得前一個元素。

    <script type="text/javascript" id="s2"> 
        $(document).ready(function(){ 
         $("#s2").prev().append("<h1>Prev Element</h2>"); 
        }) 
    </script> 
    

    jsfiddle的示例。

    +0

    [Monte Hayward](http://stackoverflow.com/users/738942/monte-hayward)的評論:「@Mark:腳本元素不支持id屬性,我們看到這會影響Chrome中的執行。http://www.w3.org/TR/REC-html40/interact/scripts.html#h-18.2.1「 –

    3

    您將需要獲得一種方法,在「網格」div之後立即引用腳本標記。正如@Mark所說,最簡單的方法是給腳本標籤一個唯一的ID。如果這是你無法控制的,但你有腳本內容的控制,你可以做這樣的事情(的事實,你正在創造它隱含的):

    var UniqueVariableName; 
    var scripts = document.getElementsByTagName('script'); 
    var thisScript = null; 
    for(var i = 0; i < scripts.length; i++){ 
        var script = $(scripts[i]); 
        if(script.text().indexOf('UniqueVariableName') >= 0){ 
         thisScript = script; 
         break; 
        } 
    } 
    if(thisScript){ 
        thisScript.prev().append("<h1>Prev Element</h2>"); 
    } 
    

    哈克?是。它工作嗎?另外,是的。

    0

    下面是在FF,Chrome和IE 8中可用的東西,在其他任何地方都可以使用。它查看頁面上最後一個元素(即正在分析的腳本)之前的元素,將其存儲在本地(使用自調用函數),以便負載處理程序可以使用它。

    http://jsfiddle.net/MtQ5R/2/

    <div class="grid" > 
        <div class="item" id="item_13"> 
         This is item 13 
        </div> 
        <div class="item" id="item_14"> 
         This is item 14 
        </div> 
    </div><script>(function(){ 
        var nodes = document.body.childNodes; 
        var prevSibling = nodes[nodes.length - 2]; 
    
        $(document).ready(function(){ 
         console.log(prevSibling); 
        }) 
    
    })();</script> 
    

    說了這麼多。我仍然必須提到,通過將行爲(JS)和HTML緊密耦合,將它們放入同一個文件中,這種文件與分離它們的Web流程相反。此外,我不知道你會如何期待這與AJAX請求一起工作,因爲你不只是將它添加到HTML中,因爲它正在呈現。在這種情況下,獲取對剛剛插入的html的引用將非常容易。