0

我有一个任务,我似乎无法弄清楚这一部分:我已经编写了一个 Javascript 函数来为每个图像标签预加载/预缓存两个图像,来自基于 img-html 标签 ID 的“img”文件夹。这部分工作正常。

但是,更改图像mouseovermouseout使用的addEventListener功能似乎不起作用,我似乎无法弄清楚为什么!如果我调试,我可以看到图像加载正常并且没有错误。但是,mouseover它似乎不起作用!

HTML页面:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="author" content="Nilay Panchal"/>
        <meta name="description" content="Part 1 Assignment 3"/>
        <title>HomePage</title>
        <script src="js/breadcrumb.js"></script>
        <script src="js/preloader.js"></script>
        <script type="text/javascript">
            function animal(name,scientificName,typeOfFood,sleepingPattern,size) {
                this.name = {
                    realName:name,
                    scientificName:scientificName
                    };
                this.typeOfFood = typeOfFood;
                this.sleepingPattern = sleepingPattern;
                this.size = size;                    
            }
            
            function makeNewAnimal(name, scientificName, typeOfFood,sleepingPattern,size) {
                var animalClicked = new animal(name, scientificName, typeOfFood,sleepingPattern,size);          
                var finalStringObject = "{"+myOwnRecursiveToStringMethod(animalClicked,"")+"}";
                document.getElementById("stringOfObject").value = finalStringObject;
                var backToObject = parseStringAndConvertToObject(finalStringObject);
                document.getElementById("jsonDisplay").value = backToObject;                
            }
            
            function myOwnRecursiveToStringMethod(objectToParse, outputString) {
                var first = 1;
                for(nameOfProperty in objectToParse){               
                    if(objectToParse[nameOfProperty] instanceof Object) {                       
                        outputString += nameOfProperty+":{";
                        outputString = myOwnRecursiveToStringMethod(objectToParse[nameOfProperty],outputString);
                        outputString += "},";
                    } else{                         
                        outputString = outputString + nameOfProperty +":'"+ objectToParse[nameOfProperty]+"',";
                    }                                                   
                }
            if(outputString.charAt(outputString.length-1) == ',') {
                    outputString = outputString.slice(0,-1);
            }
            return outputString;            
         }
         
         function parseStringAndConvertToObject(finalString) {
            eval("var backToObject = "+finalString);
            return backToObject;
         }
        </script>
    </head>
    <body>
        <h3>Navigation List:</h3>
        <nav id="navigationBar" style="border-style: double ;border-width: 10">
            <ul>
                <li><a href="#">Assignment 3 Root</a></li>
                <li><a href="Animals/index.html">All Animals</a>
                    <ul>
                        <li><a href="Animals/Insects.html">Insects.html</a></li>
                        <li><a href="Animals/Birds/index.html">Birds-Aves</a>
                            <ul>
                                <li><a href="Animals/Birds/Pelican/index.html">The Mighty Pelican</a></li>
                            </ul>
                        </li>                       
                        <li><a href="Animals/Giraffe/index.html">The Tall Giraffe</a></li>
                        <li><a href="Animals/Rhino/index.html">The Hefty Rhinoceros</a></li>                        
                    </ul>                   
                </li>               
            </ul>           
        </nav>
        <div style="border-style:groove;padding-bottom: 10px;padding-left: 10px">
            <h4><u>BREADCRUMB:</u></h4>
            <div id="breadcrumb"></div>
        </div>
        <div style="text-align: center">
        <h3><u>Please click on any of the images below and the JSON object of the animals data will be displayed in the text area below!</u></h3>
        <a href="javascript:void(0);" onclick="makeNewAnimal('Pelican','Pelecanus','Pescatarian','Diurnal','Small')"><img style="width:300px;height:300px"  id='pelican' alt="Pelican"/></a>
        <a href="javascript:void(0);" onclick="makeNewAnimal('Rhinoceros','Rhinocerotidae','Herbivore','Diurnal','Large')"><img style="width:500px;height:300px"  id="rhino" alt="Rhinoceros"/></a>
        <br>
        <a href="javascript:void(0);" onclick="makeNewAnimal('Giraffe','Giraffa camelopardalis','Herbivore','Diurnal','Very Large')"><img style="width:500px;height:300px" id="giraffe" alt="Giraffe"/></a>
        <a href="javascript:void(0);" onclick="makeNewAnimal('Owl','Strigiformes','Carnivore','Nocturnal','Very Small')"><img style="width:300px;height:300px"  id='owl' alt="Owl"/></a>
        </div>
        <hr>
        <h5>Animal Objects to String:</h5>
        <textarea style="width:100%" id="stringOfObject"></textarea>
        <h5>Animal Strings back to Objects</h5>
        <textarea style="width:100%" id="jsonDisplay"></textarea>
    </body>
    <script type="text/javascript">
        window.onload = precacheAndLoad();
        makeBreadcrumb(location.pathname);        
    </script>
</html>

Javascript 文件:

/*
 * 
 * Below I wrote a function to perform all the image operations and precaching too. To add a new image simply do the following:
 * 1) Include, the JS file and add a new img tag on the HTML page. The ID of this img tag should be the name of the animal (eg. hippo).
 * 2) Save two images named the same as the animal, with a suffix of 1 and 2 for default image and hover over image. (eg. hippo1.jpg and hippo2.jpg)
 * The script will take care of the rest!
 */

var allImageVariables = new Array();

function precacheAndLoad() {    
    var allImages = document.getElementsByTagName("img");
    for(imageCount=0; imageCount<allImages.length ; imageCount++) {
        currentImageId = allImages[imageCount].id;
        eval("var "+currentImageId+"1 = new Image(300,300)");
        eval("var "+currentImageId+"2 = new Image(300,300)");
        eval(currentImageId+"1.src = 'img/"+currentImageId+"1.jpg'");
        eval(currentImageId+"2.src = 'img/"+currentImageId+"2.jpg'");
        allImageVariables[imageCount] = eval(currentImageId+"1");
        allImageVariables[imageCount+allImages.length] = eval(currentImageId+"2");      
        allImages[imageCount].src = eval(currentImageId+"1.src");
        allImages[imageCount].addEventListener("mouseover", hoverImage(currentImageId,imageCount+allImages.length), false); 
        allImages[imageCount].addEventListener("mouseout", outImage(currentImageId,imageCount), false);
    }
}

function hoverImage(currentImageId, arrayIndexOfImageVariable) {
    eval("document.getElementById('"+currentImageId+"').src = allImageVariables[arrayIndexOfImageVariable].src");
}

function outImage(currentImageId, arrayIndexOfImageVariable) {
    eval("document.getElementById('"+currentImageId+"').src = allImageVariables[arrayIndexOfImageVariable].src");
} 
4

1 回答 1

0

因为您正在执行函数并传递返回结果,而不是在使用时传递对函数的引用addEventListener()。当你()在函数名上使用时,它会立即执行。要仅传递引用,您只需要传递函数的名称,或者如果您需要自定义参数,那么您需要创建一个可以传递的 shell 函数。

此外,您正在尝试for在事件处理程序中使用循环变量,因此您需要创建一个闭包,以便在for循环完成后很长时间内为事件处理程序保留这些变量的值:

改变这个:

    allImages[imageCount].addEventListener("mouseover", hoverImage(currentImageId,imageCount+allImages.length), false); 
    allImages[imageCount].addEventListener("mouseout", outImage(currentImageId,imageCount), false);

为此(为便于阅读添加了换行符):

(function(imageCount, currentImageId) {
    allImages[imageCount].addEventListener("mouseover", function() {
        hoverImage(currentImageId,imageCount+allImages.length);
    }, false); 
    allImages[imageCount].addEventListener("mouseout", function() {
        outImage(currentImageId,imageCount);
    }, false);
})(imageCount, currentImageId);

另外,你到底为什么要eval()像现在这样使用。您可以在没有它的情况下编写代码,并获得更好的代码、更好的性能,并且在某些情况下更安全。

例如,这个:

    eval("var "+currentImageId+"1 = new Image(300,300)");
    eval("var "+currentImageId+"2 = new Image(300,300)");
    eval(currentImageId+"1.src = 'img/"+currentImageId+"1.jpg'");
    eval(currentImageId+"2.src = 'img/"+currentImageId+"2.jpg'");

可以是这样的:

    var images = [];
    images.push(new Image(300,300));
    images.push(new Image(300,300));
    images[0].src = 'img/'+currentImageId+'1.jpg');
    images[1].src = 'img/'+currentImageId+'2.jpg');

eval()您可以使用对象或数组并将动态变量放入其中,然后从那里引用它们,而不是通过直接的变量名来引用它们,而不是用声明变量。这是创建动态变量的常用方法。

于 2013-11-05T04:12:01.363 回答