web-dev-qa-db-ja.com

JavaScriptでIDによるASP.NETコントロールを参照しますか?

ASP.NETコントロールがレンダリングされると、名前付けコンテナー内にある場合など、IDが変更されることがあります。 Button1は、実際にはctl00_ContentMain_Button1たとえば、レンダリングされるとき。

JavaScriptを.csファイルの文字列として記述し、コントロールのclientIDを取得し、clientscriptを使用してページにスクリプトを挿入できることを知っていますが、ASP.NET Ajaxを使用してJavaScriptから直接コントロールを参照する方法はありますか?

Domを再帰的に解析し、必要なidを含むコントロールを見つけるための関数を記述することは信頼できないため、回避策ではなくベストプラクティスを探していました。

46
NetHawk

ああ、他の誰かがこの問題を抱えている場合に備えて、これも見つけました。

Asp.netコントロールにカスタムjQueryセレクターを使用します。 http://john-sheehan.com/blog/custom-jquery-selector-for-aspnet-webforms/

0
NetHawk

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>

上記でリンクした記事へのコメントスレッドにも、いくつかの良い議論があります。

70
Chuck

コントロールのClienIDModeプロパティを'Static'に変更すると、.NETコードでコントロールに与えたものと同じIDが得られます。

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

結果:

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

あなたは同じIDを持っています。

16
Sudi

これに関するいくつかの考え:

1)asp.net idはあなたが述べたように信頼できないので、私はidではなくcssクラスで要素を取得することができました。私はこの機能を使用し、それはかなりよく機能します:

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

12
brendan

これを行うための単一の「ベストプラクティス」があるとは思わない。さまざまなかなり良いプラクティスがあります。ここに私たちのものがあります:

クライアント側の機能を持つすべてのコントロールは、コントロールのマークアップのすぐ下に、スクリプトブロックをインラインでレンダリングします。

<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");
}
0
Rex M

Rex Mと似たようなことをしますが、複数のスクリプトタグを避けるため、ページベースクラスで関数を使用してクライアントサイドで使用するコントロールを登録し、1つのスクリプトタグ内でhtmlに吐き出します。

コントロールをサブクラス化して関数に自動的に登録するか、ブールプロパティを使用してクライアント側で使用するかどうかを設定することもできます。

0
Element

サーバー側のタグ実装<%= TextBox1.ClientID%>を使用するよりも、マークアップdocument.getElementById( '<%#TextBox1.ClientID%>')。valueのデータバインドタグを使用します。

サーバー側のタグにより、コードビハインドのdomにコントロールを追加できません。この必要性は、通常、アプリケーションを構築するときに発生し、データバインドアプローチにより、大幅な書き換えが不要になります。

サーバー側タグを使用する場合、この共通操作を実行する「コードブロック」としても知られています

this.Form.Controls.Add(myContorl);

実行時にこのエラーを生成します:

コントロールにコードブロック(<%...%>)が含まれているため、Controlsコレクションを変更できません。

残念ながら、これは多くの場合、Webサイトを構築して初めて本質的に明らかになります。

データバインドコントロール '<%#TextBox1.ClientID%>'を実装する場合、次のようにPage_Loadデータバインドの終わりなどの適切な場所で、マークアップで参照されるコントロールプロパティの値を解決します。

Page.DataBind()

Page.DataBind()により、ページ上の子コントロールもDataBindになります。ページが特定の子コントロールのデータバインディングを個別に処理する場合、これは望ましくない副作用になる可能性があります。この場合、次のように個々のコントロールでデータバインディングを実行できます。

TextBox1.DataBind()

特にページがデータバインディングを処理するようにコーディングされている場合、アプリケーションの進化により、ベースサイト全体の何らかの機能がベースコントロールを追加し、サーバーサイドタグをデータバインドに置き換えるとウェブサイトアプリケーションが問題になる場合があります自分自身で。

0
David Sopko

「ctl00_ContentMain_Button1」の場合-asp.netでは、ページがブラウザでレンダリングされるとき、最初の部分は同じ「ctl00」のままです。 2番目の部分は、「ContentMain」を使用するContentPlaceHolderのIDです。 3番目はコントロール「Button1」のIDです

これが気に入った http://codedotnets.blogspot.in/2012/01/how-get-id-server-control-javascript.html

0
suyog