Я занимаюсь рефакторингом CSS на веб-сайте. Я работал и заметил отсутствие в коде традиционных HTML-идентификаторов.
CssClass='…', а иногда и просто class='…', широко используется, но я не могу найти способ сказать id = '…', чтобы сервер не заменил его.
Вот пример:
<span id='position_title' runat='server'>Manager</span>
Когда ответ приходит с сервера, я получаю:
<span id='$aspnet$crap$here$position_title'>Manager</span>Здесь есть помощь?





.Net всегда будет заменять ваши значения идентификаторов каким-то искаженным (почти предсказуемым, но все же не рассчитывающим на это) значением. Вам действительно НУЖНО иметь этот идентификатор runat = server? Если вы не введете runat = server, он не испортит его ...
ДОБАВЛЕН: Как сказал leddt, вы можете ссылаться на диапазон (или любой runat = server с идентификатором), используя ClientID, но я не думаю, что это работает в CSS.
Но я думаю, что у вас есть большая проблема, если ваш CSS использует селекторы на основе идентификаторов. Вы не можете повторно использовать ID. Вы не можете иметь несколько элементов на одной странице с одним и тем же идентификатором. .Net будет жаловаться на это.
Итак, имея это в виду, ваша работа по рефакторингу CSS становится немного шире по объему?
«Дерьмо», помещенное перед идентификатором, связано с контейнером (ами) элемента управления, и нет никакого способа (насколько я знаю) предотвратить такое поведение, кроме как не помещать его в какой-либо контейнер.
Если вам нужно обратиться к идентификатору в скрипте, вы можете использовать ClientID элемента управления, например:
<script type = "text/javascript">
var theSpan = document.getElementById('<%= position_title.ClientID %>');
</script>
Хорошо, я полагаю, что по этому поводу нет жюри.
@leddt, я уже знал, что «хрень» - это окружающие его контейнеры, но я подумал, что, может быть, Microsoft оставила бы бэкдор, чтобы оставить идентификатор в покое. Повторное создание файлов CSS при каждом использовании с включением ClientID было бы ужасной идеей.
Я либо остаюсь с использованием классов повсюду, либо с некоторыми искаженными идентификаторами, жестко закодированными в CSS.
Если вам ДЕЙСТВИТЕЛЬНО нужно использовать идентификатор в вашем CSS, вы должны попытаться найти способ не отмечать элемент как runat = "server". Может быть, с <asp: Literal ... />?
<span id = "Any"> <asp: Literal id = "Any_content" runat = "server" /> </span> Вы можете установить содержимое литерала в коде, и оно не будет окружено каким-либо дополнительным тегом .
@Matt Dawdy: Есть несколько отличных вариантов использования идентификаторов в CSS, в первую очередь, когда вы хотите стилизовать элемент, который, как вы знаете, появляется только один раз на веб-сайте или на странице, например, кнопка выхода или шапка.
@ Джаред. Мое предложение прозвучало не так, как я тоже имел в виду - да, есть несколько очень веских причин для того, чтобы сделать то, что вы предлагаете. Я хотел сказать, что .Net на самом деле не согласен. Удачи!
Если вы обращаетесь к span или другому тегу, который вызывает проблемы из-за кода C# или VB, тогда runat = "server" должен остаться, и вы должны использовать вместо него <span class = "some_class" id = "someID">. Если у вас нет доступа к тегу в коде позади, удалите runat = "server".
Лучше всего дать ему уникальное имя класса.
Вероятно, вам придется удалить runat = "server" из диапазона, а затем поместить в него, чтобы вы могли стилизовать диапазон и при этом иметь динамическое внутреннее содержимое.
Не изящное или простое решение (и оно требует перекомпиляции), но оно работает.
Используйте jQuery для выбора элемента:
$("span[id$='position_title']")....
Гибкие селекторы jQuery, особенно его «начинается с» / «заканчивается селекторами» (селектор «конец с» показан выше, предоставляют отличный способ обойти ASP.NET dom id munge.
rp
Я не знаю способа остановить .NET от искажения идентификатора, но я могу придумать несколько способов обойти это:
1 - пролеты гнезд, один с runat = "server", один без:
<style type = "text/css">
#position_title { // Whatever
}
<span id = "position_titleserver" runat = "server"><span id = "position_title">Manager</span></span>
2 - Как предложил Джоэл Кохорн, используйте вместо этого уникальное имя класса. Уже используете класс для чего-то? Неважно, вы можете использовать больше 1! Этот...
<style type = "text/css">
.position_title { font-weight: bold; }
.foo { color: red; }
.bar { font-style: italic; }
</style>
<span id = "thiswillbemangled" class = "foo bar position_title" runat = "server">Manager</span>
... отобразит это:
Управляющий делами
3 - Напишите функцию Javascript для исправления идентификаторов после загрузки страницы
function fixIds()
{
var tagList = document.getElementsByTagName("*");
for(var i=0;i<tagList.length;i++)
{
if (tagList[i].id)
{
if (tagList[i].id.indexOf('$') > -1)
{
var tempArray = tagList[i].id.split("$");
tagList[i].id = tempArray[tempArray.length - 1];
}
}
}
}
Если вы боитесь classitus, попробуйте использовать идентификатор в родительском или дочернем селекторе, который содержит элемент, который вы хотите стилизовать. К этому родительскому элементу НЕ должен применяться сервер runat. Проще говоря, неплохо спланировать свои структурные контейнеры так, чтобы не запускать код позади (т.е. без запуска), таким образом вы можете получить доступ к основным частям вашего приложения / сайта, используя неизмененные идентификаторы. Если это слишком поздно, добавьте обертку div / span или используйте решение класса, как упомянуто.
Есть ли особая причина, по которой вы хотите, чтобы элементы управления были runat = "server"?
Если это так, я поддерживаю использование <asp: Literal>. . .
Он должен сделать эту работу за вас, так как вы по-прежнему сможете редактировать данные в коде.
Обычно я создаю свой собственный элемент управления, расширяющий WebControl или HtmlGenericControl, и переопределяю ClientID, возвращая свойство ID вместо сгенерированного ClientID. Это приведет к тому, что любое преобразование, которое .NET выполняет с ClientID из-за именования контейнеров, будет возвращено к исходному идентификатору, который вы указали в разметке тега. Это замечательно, если вы используете библиотеки на стороне клиента, такие как jQuery, и вам нужны предсказуемые уникальные идентификаторы, но сложно, если вы полагаетесь на viewstate для чего-либо на стороне сервера.
Вы можете встроить свой CSS в страницу, посыпав некоторыми серверными тегами, чтобы решить эту проблему. Во время выполнения блоки кода будут заменены идентификаторами, сгенерированными ASP.NET.
Например:
[style type = "text/css"]
#<%= AspNetId.ClientID %> {
... styles go here...
}
[/style]
[script type = "text/javascript"]
document.getElementById("<%= AspNetId.ClientID %>");
[/script]
Вы могли бы пойти немного дальше и иметь несколько файлов кода, которые тоже генерируют CSS, если вы хотите, чтобы ваш CSS содержался в отдельном файле.
Кроме того, я, возможно, немного прыгну здесь, но вы можете использовать материал ASP.NET MVC (еще не выпущенный официально на момент написания этой статьи), который уходит от веб-форм и дает вам полный контроль над сгенерированной разметкой.
Большинство предложенных ей исправлений избыточны для очень простой проблемы. Просто имейте отдельные блоки div и span, на которые вы нацеливаетесь с помощью CSS. Не настраивайте элементы управления ASP.NET напрямую, если хотите использовать идентификаторы.
<span id = "FooContainer">
<span runat = "server" id = "Foo" >
......
<span>
</span>
Обратите внимание, что это не решит вашу проблему с CSS, поскольку вы не можете использовать эту технику во внешнем файле CSS. Если вам ДЕЙСТВИТЕЛЬНО нужно использовать идентификатор в вашем CSS, вы должны попытаться найти способ не отмечать элемент как runat = "server". Может быть, с <asp: Literal ... />?