Сохранение Javascript > логика

#javascript #arrays

#javascript #массивы

Вопрос:

Пожалуйста, помогите мне найти решение, которое использует обычный javascript (я не могу использовать внешние фреймворки). Кроме того, CSS: указатель наведения не будет работать для реализации в реальном мире.

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

 <body>
        <p>When you hover over amp;<divamp;> tags 0-2, that amp;<divamp;> tag should highlight in red. Why do all of the amp;<divamp;> tags only affect the last amp;<divamp;>?</p>

        <div class="test"></div>
        <div class="test"></div>
        <div class="test"></div>

        <p>The same results for amp;<pamp;> tags.</p>

        <p class="test"></p>
        <p class="test"></p>
        <p class="test"></p>

        <script type="text/javascript">
            //create arrays
            var divArr = new Array();
            var pArr = new Array();

            //call function to populate arrays
            divArr = getElementsByClassName('div','test');
            pArr = getElementsByClassName('p','test');

            //call function to register arrays elements events
            registerArrayElementsEvents(divArr,'div');
            registerArrayElementsEvents(pArr,'p');

            //retrieve elements that match the passed tag and class
            function getElementsByClassName(myTag,myClass) {
                //load all elements into array
                var elems = document.getElementsByTagName(myTag);
                //create new array placeholder
                var newArr = new Array();

                //iterate through elements array
                for (var i = 0; i < elems.length; i  ) {
                    //check to see if element class matches parameter
                    if (elems[i].className == myClass){
                        //add matched element to new array
                        newArr.push(elems[i]);
                    }
                }

                //return array of matched elements
                return newArr;
            }

            //register events to every element in the passed array
            function registerArrayElementsEvents(arr,type){
                //create object placeholder
                var currentObj = new Object();

                //iterate through the objects array
                for (var i = 0; i < arr.length; i  ) {
                    //assign current object corresponding to loop counter

                    currentObj = arr[i];

                    //write element index to element
                    currentObj.innerHTML = 'This is amp;<'   type   'amp;> '   i;

                    //add mouseover event to element
                    addEvent(currentObj,'mouseover',function(){
                        //set current element color to red
                        currentObj.style.color = '#f00'
                    });

                    //add mouseout event to element
                    addEvent(currentObj,'mouseout',function(){
                        //set current element color to black
                        currentObj.style.color = '#000'
                    });
                }
            }

            //register functions to events for objects
            function addEvent(obj,evt,fn){
                //if not IE
                        if (obj.addEventListener)
                    obj.addEventListener(evt,fn,false);
                //if IE
                else if (obj.attachEvent)
                    obj.attachEvent('on' evt,fn);
            }
        </script>
    </body>
  

Комментарии:

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

2. Честно говоря, я не понимаю, почему вы не можете использовать jQuery. В наши дни это практически обязательно для разработки Javascript (или, по крайней мере, эквивалента jQuery)

3. @Codemonkey — Я бы поставил вам 1, но я не могу найти плагин jQuery для этого…

4. У вас проблемы с замыканиями, см., например mennovanslooten.nl/blog/post/62

5. @Codemonkey Я ненавижу тебя за то, что ты это говоришь. Это неправильно не только в корне, но и идеологически. JQUERY — ЭТО НЕ ОЧЕНЬ ХОРОШИЙ КОД. Это минималистичная ОБОЛОЧКА на JavaScript для любителей скриптов, которые не могут написать свои собственные. jQuery способствует плохому программированию. БУДЬТЕ ОСТОРОЖНЫ.

Ответ №1:

Происходит то, что область действия currentObj in registerArrayElementsEvents ограничена registerArrayElementsEvents , а не функцией каждого события. Вам нужно поместить currentObj в область видимости каждой функции следующим образом:

 addEvent(currentObj, 'mouseover', (function (obj) {
    return function () { 
        obj.style.color = '#f00';
    };
})(currentObj));
  

В принципе, JavaScript определяет области видимости только на основе функций, а не блоков. Это означает, что

 for (...) { var x = arr[i] }
  

точно такой же, как:

 var x;
for (...) {x = arr[i]}
  

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

Ответ №2:

         //create arrays
        var divArr = new Array();
        var pArr = new Array();

        //call function to populate arrays
        divArr = getElementsByClassName('div','test');
        pArr = getElementsByClassName('p','test');
  

Присваивая новые значения divArr и pArr , вы перезаписываете массивы, назначенные изначально. Это не ваша проблема, это просто означает, что исходное назначение бесполезно.

У ТИхона есть один ответ, другой способ — избежать закрытия с помощью this :

 addEvent(currentObj, 'mouseover', function () {
        this.style.color = '#f00';
    });
  

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