2011-09-27 38 views
3

由於ID衝突,我的應用程序出現問題。該應用程序基本上使用AJAX加載用戶需求的代碼片段。這些片段非常不同,但有時,代碼片段使用與HTML標記中的另一個ID相同的ID。HTML中單獨的「名稱空間」

想象用戶請求片斷1和獲取此:

.... 
<input id="myvar" type="checkbox" name="myname" /> 
.... 

該片段是通過JQuery.load()添加到主頁代碼

然後,用戶請求內容片段2,並得到:

.... 
<div id="myvar">....</div> 
.... 

在這一刻,有具有相同ID 2個不同的HTML標籤,所以當應用程序不會:

$("#myvar").something() 

結果未定義。

所以,問題是我不知道是否可以使用任何JavaScript或HTML功能或技巧在HTML中分割代碼片段。

由於每個片段都有一個關聯的JavaScript代碼來處理它,並且需要訪問代碼段DOM,所以不能在加載時爲所有ID加上前綴。

好消息:片段完全隔離在頁面上。頁面結構是這樣的:

<html> 
    <head>...</head> 
    <body> 
    <div id="header">...</div> 
    <div id="common_controls">...</div> 
    <div id="snippets"> 
     <div class="snippet" id="snippet-1"> 
     // Snippet 1 code here 
     </div> 
     <div class="snippet" id="snippet-2"> 
     // Snippet 2 code here 
     </div> 
    </div> 
    </body> 
</html> 

任何想法?

編輯:我無法控制片段內容,因此它不是使用特定ID名稱的選項。

+4

所有的ID必須是唯一的;這是底線。這是應該和可以管理的東西服務器端 - 你沒有提到一個框架,但我認爲這不只是一個平面文件的HTML頁面? – Widor

+0

正如@Widor所說,[id必須是唯一的](https://developer.mozilla.org/en/DOM/element.id#Notes)。 – Eric

+0

是的,這是問題所在。我無法管理非唯一ID,這不是一個好習慣,但我不能強迫用戶這樣做,而且如果我這樣做,某些用戶可能會犯錯。服務器端的問題是我可以修改HTML片段,但不能修改其相應的JavaScript代碼片段,所以如果我更改了ID,此JavaScript代碼片段將無法找到它所需的DOM項目。 – Ivan

回答

3

最好的解決方案是將每個代碼片段嵌入到單獨的IFRAME中,因爲ID可能不是唯一導致衝突的項目。

  • 嚴重依賴文檔的默認CSS /腳本屬性的片段可能因腳本衝突而失敗。
  • ,在全球範圍扔變量腳本代碼段可以與其它段
  • 腳本片段引用一個特定類別的索引(class="specific")干擾也將由於衝突含有
  • 片段<script>將不被執行打破插入時在HTML中,雖然它可能對片段的外觀很重要。

Et cetera。只需將這些片段嵌入腳本iframe中即可解決這些可能的問題。

EDIT
幀可以很容易地與母體(甚至跨域)通過postMessage通信。當你在同一個域中時,交流更容易。

您可能正在尋找一種更簡單的方法來在子框架之間進行通信。那麼,考慮本實施例中(相同的域僅):

JS:

//Snippet from frame 1 
var othersnippet = parent.frames["othersnippet"].contentWindow; 
othersnippet.getspecialMethod(); //Custom function, EXAMPLE 
  • parent(在框架內)= top,它指的是Window對象
  • window.frames是一個對象它是指按名稱引用一個文檔中的所有框架。 注: 「在文檔」 doen't包括幀幀)

HTML:

<iframe name="othersnippet" /> 
<!-- No id needed, because you access frames through the 
    window.frames[name] property--> 
+0

關於第4點:如果您需要某種方法不在腳本/ iframe中執行腳本/嵌入內容,請參閱我的配置文件。我目前正在爲其他兩個問題開發這樣的功能。 –

+0

HTML純代碼和javascript代碼之間沒有衝突,因爲它們來自不同的來源(服務器清除

0

只是一個想法:

如果您知道片段將永遠是高於(或低於)重複的內容#ID,你也許能夠做這樣的事情:

if ($('#myvar').length == 1) {run function} //no offending repeat #id 
else {$('#myvar').eq(1) . . . } //repeating #id, refer to the second instance 
3

它consid在HTML中無效多次使用相同的ID,正如您所看到的那樣會導致問題。

如果你有在Ajax代碼的輸出控制,最好的解決辦法是,以防止它從同一個ID多次輸出。您沒有提供足夠的信息讓我能夠爲您提供如何實現這一目標的大量幫助,但它當然應該是可能的。

如果相同的ID來自不同的Ajax調用,您可以確保每個Ajax調用產生的所有ID前綴都是唯一的名稱(可能是產生它們的代碼塊的模塊名稱?)。

如果他們來自同一個代碼來了,你應該是很有可能產生相同ID的唯一原因是,如果你輸出相同的數據多次到頁面上。即使在這裏也會有解決方案,但在這種情況下,我需要了解更多有關應用程序的信息。

但在任一情況下,如所描述的問題似乎是與通過jQuery訪問它。好消息是jQuery實際上非常容忍重複的ID。

如果只是讓它與jQuery一起工作的情況下,那麼你應該能夠得到它的工作,而無需修復實際的重複。只要你可以運行一個選擇器來選擇你想要的唯一一個,那麼jQuery將會非常高興。

如果你想這樣做,只是換用其自己獨特的ID在<div>每個Ajax響應,然後你可以使用如下的嵌套選擇參考一式兩份:

$("#ajaxblock1 #myvar").something() 
$("#ajaxblock2 #myvar").something() 

這在jQuery中工作得很好。

但是,我不能擔保在CSS中能夠很好地工作,並且標準DOM getElementById()函數也會嚇倒,所以如果您打算使用除jQuery以外的其他任何東西,那麼您會想要重複你的ID。

+0

更改ID不是可能由於他們有相關的JavaScript代碼(不是由應用程序控制)。如果你的想法很有效,你可以節省我的一天!檢查.. :) – Ivan

相關問題