JS做农场系列(三):植物在相应土地上生长的实现
今天所做的功能是:
①整理提取CSS样式;②种子包默认种子两颗;③给每块土地添加鼠标点击事件;④植物的定时器生长。
碰到的问题:当携带种子点击可种植的空地时触发当前土地上的种子生长计时器,但是在页面加载初始化土地的时候,添加点击事件是在循环中。外部参数oDiv“当前的土地”时刻在改变,循环结束是最后一块土地对象。但是我需要的是点击某块土地就触发某块土地上的事件。
解决方案:绑定事件的时候运用闭包,调用外部参数oDiv
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
//
闭包方法***************
function Closure(oDiv) {
// 要调用外部的oDiv参数
return function () {
// 如果可以播种
if (seedObject != null && seedObject.isCanSow && seedCount > 0 ) {
seedObject.sowSeed(oDiv);
}
else {
alert( " 对不起,没有种子无法播种! " );
}
}
}
// ************************************************************
// 初始化土地(无缝拼接),【第一个div的left、top , 土地一行个数,土地一列个数】
function initMap(left, top, row, col) {
var l = left; // 第一块土地的left
var t = top; // 第一块土地的top
var landID = 0 ; // 土地标识
// 循环列,创建每列的土地
for ( var j = 0 ; j < col; j ++ ) {
// 循环行,创建每行的土地
for ( var i = 0 ; i < row; i ++ ) {
var oDiv = document.createElement( " div " );
landID ++ ;
oDiv.setAttribute( " id " , " land " + landID);
oDiv.style.width = 200 ;
oDiv.style.height = 100 ;
oDiv.style.position = " absolute " ;
oDiv.style.left = left;
oDiv.style.top = top;
oDiv.style.background = " url('http://images.cnblogs.com/cnblogs_com/meiqunfeng/农场/土地.png') " ;
// 居中
oDiv.style.lineHeight = 100 ;
oDiv.style.margin = " 0px auto " ;
oDiv.style.textAlign = " center " ;
oDiv.style.verticalAlign = " middle " ;
// 循环给每一块土地绑定事件(这里是一个闭包,需要调用外部参数“当前的土地”,这个oDiv并不是固定的,他是随循环的运行在变)
oDiv.onmousedown = Closure(oDiv);
document.getElementById( " map " ).appendChild(oDiv);
left += 100 ; top += 50 ;
}
// 创建第二行土地的时候,注意第二行土地的第一个left和top
left = l - 100 ;
top = t + 50 ;
}
}
function Closure(oDiv) {
// 要调用外部的oDiv参数
return function () {
// 如果可以播种
if (seedObject != null && seedObject.isCanSow && seedCount > 0 ) {
seedObject.sowSeed(oDiv);
}
else {
alert( " 对不起,没有种子无法播种! " );
}
}
}
// ************************************************************
// 初始化土地(无缝拼接),【第一个div的left、top , 土地一行个数,土地一列个数】
function initMap(left, top, row, col) {
var l = left; // 第一块土地的left
var t = top; // 第一块土地的top
var landID = 0 ; // 土地标识
// 循环列,创建每列的土地
for ( var j = 0 ; j < col; j ++ ) {
// 循环行,创建每行的土地
for ( var i = 0 ; i < row; i ++ ) {
var oDiv = document.createElement( " div " );
landID ++ ;
oDiv.setAttribute( " id " , " land " + landID);
oDiv.style.width = 200 ;
oDiv.style.height = 100 ;
oDiv.style.position = " absolute " ;
oDiv.style.left = left;
oDiv.style.top = top;
oDiv.style.background = " url('http://images.cnblogs.com/cnblogs_com/meiqunfeng/农场/土地.png') " ;
// 居中
oDiv.style.lineHeight = 100 ;
oDiv.style.margin = " 0px auto " ;
oDiv.style.textAlign = " center " ;
oDiv.style.verticalAlign = " middle " ;
// 循环给每一块土地绑定事件(这里是一个闭包,需要调用外部参数“当前的土地”,这个oDiv并不是固定的,他是随循环的运行在变)
oDiv.onmousedown = Closure(oDiv);
document.getElementById( " map " ).appendChild(oDiv);
left += 100 ; top += 50 ;
}
// 创建第二行土地的时候,注意第二行土地的第一个left和top
left = l - 100 ;
top = t + 50 ;
}
}
===================
下面的例子更详细更好的解决了:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
<
body
>
< ul >
< li > one </ li >
< li > two </ li >
< li > three </ li >
< li > one </ li >
</ ul >
*/
var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++ ){
lists[ i ].onmouseover = function(){
alert( i );
};
}
< ul >
< li > one </ li >
< li > two </ li >
< li > three </ li >
< li > one </ li >
</ ul >
*/
var lists = document.getElementsByTagName('li');
for(var i = 0 , len = lists.length ; i < len ; i++ ){
lists[ i ].onmouseover = function(){
alert( i );
};
}
你会发现当鼠标移过每一个<li>元素时,总是弹出4,而不是我们期待的元素下标。
解决办法一:
解决办法一
var
lists
=
document.getElementsByTagName(
'
li
'
);
for ( var i = 0 , len = lists.length; i < len; i ++ ) {
( function (index) {
lists[index].onmouseover = function () {
alert(index);
};
})(i);
}
for ( var i = 0 , len = lists.length; i < len; i ++ ) {
( function (index) {
lists[index].onmouseover = function () {
alert(index);
};
})(i);
}
解决办法二:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
var
lists
=
document.getElementsByTagName(
'
li
'
);
for ( var i = 0 , len = lists.length; i < len; i ++ ) {
lists[i].$$index = i; // 通过在Dom元素上绑定$$index属性记录下标
lists[i].onmouseover = function () {
alert( this .$$index);
};
}
for ( var i = 0 , len = lists.length; i < len; i ++ ) {
lists[i].$$index = i; // 通过在Dom元素上绑定$$index属性记录下标
lists[i].onmouseover = function () {
alert( this .$$index);
};
}
解决办法三:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
function
eventListener(list, index) {
list.onmouseover = function () {
alert(index);
};
}
var lists = document.getElementsByTagName( ' li ' );
for ( var i = 0 , len = lists.length; i < len; i ++ ) {
eventListener(lists[i], i);
}
list.onmouseover = function () {
alert(index);
};
}
var lists = document.getElementsByTagName( ' li ' );
for ( var i = 0 , len = lists.length; i < len; i ++ ) {
eventListener(lists[i], i);
}