Angular / JS - setTimeout仅在鼠标单击后执行

时间:2017-10-24 09:52:13

标签: javascript angularjs

我正在建立一个网站来计算网格中两个点之间的最短路径 使用AngularJS。

我已经有了算法,我可以为路径着色,但是我想要在tile(setTimeout(1000))之后对路径进行着色。

在这里进行了长时间的搜索后,我发现了如何在for循环中设置setTime,但是现在只有在鼠标单击后才会改变它们的颜色(不知道为什么)。

示例:第一个瓷砖更改颜色 - > 3秒后&鼠标点击 - > 4块瓷砖改变了颜色。 (等等时间过去了。)

我虽然是因为事件监听器,但我在使用它们之后删除了它们。

编辑:

function colorThePath(tile) {
  tile.color = "purple";
}

for (var i = 0; i < shortestPath.length - 1; i++) {
  if (shortestPath[i] == 'East') {
    $interval(function() {
      colorThePath(self.board[self.startTile.x][self.startTile.y + 1])
    }, 2000, 1);
    self.startTile = self.board[self.startTile.x][self.startTile.y + 1];
  } else if (shortestPath[i] == 'South') {
    self.board[self.startTile.x + 1][self.startTile.y].color = "purple";
    self.startTile = self.board[self.startTile.x + 1][self.startTile.y];
  } else if (shortestPath[i] == 'West') {
    self.board[self.startTile.x][self.startTile.y - 1].color = "purple";
    self.startTile = self.board[self.startTile.x][self.startTile.y - 1];
  } else if (shortestPath[i] == 'North') {
    self.board[self.startTile.x - 1][self.startTile.y].color = "purple";
    self.startTile = self.board[self.startTile.x - 1][self.startTile.y];
  }
}

“着色”发生在“go”功能中(在js文件的末尾)。

HTML code:

<!doctype html>

<html ng-app="myApp">
<head>
<meta charset="utf-8">

<title>Main</title>
<!-- angular -->
<script src="../scripts/angular.js"></script>
<script type="text/javascript" src="../scripts/angular-ui-router.js"></script>
<!-- Angular Material style sheet -->
<link rel="stylesheet"
	href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
<!-- Angular Material Library -->
<script
	src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>

<script type="text/javascript" src="../scripts/MainRoute.js"></script>
<script type="text/javascript" src="../scripts/mainController.js"></script>
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="../css/a.css"></link>
</head>

<body ng-controller="mainController as m">
<div id="navBar">
	<nav class="navbar navbar-default">
		<div class="container-fluid">
			<div class="navbar-header">
				<a class="navbar-brand" href="#">WebSiteName</a>
			</div>
			<ul class="nav navbar-nav">
				<li class="active"><a href="#">Home</a></li>
				<li><a ng-click="m.start()">Start</a></li>
				<li><a ng-click="m.end()">End</a></li>
				<li><a ng-click="m.go()">Go!</a></li>
			</ul>
		</div>
	</nav>
</div>

	<div>
		<table id="table">
			<tr ng-repeat="r in m.board">
				<td ng-repeat="x in r track by x.id" style="background-color: {{x.color}}" ng-click="m.changeColor(x.id)" id="{{x.id}}">{{x.id}}</td>
			</tr>
		</table>
	</div>
</body>
</html>

JS / Angular Code:

! - begin snippet:js hide:false console:true babel:false - &gt;

