Ссылка ASP.NET контроль по идентификатору в JavaScript? - PullRequest
46 голосов
/ 13 марта 2009

Когда элементы управления ASP.NET отображаются, их идентификаторы иногда меняются, как если бы они находились в контейнере именования. Button1 может фактически иметь идентификатор ctl00_ContentMain_Button1, когда он отображается, например.

Я знаю, что вы можете написать свой JavaScript в виде строки в вашем файле .cs, получить clientID элемента управления и внедрить сценарий на свою страницу, используя clientcript, но есть ли способ, с помощью которого вы можете ссылаться на элемент управления непосредственно из JavaScript, используя ASP. NET Ajax?

Я обнаружил, что написание функции для рекурсивного анализа dom и поиска элемента управления, который содержит идентификатор, который я хочу, ненадежно, поэтому я искал лучшую практику, а не обходной путь.

Ответы [ 9 ]

69 голосов
/ 13 марта 2009

Эта запись Дэйва Уорда может иметь то, что вы ищете:

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

Выдержка из статьи:

Действительно, есть. Лучшее решение это использовать встроенный код ASP.NET для ввести ClientID элемента управления Свойство:

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

Теперь правильный идентификатор элемента клиента ссылаться, независимо от структура страницы и вложенность уровень контроля. По моему мнению, очень низкая стоимость исполнения этот метод стоит того, чтобы его сделать ваш клиентский сценарий более устойчивый изменить.

И пример кода Дэйва из ветки комментариев этого поста:

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

В теме комментариев к статье, на которую я ссылался выше, также есть хорошее обсуждение.

16 голосов
/ 04 ноября 2013

Можно изменить свойство ClienIDMode элемента управления на 'Static', что приведет к тому же идентификатору, который вы присвоили элементу управления в коде .NET.

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

приведет к:

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

так что у вас тот же ID.

12 голосов
/ 13 марта 2009

Пара мыслей по этому поводу:

1) Мне посчастливилось получить элементы по классу css вместо id, потому что идентификаторы asp.net не надежны, как вы заявили. Я использую эту функцию, и она работает достаточно хорошо:

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, вы можете надежно получать элементы, в которых идентификатор заканчивается определенной строкой. Хотя это не «причина» использования jQuery, это определенно плюс.

3) Это будет исправлено в asp.net 4.0, так что подождите :-) http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview.aspx

1 голос
/ 13 марта 2009

О, и я тоже нашел это, на случай, если у кого-то еще возникнет эта проблема.

Используйте пользовательский селектор jQuery для элементов управления asp.net: http://john -sheehan.com / блог / на заказ JQuery селектор-для-САШ-WebForms /

0 голосов
/ 18 июня 2013

Я предпочитаю привязанные к данным теги в разметке document.getElementById ('<% # TextBox1.ClientID%>'). Value, вместо использования реализации тега на стороне сервера <% = TextBox1.ClientID%>.

Теги на стороне сервера запрещают вам добавлять элементы управления в код в коде. Это обычно возникает, когда вы создаете свое приложение, и подход, основанный на данных, может спасти вас от серьезных переписываний.

При использовании серверных тегов, также известных как «кодовые блоки», выполняющие эту обычную операцию

this.Form.Controls.Add (myContorl);

генерирует эту ошибку во время выполнения:

Коллекция элементов управления не может быть изменена, поскольку элемент управления содержит блоки кода (т. е. <% ...%>).

К сожалению, это часто становится очевидным только после того, как вы создали свой веб-сайт.

При реализации привязанного к данным элемента управления «<% # TextBox1.ClientID%>» разрешите значение свойств элемента управления, на которое есть ссылка в разметке, в соответствующем месте, например в конце привязки данных Page_Load, следующим образом:

* * Page.DataBind тысячи двадцать-одина () * * тысяча двадцать две

Имейте в виду, что Page.DataBind () заставляет дочерние элементы управления на странице также использовать DataBind, это может быть нежелательным побочным эффектом, если страница обрабатывает привязку данных некоторых дочерних элементов управления отдельно. В этом случае привязка данных может быть выполнена для отдельного элемента управления следующим образом:

TextBox1.DataBind ()

Эволюция приложений в конечном итоге приводит к некоторой функциональности базового сайта, где вы можете захотеть добавить базовые элементы управления, как только вы засыпали свое приложение веб-сайта тегами на стороне сервера, а замена их на привязки данных становится проблематичной, особенно когда страницы закодированы обрабатывать привязку данных самостоятельно.

0 голосов
/ 28 ноября 2012

Для 'ctl00_ContentMain_Button1' - в asp.net, когда страница отображается в браузере, первая часть остается такой же 'ctl00' Вторая часть - это идентификатор ContentPlaceHolder, используемый «ContentMain». В-третьих, это идентификатор элемента управления «Button1»

Мне понравилось http://codedotnets.blogspot.in/2012/01/how-get-id-server-control-javascript.html

0 голосов
/ 29 января 2012

Вы также можете получить идентификатор, используя метод document.getElementById.

0 голосов
/ 13 марта 2009

Я делаю что-то похожее на Rex M, за исключением того, чтобы избежать нескольких тегов скрипта. Я использую функцию в базовом классе своей страницы, чтобы зарегистрировать элементы управления, которые я собираюсь использовать на клиентской стороне, а затем выкладываю их в HTML внутри 1 тега скрипта.

Вы можете даже создать подклассы своих элементов управления для автоматической регистрации в функции или использовать логическое свойство, чтобы указать, собираетесь ли вы использовать их на стороне клиента.

0 голосов
/ 13 марта 2009

Я не думаю, что есть одна «лучшая практика» для этого. Существует множество различных довольно хороших практик. Вот наши:

Каждый элемент управления, который имеет функциональные возможности на стороне клиента, отображает встроенный блок сценария непосредственно под разметкой для элемента управления:

<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");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...