Именование атрибутов HTML «class» и «id» - тире против подчеркивания [закрыто]


114

<div id="example-value">или <div id="example_value">?

Этот сайт и Twitter используют первый стиль. Facebook и Vimeo - второе.

Какой из них вы используете и почему?


11
Обе эти связи теперь разорваны
Стив

Ответы:


136

Используйте дефисы, чтобы обеспечить изоляцию между HTML и JavaScript.

Зачем? увидеть ниже.

Дефисы можно использовать в CSS и HTML, но не в объектах JavaScript.

Многие браузеры регистрируют идентификаторы HTML как глобальные объекты в объекте окна / документа, в больших проектах это может стать настоящей проблемой.

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

Учтите следующее:

message.js

message = function(containerObject){
    this.htmlObject = containerObject;
};
message.prototype.write = function(text){
    this.htmlObject.innerHTML+=text;
};

HTML

<body>
    <span id='message'></span>
</body>
<script>
    var objectContainer = {};
    if(typeof message == 'undefined'){
        var asyncScript = document.createElement('script');
        asyncScript.onload = function(){
            objectContainer.messageClass = new message(document.getElementById('message'));
            objectContainer.messageClass.write('loaded');
        }
        asyncScript.src = 'message.js';
        document.appendChild(asyncScript);
    }else{
        objectContainer.messageClass = new message(document.getElementById('message'));
        objectContainer.messageClass.write('loaded');
    }
</script>

Если браузер регистрирует идентификаторы HTML как глобальные объекты, выполнение вышеуказанного не удастся, потому что сообщение не является «неопределенным», и он попытается создать экземпляр объекта HTML. Убедившись, что HTML-идентификатор содержит дефис в имени, предотвращает конфликты, подобные приведенному ниже:

message.js

message = function(containerObject){
    this.htmlObject = containerObject;
};
message.prototype.write = function(text){
    this.htmlObject.innerHTML+=text;
};

HTML

<body>
    <span id='message-text'></span>
</body>
<script>
    var objectContainer = {};
    if(typeof message == 'undefined'){
        var asyncScript = document.createElement('script');
        asyncScript.onload = function(){
            objectContainer.messageClass = new message(document.getElementById('message-text'));
            objectContainer.messageClass.write('loaded');
        }
        asyncScript.src = 'message.js';
        document.appendChild(asyncScript);
    }else{
        objectContainer.messageClass = new message(document.getElementById('message-text'));
        objectContainer.messageClass.write('loaded');
    }
</script>

Конечно, вы можете использовать messageText или message_text, но это не решает проблему, и вы можете столкнуться с той же проблемой позже, когда случайно получите доступ к объекту HTML вместо объекта JavaScript.

Одно замечание, вы все еще можете получить доступ к объектам HTML через (например) объект окна, используя window ['message-text'];


Я что-то не понимаю в вашем посте, возможно, вы сможете уточнить. Итак, вы говорите, что некоторые браузеры регистрируют идентификатор html как глобальные объекты и что если вы поместите дефис в идентификатор, вы гарантируете, что не будет конфликта между этими автоматически сгенерированными объектами и теми, которые вы создаете, потому что дефисы не разрешены. . Но как тогда браузер создает эти объекты с переносом, если переносить его нельзя? кажется, что их придется разделить, что оставит вас с потенциалом конфликта имен.
Dallas Caley

@DallasCaley, если вы не видели, этот ответ был window['message-text'];
вызван

Я думаю, я понял. Странно, что javascript не позволяет вам создать объект с тире в имени как отдельный объект, но он позволит вам создать объект с тире в имени, если он создан как свойство другого объекта в названии которого нет тире.
Dallas Caley

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

87

Я бы порекомендовал Google Руководство по стилю HTML / CSS.

В нем конкретно говорится :

Слова в идентификаторах и названиях классов разделяйте дефисом . Не объединяйте слова и сокращения в селекторах никакими символами (включая вообще никакие), кроме дефисов, чтобы улучшить понимание и удобство просмотра.

/* Not recommended: does not separate the words “demo” and “image” */
.demoimage {}

/* Not recommended: uses underscore instead of hyphen */
.error_status {}

/* Recommended */
#video-id {}
.ads-sample {}

1
А что насчет BEMобозначений?
Юлиан Онофрей

1
@IulianOnofrei, конечно, вы можете использовать БЭМ, но это явно не соответствует строго Руководству по стилю Google.
Клас Меллборн 01

хм, очень странно. Фреймворк GWT от Google использует camelcase. Проверьте эту строку кода <h1 id = "appTitle"> </h1> в следующем документе. gwtproject.org/doc/latest/tutorial/i18n.html
karlihnos

4
Google! = Автоматически правильно. Часто это так, но просто быть Google недостаточно для оправдания.
Крейг Бретт

2
Это действительно плохая идея. Рано или поздно вы захотите использовать свое имя на языке программирования, который не поддерживает дефисы в именах переменных (в основном, во всех), и тогда БУМ! Идиотские правила переименования.
Timmmm

5

На самом деле все сводится к предпочтениям, но то, что повлияет на вас в определенном направлении, может быть редактором, с помощью которого вы кодируете. Например, функция автозаполнения TextMate останавливается на дефисе, но видит слова, разделенные подчеркиванием, как одно слово. Таким образом, имена и идентификаторы классов the_postработают лучше, чем the-postпри использовании функции автозаполнения ( Esc).


Вы правы, но в окружающих его «html-джунглях» это будет казаться гораздо более беспорядочным
Камил Томшик

4

Я считаю, что это полностью зависит от программиста. Вы также можете использовать camelCase, если хотите (но я думаю, что это будет выглядеть неловко).

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


3
этот вопрос аналогичен и подтверждает этот ответ stackoverflow.com/questions/70579/…
Мэтт Смит

2

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


14
Да, вы можете использовать двоеточия и точки для идентификаторов, но это хороший способ заставить человека, пишущего файл CSS, возненавидеть вас.
Дэйв Маркл

5
Идентификатор HTML ZZ:ZZдолжен быть экранирован как ZZ\00003AZZ(CSS2 и выше).
McDowell

1
Я не сказал, что это хорошая практика, я сказал, что это действительно так.
Майлз

5
Похоже, интересный способ взорвать jQuery
Майк Робинсон,

0

Я использую первый (один-два), потому что он более читабельный. Для изображений я предпочитаю подчеркивание (btn_more.png). Другой вариант - чехол Camel (oneTwo).


0

На самом деле некоторые внешние фреймворки (javascript, php) испытывают трудности (ошибки?) С использованием хайпена в именах идентификаторов. Я использую подчеркивание (как и 960grid), и все отлично работает.


3
Какие? В любом случае, удобочитаемость кода важнее.
Kamil Tomšík

-1

Я бы посоветовал подчеркнуть в основном по причине побочного эффекта javascript, с которым я сталкиваюсь.

Если вы введете приведенный ниже код в адресную строку, вы получите сообщение об ошибке: «примерное значение» не определено. Если бы div был назван с подчеркиванием, он бы работал.

javascript:alert(example-value.currentStyle.hasLayout);

5
Так должно быть document.getElementById("example-value"), и все будет нормально.
Чак

У меня возникает аналогичная проблема с ASP.NET MVC при указании значения для атрибута в параметре HtmlAttributes вспомогательных функций Html.
Matthijs Wessels,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.