2011-11-14 49 views
4

我有一個應用程序需要從隱藏的輸入表單字段中檢索一個值。然而,這個應用程序有它調用另一頁是在iframe基頁,然後它也可以調用本身另一iFrame中:getElementById 3種方式

的default.asp - > screen.asp(在iFrame中) screen.asp - > screen.asp的(在iFrame中)

document.getElementById('focusValue').value 
window.frames[0].document.getElementById('focusValue').value 
parent.frames[arrVal].document.getElementById('focusValue').value 

當我從默認參考隱藏的輸入表單字段的新實例 - >屏幕我可以使用標準的document.getElementById('focusValue').value;。然後當我在第一級iFrame時,我必須使用window.frames[0].document.getElementById('focusValue').value;。然後,當我在iFrame中的2+級別時,我必須使用parent.frames[arrVal].document.getElementById('focusValue').value;

說我開始看到一個常見的結構是這樣的:

if(document.getElementById('focusValue') == undefined){ 
     window.frames[0].document.getElementById('focusValue').value = focusValue; 
     console.log('1'); 
}else if((parent.frames.length -1) == arrVal){ 
     console.log('2'); 
     if (arrVal > 0) { 
      parent.frames[arrVal].document.getElementById('focusValue').value = focusValue; 
     } 
}else{ 
    document.getElementById('focusValue').value = focusValue; 
    console.log('3'); 
} 

現在,我當然可以這樣做,但寫評論的新價值之外我很擔心其他的程序員(或者我1從現在開始)看着這段代碼,並想知道我在做什麼。

我的問題是有沒有一種方法可以實現我在標準格式中要做的事情?我真的希望有更好的方法來實現這一點。

+0

這就是爲什麼發明評論。記錄你在做什麼。 – Gerben

回答

1

我建議你讓每個頁面通過調用一個方法來找到你想要的值。基本上暴露一個查找界面。然後,您只需要從父頁面調用目標頁面上的方法。正確的命名將幫助開發人員理解正在發生的事情,使用方法將簡化邏輯。

或者,如果您只需要從父頁面獲取值,則可以使用通用界面在iframe中的每個頁面上註冊一個鉤子。每個頁面都可以調用該鉤子來獲取值。這會阻止您確定頁面的級別的複雜邏輯。像

iframe1.GetValueHook = this.GetValue; 
iframe2.GetValueHook = this.GetValue; 

東西然後,每個頁面可以叫

var x = this.GetValueHook(); 

如果您有嵌套頁面,你可以把這個遞歸。如果您需要所有頁面之間的通信,則使用相同的方法,但需要註冊過程。每個頁面註冊自己(和它的孩子)與它的父母。但是如果你需要這樣做,那麼你應該重新評估你的架構。

實施例: register.js

var __FRAMENAME = "Frame1"; 
var __FIELDID = "fieldId"; 
var __frames = []; 

function RegisterFrame(frame) { 
    __frames.push(frame); 

    for (var i = 0; i < frame.children.length; i++) { 
     __frames.push(frame.children[i]); 
    } 

    RegisterWithParent(); 
} 

function RegisterWithParent() { 

    var reg = { 
     name: __FRAMENAME, 
     getvalue: GetFieldValue, 
     children: __frames 
    }; 

    if(parent != undefined && parent != this) { 
     parent.RegisterFrame(reg); 
    } 
} 

function SetupFrame(name, fieldId) { 
    __FRAMENAME = name; 
    __FIELDID = fieldId; 

    RegisterWithParent(); 
} 

function GetFieldValue() { 
    return document.getElementById(__FIELDID).value; 
} 

function GetValueFrom(name) { 
    for (var i = 0; i < __frames.length; i++) { 
     if (__frames[i].name == name) { 
      return __frames[i].getvalue(); 
     } 
    } 

} 

的index.html

<html> 
<head> 
<script language="javascript" type="text/javascript" src="register.js"></script> 
</head> 
<body> 

PAGE 

