Javascript持久性>逻辑

时间:2011-05-03 20:31:25

标签: javascript arrays

请帮我找一个使用普通'ol javascript(我不能使用外部框架)的解决方案。此外,CSS:悬停选择器不适用于现实世界的实现。

使用已注册事件进行的事情设置都会调用最后一个已注册的事件数组项。

<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>

2 个答案:

答案 0 :(得分:3)

正在发生的事情是,currentObjregisterArrayElementsEvents的范围限定为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的最新值。为了解决这个问题,你可以使用像我这样的匿名函数在每次循环时创建一个闭包。

答案 1 :(得分:1)

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

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

通过为divArrpArr分配新值,您可以覆盖最初分配的数组。这不是你的问题,只是意味着原来的任务毫无用处。

TIkhon有一个答案,另一种方法是避免this的封闭:

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

但您必须修改addEvent的{​​{1}}功能,以便正确设置attachEvent。我马上就补充说......