简体   繁体   中英

Multiple click actions - Javascript

I have a button with id called 'draw' and want from it, each time I click on that draw button the next operation to process (ie shape in my case). I tried with style.visibility but didn't work. Maybe I did it wrong. However, here is the code:

window.onload = function() {
  var canvas = document.getElementById('myCanvas'), 
      draw = document.getElementById('draw'),
      clr = document.getElementById('clear'), 
      context = canvas.getContext('2d');
  var grad = context.createLinearGradient(100,0,200,0);

function shapeOne(){
    context.beginPath(); // circle
    context.fillStyle = 'blue';
    context.arc(200, 100, 100, 50 , 2 * Math.PI, false);
    context.fill();
    context.lineWidth = '1';
    context.stroke();
    context.closePath(); 
  }


function shapeTwo(){
    context.beginPath(); // rectangle
    grad.addColorStop(0,"#0033cc");
    grad.addColorStop(1,"#0066ff");
    context.fillStyle=grad;
    context.fillRect(120,40,160,120);
    context.strokeStyle="black";
    context.strokeRect(120,40,160,120);
    context.closePath();
  }

function shapeThree(){
    context.beginPath(); // line
    context.moveTo(280, 40);
    context.lineTo(120, 160);
    context.stroke();
    context.closePath();
  }

  draw.addEventListener('click', shapeOne, false);      
  draw.addEventListener('click', shapeTwo, false);
  draw.addEventListener('click', shapeThree, false);

  clr.addEventListener('click', function(){
    canvas.width = canvas.width;
  }, false);  

};

As others have said, currently all your event listeners bound to the 'draw' element will fire at the same time. Really there is no need to have multiple event listeners. You just need a way of knowing what shape you want to draw currently.

So I would declare a variable called something like currentShape and set it to zero.

var canvas = document.getElementById('myCanvas'), 
  draw = document.getElementById('draw'),
  clr = document.getElementById('clear'), 
  context = canvas.getContext('2d');
var grad = context.createLinearGradient(100,0,200,0);
// Start current shape at 0
var currentShape = 0;
// More code ...

I would then create an array which is basically a list of the shape-drawing functions you have.

like this:

var shapes = [shapeOne, shapeTwo, shapeThree]

Then instead of your three event listeners, just have one that looks something like this:

draw.addEventListener('click', function(){
    // Check if there is a function available for the current shape.
    if(shapes[currentShape]) {
        // If so, call that function and add one to the current shape.
        shapes[currentShape]();
        currentShape += 1;
    } else { // If the function isn't available, then lets assume we have already drawn all the shapes and need to start again.
         currentShape = 0;
         shapes[currentShape]();
    }
}, false); 

There are a bunch of other ways that you could do this as well. Including using a switch statement , which would possibly remove some code duplication.

No, this is not the way , because when you add more than one listener to the to the same event of a html element, all listeners will trigger at the same time.

So, you need to create a poll(array of functions) , then when the element is clicked you put a new function to execute in an array, then another function controls the execution of those function.

You can use an array of functions, your click event will put functions at the array and then you can call (as explain at this stackoverflow question ) in another moment.

If you want to control a dynamic execution of a list of functions this sample is a better solution .

How to add a list of functions:

var listRuns = [],
    ind = 0;
$('#btnRun').click(function(){
  var message = document.getElementById("txtMsg").value;

  listRuns.push(function(){
    run(message);
  });
});

How to execute them:

var runAll = function(){  
  console.log('called');
  if (listRuns.length>ind){
    listRuns[ind]();
    ind++; 
  }
};
var idInterval = setInterval(function(){
  runAll();
},1000);

So, independently of how many clicks the user did, you will execute all of them.

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