(function() {

    var module = angular.module("myApp");
    module.controller("mainController", mainControllerCTOR)

    function mainControllerCTOR() {
        this.board;
        this.startTile;
        this.endTile;

        var self = this;

        function Tile(x, y) {
            this.id = x + "," + y;
            this.x = x;
            this.y = y;
            this.pressed = false;
            this.color = "yellow";
            this.secret = 'Empty';
        }

        window.onload = function() {
            self.board = [];
            for (var i = 0; i < 12; i++) {
                self.board[i] = [];
                for (var j = 0; j < 12; j++) {
                    self.board[i][j] = new Tile(i, j);
                }
            }
        }

        this.changeColor = function(id) {
            for (var i = 0; i < 12; i++) {
                for (var j = 0; j < 12; j++) {
                    if (self.board[i][j].id == id) {
                        if (self.board[i][j].color == "yellow") {
                            self.board[i][j].color = "blue";
                            self.board[i][j].secret = 'Obstacle';
                        } else {
                            self.board[i][j].color = 'yellow';
                            self.board[i][j].secret = 'Empty';
                        }
                    }
                }
            }
        }

        this.chooseStart = function(event) {
            var tile = document.getElementById(event.target.id);
            for (var i = 0; i < 12; i++) {
                for (var j = 0; j < 12; j++) {
                    if (self.board[i][j].id == tile.id) {
                        self.board[i][j].color = "green";
                        self.board[i][j].secret = 'Start';
                        self.startTile = self.board[i][j];
                    }
                }
            }
            tile.innerHTML = "start"
            var table = document.getElementById("table");
            table.removeEventListener('click', self.chooseStart);
        }

        this.start = function() {
            var table = document.getElementById("table");
            table.addEventListener('click', self.chooseStart);
        }

        this.chooseEnd = function(event) {
            var tile = document.getElementById(event.target.id);
            for (var i = 0; i < 12; i++) {
                for (var j = 0; j < 12; j++) {
                    if (self.board[i][j].id == tile.id) {
                        self.board[i][j].color = "red";
                        self.board[i][j].secret = 'Goal';
                        self.endTile = self.board[i][j];
                    }
                }
            }
            tile.innerHTML = "end";
            var table = document.getElementById("table");
            table.removeEventListener('click', self.chooseEnd);
        }

        this.end = function() {
            var table = document.getElementById("table");
            table.addEventListener('click', self.chooseEnd);
        }

        // =======================================================================
        // Breadth-First Search - Greg Trowbridge JS algorithm
        // =======================================================================
        var findShortestPath = function(startCoordinates, grid) {
            var distanceFromTop = startCoordinates[0];
            var distanceFromLeft = startCoordinates[1];

            var location = {
                distanceFromTop : distanceFromTop,
                distanceFromLeft : distanceFromLeft,
                path : [],
                status : 'Start'
            };

            var queue = [ location ];

            while (queue.length > 0) {
                var currentLocation = queue.shift();

                var newLocation = exploreInDirection(currentLocation, 'North',
                        grid);
                if (newLocation.status === 'Goal') {
                    return newLocation.path;
                } else if (newLocation.status === 'Valid') {
                    queue.push(newLocation);
                }

                var newLocation = exploreInDirection(currentLocation, 'East',
                        grid);
                if (newLocation.status === 'Goal') {
                    return newLocation.path;
                } else if (newLocation.status === 'Valid') {
                    queue.push(newLocation);
                }

                var newLocation = exploreInDirection(currentLocation, 'South',
                        grid);
                if (newLocation.status === 'Goal') {
                    return newLocation.path;
                } else if (newLocation.status === 'Valid') {
                    queue.push(newLocation);
                }

                var newLocation = exploreInDirection(currentLocation, 'West',
                        grid);
                if (newLocation.status === 'Goal') {
                    return newLocation.path;
                } else if (newLocation.status === 'Valid') {
                    queue.push(newLocation);
                }
            }
            return false;
        };

        var locationStatus = function(location, grid) {
            var gridSize = grid.length;
            var dft = location.distanceFromTop;
            var dfl = location.distanceFromLeft;

            if (location.distanceFromLeft < 0
                    || location.distanceFromLeft >= gridSize
                    || location.distanceFromTop < 0
                    || location.distanceFromTop >= grid.size) {
                return 'Invalid';
            } else if (grid[dft][dfl] === 'Goal') {
                return 'Goal';
            } else if (grid[dft][dfl] !== 'Empty') {
                return 'Blocked';
            } else {
                return 'Valid';
            }
        };

        var exploreInDirection = function(currentLocation, direction, grid) {
            var newPath = currentLocation.path.slice();
            newPath.push(direction);

            var dft = currentLocation.distanceFromTop;
            var dfl = currentLocation.distanceFromLeft;

            if (direction === 'North') {
                dft -= 1;
            } else if (direction === 'East') {
                dfl += 1;
            } else if (direction === 'South') {
                dft += 1;
            } else if (direction === 'West') {
                dfl -= 1;
            }

            var newLocation = {
                distanceFromTop : dft,
                distanceFromLeft : dfl,
                path : newPath,
                status : 'Unknown'
            };

            newLocation.status = locationStatus(newLocation, grid);

            if (newLocation.status === 'Valid') {
                grid[newLocation.distanceFromTop][newLocation.distanceFromLeft] = 'Visited';
            }
            return newLocation;
        };

        // =======================================================================

        this.go = function() {
            var grid = [];
            for (var j = 0; j < 12; j++) {
                grid[j] = self.board[j].slice();
            }

            for (var i = 0; i < 12; i++) {
                for (var j = 0; j < 12; j++) {
                    grid[i][j] = grid[i][j].secret;
                }
            }

            var x = new Number(self.startTile.x);
            var y = new Number(self.startTile.y);

            var shortestPath = findShortestPath([ x, y ], grid);
            console.log(shortestPath);

            function colorThePath(i) {

                if (shortestPath[i] == 'East') {
                    self.board[self.startTile.x][self.startTile.y + 1].color = "purple";
                    self.startTile = self.board[self.startTile.x][self.startTile.y + 1];
                } else if (shortestPath[i] == 'South') {
                    self.board[self.startTile.x + 1][self.startTile.y].color = "purple";
                    self.startTile = self.board[self.startTile.x + 1][self.startTile.y];
                } else if (shortestPath[i] == 'West') {
                    self.board[self.startTile.x][self.startTile.y - 1].color = "purple";
                    self.startTile = self.board[self.startTile.x][self.startTile.y - 1];
                } else if (shortestPath[i] == 'North') {
                    self.board[self.startTile.x - 1][self.startTile.y].color = "purple";
                    self.startTile = self.board[self.startTile.x - 1][self.startTile.y];
                }

                if (--i > -1) {
                    setTimeout(function() {
                        colorThePath(i);
                    }, 1000);
                }
            }

            colorThePath(shortestPath.length - 1);
        };

    }
})();

1 个答案:

答案 0 :(得分:0)

如果没有检查所有逻辑,Angular摘要循环不会注意到setTimeout触发的事件,你应该使用$ timeout。 https://coderwall.com/p/udpmtq/angularjs-use-timeout-not-settimeout