请帮助我找到一个使用普通'ol javascript的解决方案(我不能使用外部框架)。另外,CSS:hover选择器不适用于实际的实现。

注册事件进行时,所有事件都将调用最后一个注册事件数组项。

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

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

        <p>The same results for &lt;p&gt; 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 &lt;' + type + '&gt; ' + 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>

最佳答案

发生的是,在currentObj中的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值。为了克服这个问题,您可以在每次循环遍历时使用像我一样的匿名函数创建一个闭包。

08-16 20:34