简体   繁体   中英

Add event listener to canvas using for loop not returning correct index

Im trying to add an event listener to dynamic canvas. Instead of manually writting event listener for each canvas I used a for loop. The problem is when I click at canvas1 it returns id 3. It's suppose to be 1.

<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>

<script>

var canvas = []
var totalCanvas = 2

for(var i=1;i<=totalCanvas;i++){
    canvas[i] = document.getElementById('canvas'+i);
    canvas[i].addEventListener('mousedown', function(e) { onMouseDown(e,i) }, false);
}

function onMouseDown(e,i){
    console.log('ID'+i) //returning 3
}

</script>

The issue is because by the time you raise the mousedown event the loop has completed and i is always at the last value set in the loop.

One way to fix this would be to wrap the event handler in a closure to retain the state of the i value:

 var canvas = [] var totalCanvas = 2 for (var i = 1; i <= totalCanvas; i++) { canvas[i] = document.getElementById('canvas' + i); (function(i) { canvas[i].addEventListener('mousedown', function(e) { onMouseDown(e, i) }, false) })(i); } function onMouseDown(e, i) { console.log('ID' + i) //returning 3 }
 canvas { width: 50px; height: 50px; } #canvas1 { background-color: #C00; } #canvas2 { background-color: #0C0; }
 <canvas id="canvas1"></canvas> <canvas id="canvas2"></canvas>

A better way would be to select the canvas elements and loop through them, assigning the event handler to them directly and using the index argument of forEach() to get the index.

 var canvas = document.querySelectorAll('canvas'); canvas.forEach((el, i) => { el.addEventListener('mousedown', function(e) { onMouseDown(e, i + 1) }, false) }); function onMouseDown(e, i) { console.log('ID' + i) }
 canvas { width: 50px; height: 50px; } #canvas1 { background-color: #C00; } #canvas2 { background-color: #0C0; }
 <canvas id="canvas1"></canvas> <canvas id="canvas2"></canvas>

 var canvas = []; var totalCanvas = 2; for(var i=1;i<=totalCanvas;i++){ let a = i; canvas[i] = document.getElementById('canvas'+i); canvas[i].addEventListener('mousedown', function(e) { onMouseDown(e,a) }, false); } function onMouseDown(e,x){ console.log('ID'+x) //returning 3 }
 canvas { width: 50px; height: 50px; } #canvas1 { background-color: #C00; } #canvas2 { background-color: #0C0; }
 <canvas id="canvas1"></canvas> <canvas id="canvas2"></canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM