Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   проверки с in (https://javascript.ru/forum/misc/27472-proverki-s.html)

Pavel M. 14.04.2012 12:35

bes,
посмотрите как эмулируются для неподдерживающих броузеров события mouseenter mouseleave http://learn.javascript.ru/mouse-eve...ter-mouseleave

там проверяется parentNode - удобнее и с объектами событий все сделано кроссбраузерно

Gvozd 14.04.2012 13:38

Цитата:

Сообщение от bes
Говорит ли это о том, что псевдомассивы (такие как HTMLCollection) отличаются от массивов только тем, что у них нет некоторых методов массивов?

Нет.
Вы процитировали мое сообщение не полностью, опустив более важное отличие, а именно живость массива.
Вот пример приведенного кода, только a - это уже массив, с одним элементом - ссылкой. Запускать на вашем HTML-е
var a_elem = document.getElementsByTagName('a')[0];
var a = [a_elem];
console.log(a.length);//1
console.log(a[0]);//<a href="">
console.log(a[0].innerHTML);//content
document.getElementsByTagName('div')[0].innerHTML = 'qwe';
console.log(a.length);//1
console.log(a[0]);//<a href="">
console.log(a[0].innerHTML);//content

Как видим для настоящего массива количество элементов не изменилось, и он даже все еще хранит некоторую информацию об элементе которого уже нету в DOM-модели.
А HTMLCollection в данном случае вместе с ичсчезновением ссылки, и сам переставал ссылатся на нее, и становился размера 0
================================================== ======
Вообще массивом является только то, что выдает true на x instanceof Array
var construct = function(){//конструктор объектов - наследующих массив
    for(var i =0; i < arguments.length; i++){
        this.push(arguments[i]);
    }
};
construct.prototype = [];


var a = document.getElementsByTagName('a');
var b = {};
b[0] = 'qwe';
var c = ['qwe']
d = new construct('qwe');

console.log(a.length, a[0], a instanceof Array);//false
console.log(b.length, b[0], b instanceof Array);//false
console.log(c.length, c[0], c instanceof Array);//true
console.log(d.length, d[0], d instanceof Array);//true

Результат:
Код:

1 <a href=""> false
undefined qwe false
1 qwe true
1 qwe true

Как видим, только c и d являются массивами(второй - наследует его свойства), хотя у всех объектов в данном случае можно получить нулевой элемент

Gvozd 14.04.2012 13:50

Цитата:

Сообщение от bes
Правильно ли я понимаю, что псевдомассивы хранят в качестве элементов ссылки на некоторые элементы (через которые собственно можно получить к ним доступ), ведь мы можем обращаться к доступным свойствам этих элементов (например, a[0].innerHTML)

Да.
Только для HTMLCollection эти ссылки будут хранится только на живые элементы, если они есть.
ПРи их исчезновении, коллекция будет уменьшатся в размерах.
А при добавлении новых элементов, наоборот даже расти:
var a = document.getElementsByTagName('a');
console.log(a.length);//1
document.getElementsByTagName('div')[0].innerHTML += '<a href="">content</a>';
console.log(a.length);//2, потому что ссылок уже две


Цитата:

Сообщение от bes
хотя приведённый вами пример, Gvozd, вернул строку <a href=""> для a[0] .

Вообще-то тут возвращается сам элемент.
Просто в консоли отладчика он выглядит как такая строка, которую я сюда скопипастил.
Запустите мои примеры в консоли firebug(это плагин для FireFox), например.
Можно и в отладочной консоли любого другого браузера, благо она есть сейчас во многих браузерах.
Цитата:

Сообщение от bes
Если работает, почему бы и нет

Как я уже сказал, в данном случае оператор in не будет работать так как вы хотите.
Зато я привел вам столь же короткий способ решения, без циклов, который будет работать.
Даже Pavel M., уже вам говорит о том же самом

bes 15.04.2012 09:28

Цитата:

Сообщение от Pavel M.
посмотрите как эмулируются для неподдерживающих броузеров события mouseenter mouseleave http://learn.javascript.ru/mouse-eve...ter-mouseleave

Да, я видел этот способ, просто хотелось для простейших случаев, как мне показалось, использовать более простой и короткий способ, когда весь код помещается в обработчик onmouseout родительского элемента, а дочерние элементы обработчиками не обременяются (даже путём их "короткого" задания во внешнем по отношению к ним коде), для этого достаточно было сформировать ряд условий, варианты реализации одного из этих условий и были помещены в тему обсуждения.

Gvozd, спасибо за пояснения, разницу между массивами и HTML-коллекциями я почувствовал.

Цитата:

Сообщение от Gvozd
Сообщение от bes: Eсли работает, почему бы и нет
Как я уже сказал, в данном случае оператор in не будет работать так как вы хотите.

Я и не утверждал, что собираюсь использовать in, даже если он здесь не работает, просто хотелось понять, не работает ли он здесь потому что он здесь совсем не работает или потому что я его как -то неправильно использую.

Цитата:

Сообщение от Gvozd
Зато я привел вам столь же короткий способ решения, без циклов, который будет работать.

О каком коротком способе без циклов идёт речь?
Если о вариантах получения единственного элемента-ссылки, то в случае с несколькими элементами-ссылками всё равно придётся использовать цикл.

Цитата:

Сообщение от Gvozd
Даже Pavel M., уже вам говорит о том же самом

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

bes 15.04.2012 10:45

Кстати, статья http://learn.javascript.ru/mouse-events теперь расположена по адресу http://learn.javascript.ru/mousemove-events.

bes 15.04.2012 11:16

Удалось получить простой и кроссбраузерно работающий код, когда скрытие div происходит только при уходе с него (Pavel M., способ с parentNode в статье, действительно, пригодился, по ходу я просто не понял этой фишки, читая статью до этого, то ли обновлённая статья стала понятнее).

Код:

<div id=div1 style="background: gray"
  onmouseout = "
  var rt = event.relatedTarget || event.toElement;

  while (rt && rt !== this) rt = rt.parentNode;

  if (rt == this) return; else this.style.display = 'none';
">
<a href="">content1</a><br>
<a href="">content2</a>
</div>


nerv_ 15.04.2012 23:07

Цитата:

Сообщение от Раед
for (var i=0;i<this.children.length;i++) if(!(event.relatedTarget==this.children[i])) this.style.display = 'none';

Что за мода все в одну строчку лепить?

Раед 15.04.2012 23:09

Цитата:

Сообщение от nerv_
Что за мода все в одну строчку лепить?

На мой взгляд, для простых конструкций это самый оптимальный вариант

nerv_ 15.04.2012 23:12

Раед, на мой взгляд простая конструкция это
var foo = null;

;)

Gvozd 15.04.2012 23:28

Цитата:

Сообщение от Раед
На мой взгляд, для простых конструкций это самый оптимальный вариант

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


Часовой пояс GMT +3, время: 16:28.