<input type="hidden" id="hid123" value="123" /> 
<iframe id="frame1" src="frame1.html"></iframe> 
<iframe id="frame2" src="frame2.html"></iframe> 
<script type="text/javascript"> 
    SetupFrame("Index", "hid123"); 

    setTimeout(function() { //Only here for demonstration. Make sure the pages are registred 
     alert(GetValueFrom("frame3")); 
    }, 2000); 
</script> 
</body></html> 

幀1。HTML

<html> 
<head> 
<script language="javascript" type="text/javascript" src="register.js"></script> 
</head> 
<body> 
<input type="hidden" id="hid" value="eterert" /> 
<script type="text/javascript"> 
    SetupFrame("frame1", "hid"); 
</script> 
</body></html> 

frame2.html

<html> 
<head> 
<script language="javascript" type="text/javascript" src="register.js"></script> 
</head> 
<body> 
<input type="hidden" id="hid456" value="sdfsdf" /> 
<iframe id="frame2" src="frame3.html"></iframe> 
<script type="text/javascript"> 
    SetupFrame("frame2", "hid456"); 
</script> 
</body></html> 

frame3.html

<html> 
<head> 
<script language="javascript" type="text/javascript" src="register.js"></script> 
</head> 
<body> 
<input type="hidden" id="hid999" value="bnmbnmbnm" /> 
<script type="text/javascript"> 
    SetupFrame("frame3", "hid999"); 
</script> 
</body></html> 

這將是更好,如果你可以改變它使用字典/哈希tbale而不是循環。

+0

我從來沒有使用/看到GetValueHook屬性。你有任何解釋它的鏈接嗎?即使iFrame是遞歸的(相同的頁面,但給定不同的元素ID),這會工作嗎? – webdad3

+0

它不是一個屬性,它將是一個由腳本聲明的全局函數指針。我會寫一個演示併發布它 – ILovePaperTowels

+0

@jeff我已經更新了我的答案以包含代碼示例。 – ILovePaperTowels

0

如果你真的必須爲給定的元素搜索幀,那麼你應該創建自己的函數來做到這一點,並在任何地方使用該函數。在函數中解釋了爲什麼/在做什麼以及賦予函數一個有意義的名稱的許多註釋,以便將來的程序員看到代碼時更明顯地看你正在做什麼,或者他們可以在哪裏找到你想要的東西這樣做。

function setValueByIdFrames(name) { 
    if(document.getElementById(name) == undefined){ 
     window.frames[0].document.getElementById(name).value = name; 
     console.log('1'); 
    } else if((parent.frames.length -1) == arrVal){ 
     console.log('2'); 
     if (arrVal > 0) { 
      parent.frames[arrVal].document.getElementById(name).value = name; 
     } 
    } else { 
     document.getElementById(name).value = name; 
     console.log('3'); 
    } 
} 
+1

我同意除了這仍然需要一堆複雜和脆弱的邏輯。 – ILovePaperTowels

+0

@ILovePaperTowels - 如果期望的對象的位置不是事先知道的(幀之間的),那麼它是複雜和脆弱的應用程序的設計,這是最好的。顯然,修復應用程序的設計會更好,因此不必搜索多個框架即可找到給定的對象。 – jfriend00

+0

@ jfriend00 - 我同意這可能是正確的解決方案(可以解決整體問題的解決方案),但是,此代碼被埋在幾年前的巨型.js文件中。根據你的建議,需要重複代碼,這在我看來可能會導致其他問題(即改變某個地方而不改變另一個地方)。儘管關於架構我當然看到你的觀點。 – webdad3

1

最好的辦法就是設置正確命名的可變參數,以便它自我記錄。像這樣的東西...

var screenFrame = window.frames[0]; 
var screenFrame2 = parent.frames[arrVal]; 

var value = screenFrame2.document.getElementById('focusValue').value 

這將使它更容易閱讀。

+0

我看到你要去那裏,但不幸的是,可能會有多達7層!我知道,這很醜陋,但這正是我正在處理的。 – webdad3

+0

@JeffV更好的辦法是把它全部放在一個頁面上,你可以創建一個函數,讓你回到你需要的框架。 7嵌套iframe是很多,應該快速重新設計! – JTWebMan