1

Тема: HTA: GetElementsById

Сразу хочу договорится: Ни о какой кросс-браузерности речи не идет. Мы работаем с HTA, а значит речь только о Internet Explorer.
Итак, в IE очень удобно обращаться к элементу по его ID.
Для этого даже getElementById использовать не нужно. Тем более что document.getElementById('myId') вернет только первый элемент с указанным ID.
Функции getElementsById просто не существует. Да она и не нужна. В IE можно обратиться к нужному элементу с известным ID просто указав его индекс, например:

myId[6].style.color = 'red';

И все хорошо, пока элементов с заданным ID больше одного. Если же элемент myId - единственный, то к нему уже нельзя обратиться как к массиву и приходится использовать

myId.style.color = 'red';

Вставлять во все участки кода проверку на количество элементов с заданным ID мне показалось неудобным. Сочинил такую простенькую функцию:


function GetElementsById(id){
    return (id[0]) ? id : [id];
}

Теперь можно писать так:


GetElementsById(myId)[n].style.color = 'red';

Код будет работоспособен как при нескольких элементах с указанным ID так и при единственном.

JS я люблю, но спецом в нем себя не считаю. Поэтому решил посоветоваться прежде чем вставлять это решение во все мои HTA проги.
Попутно хотел задать вопрос:
Я никогда не использую document.getElementById('myId'), но иногда (очень-очень редко) обращение напрямую к элементу по его ID почему то не срабатывает, тогда приходится применять getElementById.
Есть какие нибудь правила когда обязательно надо использовать getElementById или это просто глюки IE?

P.S. Можно, конечно, использовать самописную кросс-браузерную фукцию getElementsById (в инете ее многие приводят). Но перебирать все элементы подряд, а потом сверять их ID с заданным мне кажется уж чересчур ресурсоемким.

2

Re: HTA: GetElementsById

Много текста - я не понял о чем речь. Могу только сказать следующее.

Первое. getElementById - это стандартный метод всех браузеров и эмулировать его собственными силами не надо (возможно Вы путаете с методом getElementsByClassName - она до недавнего времени не существовала вообще, и именно ее приходилось реализовывать).

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

Третье. Пример, который показывает, почему стоит пользоваться getElementById.


<html>

<body>
<div id="uniq">hello, world</div>
<script>

var uniq = {
    innerHTML: 'BUE!!!'
};

alert([
    uniq.innerHTML, 
    document.getElementById('uniq').innerHTML
]);

</script>
</body>
</html>

Здесь не надо смотреть на искусственность примера и его простоту. Маленькие проекты очень быстро вырастают в большие. Однажды может случиться, что будет создана переменная, одноименная тэгу, и Вы неожиданно осчастливите себя, отлаживая казалось бы правильный код.

( 2 * b ) || ! ( 2 * b )

3 (изменено: mozers, 2013-05-25 11:26:23)

Re: HTA: GetElementsById

2Rumata

возможно Вы путаете с методом getElementsByClassName

Нет не путаю. getElementsByClassName как и getElementsById в IE не существует. Тормознутые эмуляции не рассматриваем.

Это не правильно, если на странице несколько элементов с одинаковыми ID

Позвольте не согласится. В чем "неправильность"? Это - супер-удобно, т.к. позволяет всегда и очень просто идентифицировать элемент не создавая никаких функций поиска. Для сравнения, по name элемент так запросто не найдешь. А тут, присвоив элементам только ID мы можем не только всегда однозначно и просто обратиться к любому из них, но и одним махом поменять их стиль задав в CSS #MyID {}.
И Вы предлагаете мне добровольно отказаться от этой красоты и удобства, только потому что кто то однажды написал что это "неправильно"???

Однажды может случиться, что будет создана переменная, одноименная тэгу

Ну, извините, как говорится - "смотреть надо". Да мало ли ошибок может возникнуть по человеческой невнимательности???
Я, например, чтобы избежать такой ошибки, имена для всех ID-шников всегда начинаю с букв "id".

P.S. Возможно для тех кто пишет кросс-браузеный код привыкать к такому удобству и не стоит. Привыкнешь, а потом будешь страдать что в других браузерах так просто это не получается. Для тех, кто как я, сочиняет только HTA-шки, метод - просто супер.

4

Re: HTA: GetElementsById

Добавлю еще об одной уникальной возможности, которую мы получаем, присваивая элементам ID.
Мы можем находить их с помощью функции getElementsByName !

<html>
<head>
<style type="text/css">
    #idInput {font-weight:bold; color:blue;};
</style>
<script type="text/javascript">
    function GetValuesById(){ // так - проще, но это работает верно, только если элементов с idInput больше одного.
        for (var i = 0; i < idInput.length; i++) {
            alert ("Param" + i + " = " + idInput[i].value);
        }
    }
    function GetValuesByName(){
        var arrInputs = document.getElementsByName('idInput');
        for (var i = 0; i < arrInputs.length; i++) {
            alert ("Param" + i + " = " + arrInputs[i].value);
        }
    }
</script>
</head>
<body>
    <table border="1">
        <tr>
            <td>Param0:</td><td><input type="text" value="Mary" id="idInput"></td>
        </tr>
        <tr>
            <td>Param1:</td><td><input type="text" value="Vanessa" id="idInput"></td>
        </tr>
        <tr>
            <td>Param2:</td><td><input type="text" value="Lara" id="idInput"></td>
        </tr>
        <tr>
            <td colspan="2"><input type="button" value="Get Values" onclick="GetValuesByName()"></td>
        </tr>
    </table>
</body>
</html>

При использовании getElementsByName нужда в моей функции GetElementsById, приведенной в первом посте, отпадает.

5 (изменено: Rumata, 2013-05-25 13:16:46)

Re: HTA: GetElementsById

Возможно это Вам удобно, тогда почему же Вы спрашиваете совета? Делайте как Вы считаете это удобным, не взирая на стандарты. МСИЕ тоже на них не смотрит и расширяет стандартные решения в свою угоду. В результате путаетесь Вы.

HTMLElement.id

http://www.w3.org/TR/1999/REC-html401-1 … ml#adef-id
id = name [CS]
    This attribute assigns a name to an element. This name must be unique in a document.

document.getElementById

http://www.w3.org/TR/DOM-Level-2-Core/c … D-getElBId
getElementById introduced in DOM Level 2
    Returns the Element whose ID is given by elementId. If no such element exists, returns null. Behavior is not defined if more than one element has this ID.

Обратите внимание: везде говорится в единственном числе. ID нужен для уникальности элемента, чтобы однозначно идентифицировать один элемент. То что МСИЕ позволяет получать список элементов по атрибуту name с помощью метода getElmentById не говорит о том, что это хорошо. Для этого Вы можете с тем же успехом использовать getElementsByName:

http://www.w3.org/TR/DOM-Level-2-HTML/h … D-71555259
getElementsByName
    With [HTML 4.01] documents, this method returns the (possibly empty) collection of elements whose name value is given by elementName. In [XHTML 1.0] documents, this methods only return the (possibly empty) collection of form controls with matching name. This method is case sensitive.

Это будет лучше (близко стандарту), понятнее (другие программисты скажут спасибо) и логичнее (поиск одного по id - getElementById, поиск кучи по name - getElementsByName):


<div name="cite" id="poem"></div>
<div name="cite" id="author"></div>
...

var cites = document.getElementsByName('cite');
alert(cites.length);

document.getElementById('poem').innerHTML = 'To be or not to be';
document.getElementById('author').innerHTML = 'William Shakespeare';
( 2 * b ) || ! ( 2 * b )

6

Re: HTA: GetElementsById

2Rumata

Возможно это Вам удобно, тогда почему же Вы спрашиваете совета?

Да потому что меня всегда удивляло, что такую великолепную возможность так редко используют. Даже сами мелкософтовцы сплошь и рядом пишут document.getElementById('myID').value когда можно написать просто myID.value.
Вы мне все очень подробно и аргументировано разъяснили. Спасибо!

Кстати, о возможности получить массив id c помощью document.getElementByName я узнал только вчера, совершенно случайно, сочиняя пример для этой темы. Теперь буду пользоваться

Таким образом, для сочинения своих HTA-шек буду пользовать:
- для определения есть ли вообще элемент с указанным id:

if (document.getElementById('idElement'))

- для подключения к единственному элементу:

idElement.value = 'sample';

- для подключения к одному элементу массива id (если кол-во элементов всегда больше 1) :

idElement[i].value = 'sample';

- для подключения к одному элементу массива id (если кол-во элементов неизвестно) :

document.getElementByName('idElement')[i].value = 'sample';

Другие конструкции считаю неоправданно громоздкими.
Повторюсь, что тем, кто пишет не только на HTA, такие советы только повредят.

7 (изменено: Serge Yolkin, 2013-05-25 23:48:02)

Re: HTA: GetElementsById

Вот, с одной стороны, стандарты - да, нужны. И учить начинающих профессионалов, наверное, надо по стандартам; а с другой - и трикс никто не отменял. Не то, чтобы мне понравилось использовать один id для разных элементов, но и сам как-то использовал, так было удобнее. А если взглянуть на батнички в коллекции, так там чуть ли не все с теми или иными трюками (иногда - с очень забавными). Пожалуй, за использование подобных решений ответственен разработчик: если всё работает, какие могут быть претензии? А при публикации надо прсто предупреждать читателей, что в данном случае и было сделано.

8 (изменено: Rumata, 2013-05-26 19:26:24)

Re: HTA: GetElementsById

Плохая практика мешать в се в одну кучу. Надо стараться чтобы "котлеты - отдельно, мухи - отдельно". Это я вот к чему:

-- для доступа к множеству одноименных элементов использовать атрибут name и метод getElementsByName
-- для доступа к одному конкретному элементу использовать атрибут id и метод getElementById

При этом я не отвергаю Ваш способ адресации - всего лишь дополняю его некоторой систематичностью. Пользователям Ваших работ все равно, что и как работает, а вот желающие заглянуть "под капот" могут удивиться нетрадиционному использованию известных механизмов. Согласен, что в таких случаях должен быть подробный комментарий, описывающий о нестандартном использовании. Но оправданно ли использование "триков" - getElementsByName для доступа по id, вместо name, когда можно добавить атрибут name и следовать стандарту?

( 2 * b ) || ! ( 2 * b )

9

Re: HTA: GetElementsById

mozers пишет:

... но и одним махом поменять их стиль задав в CSS #MyID {}.

Может правильней будет использовать class и в CSS писать ".MyID {}"?

Нас невозможно сбить с пути, нам пофигу куда идти.

10 (изменено: mozers, 2013-05-30 19:54:39)

Re: HTA: GetElementsById

2DnsIs
Конечно можно любому элементу присвоить class (для задания стиля), еще присвоить name (чтобы находить его с помощью getElementsByName), еще присвоить уникальный id (чтобы находить его с помощью getElementById).
Все это будет соответствовать стандартам, но сколько лишнего кода!
Я же говорил о том, как можно писать короче и удобнее.
Да, это не всегда соответствует стандартам и, порой, работает только в IE. Но работает!

11

Re: HTA: GetElementsById

Можно сахар помешивать чайной ложкой, а котлету нанизывать на вилку, а суп хлебать из глубокой тарелки да столовой ложкой. Все это будет соответствовать этикету, но сколько лишних приборов - ведь можно сделать все одной столовой ложкой. Проще и удобнее - и посуды мыть меньше!

( 2 * b ) || ! ( 2 * b )

12

Re: HTA: GetElementsById

2Rumata
Полностью соглашусь.
В походе мне с лихвой хватает широкой кружки и ложки на веревочке. Супер удобно и ничего лишнего

13

Re: HTA: GetElementsById

Не могу не согласиться. Хорошо парировали : )

( 2 * b ) || ! ( 2 * b )

14

Re: HTA: GetElementsById

Не согласен я с автором.
Я тоже минималист в коде, но идти на поводу у криворуких мелкомягких плюющих на все стандарты, это как то неправильно.

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

var chekOne=document.getElementById("chek1");
chekOneSt=chekOne.style;

и так далее.

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