簡體   English   中英

在JavaScript中引用ID控件的ASP.NET控件?

[英]Reference ASP.NET control by ID in JavaScript?

當ASP.NET控件呈現時,它們的ID有時會發生變化,就像它們位於命名容器中一樣。 Button1在渲染時實際上可能具有ctl00_ContentMain_Button1的id。

我知道您可以在.cs文件中將JavaScript編寫為字符串,獲取控件的clientID並使用clientscript將腳本注入到頁面中,但有沒有一種方法可以使用ASP.NET Ajax直接從JavaScript引用控件?

我發現編寫一個函數以遞歸方式解析dom並找到一個控件來保存我想要的id是不可靠的,所以我一直在尋找最佳實踐而不是解決方法。

Dave Ward的這篇文章可能有你想要的東西:

http://encosia.com/2007/08/08/robust-aspnet-control-referencing-in-javascript/

摘自文章:

的確有。 更好的解決方案是使用內聯ASP.NET代碼注入控件的ClientID屬性:

 $get('<%= TextBox1.ClientID %>') 

現在引用了正確的客戶端元素ID,無論頁面的結構和控件的嵌套級別如何。 在我看來,這種方法的非常小的性能成本非常值得讓您的客戶端腳本更容易適應變化。

Dave的一些示例代碼來自該帖子的評論帖子:

<script>
  alert('TextBox1 has a value of: ' + $get('<%= TextBox1.ClientID %>').value);
</script>

我上面鏈接的文章的評論主題也有一些很好的討論。

您可以將控件的ClienIDMode屬性更改為'Static' ,這將導致您在.NET代碼中為控件提供相同的ID。

<asp:TextBox ID="TextBox1" ClientIDMode="Static" runat="server"></asp:TextBox> 

將導致:

<input name="ctl00$MainContent$TextBox1" type="text" id="TextBox1"> 

所以你有相同的ID。

對此有幾點想法:

1)我有很多運氣通過css類而不是id來獲取元素,因為asp.net id並不像你所說的那樣可靠。 我使用這個功能,它表現得相當好:

function getElementsByClass(searchClass,node,tag) {
 var classElements = new Array();
 if ( node == null )
    {
        node = document;
    }

 if ( tag == null )
    {
        tag = '*';
    }

 var els = node.getElementsByTagName(tag);
 var elsLen = els.length;
 var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");

 for (i = 0, j = 0; i < elsLen; i++) 
    {
        if ( pattern.test(els[i].className) ) 
            {
                classElements[j] = els[i];
                j++;
            }
      }
 return classElements;
}

2)jQuery在這里有很多幫助。 使用jQuery,您可以可靠地獲取id以某個字符串結尾的元素。 雖然這不是使用jQuery的“理由”,但絕對是一個優勢。

3)這將在asp.net 4.0中修復,所以掛在那里:-) http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview。 ASPX

對於'ctl00_ContentMain_Button1' - 在asp.net中,當瀏覽器中的頁面呈現時,第一部分保持相同的'ctl00'。 第二部分是使用'ContentMain'的ContentPlaceHolder的ID。 第三個是控件'Button1'的ID

我喜歡這個http://codedotnets.blogspot.in/2012/01/how-get-id-server-control-javascript.html

我更喜歡標記document.getElementById('<%#TextBox1.ClientID%>')。value中的數據綁定標記,而不是使用服務器端標記實現<%= TextBox1.ClientID%>。

服務器端標簽禁止您在后面的代碼中向dom添加控件。 這種需求通常在構建應用程序時出現,數據綁定方法可能會使您免於重大修改。

當使用服務器端標簽時,也稱為“代碼塊”執行此常見操作

this.Form.Controls.Add(myContorl);

在運行時生成此錯誤:

無法修改Controls集合,因為控件包含代碼塊(即<%...%>)。

不幸的是,在構建完網站后,這通常只會變得非常明顯。

當實現數據綁定控件'<%#TextBox1.ClientID%>'解析標記中引用的控件屬性的值時,在適當的位置,例如Page_Load數據綁定結束,如下所示:

的Page.DataBind()

請記住,Page.DataBind()會導致頁面上的子控件也是DataBind,如果頁面單獨處理某些子控件的數據綁定,這可能會產生不必要的副作用。 如果是這種情況,可以對單個控件執行數據綁定,如下所示:

TextBox1.DataBind()

應用程序的發展最終會導致某些基本站點范圍的功能,您可能希望添加基本控件,一旦您使用服務器端標簽填充您的網站應用程序,用數據綁定替換它們就會出現問題,尤其是當頁面編碼為處理數據綁定時他們自己。

我不認為這樣做有一個“最佳實踐”。 有很多不同的相當好的做法。 這是我們的:

每個具有客戶端功能的控件都會在控件的標記正下方呈現內聯腳本塊:

<span id="something_crazy_long">
    control markup
</span>
<script type="text/javascript">new CustomControl('something_crazy_long');</script>

每個控件都有一個伴隨的JS:

var CustomControl = function(id) {
    this.control = document.getElementByID(id);
    this.init();
};

CustomControl.prototype.init = function() {
    //do stuff to wire up relevant events
};

在代碼隱藏中,我們做了類似的事情:

class CustomControl : Control

override void Render(HtmlTextWriter writer)
{
    writer.WriteBeginTag("span");
    writer.WriteAttribute("id", this.ClientID);
    writer.Write(HtmlTextWriter.TagRightChar);
    //write control markup
    writer.WriteEndTag("span");
    writer.WriteBeginTag("script");
    writer.WriteAttribute("type", "text/javascript");
    writer.Write(HtmlTextWriter.TagRightChar);
    writer.Write(
        string.Format("new CustomControl('{0}');", this.ClientID)
    );
    writer.WriteEndTag("script");
}

我做類似於Rex M的事情,除了避免多個腳本標簽我在我的頁面基類中使用一個函數來注冊我將使用客戶端的控件,然后將它們吐出到1個腳本標記內的html。

您甚至可以將控件子類化為自動注冊函數或使用布爾屬性來設置是否要在客戶端使用它們。

哦,我也找到了這個,以防其他人遇到這個問題。

為asp.net控件使用自定義jQuery選擇器: http//john-sheehan.com/blog/custom-jquery-selector-for-aspnet-webforms/

您也可以使用document.getElementById方法獲取ID。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM