开发者

Adding event listener to a point

(see problem in action) generally my problem is - I can add elements with innerHTML, I can style them, but I can not addEventListeners on to them. Has any one seen such problem? (see how it worked before I added html generation)

So I have such simple JavaScript:

function $(id) {
  return document.getElementById(id);
}

/* ------------------------------------------------ */
var POINTS = $('points');
var W = 800, W1_2 = W / 2;
var H = 410, H1_2 = H / 2;
var FPS = 20, FRAMES = 0;
var str ="";
var CV = $('canvas');
var CX = CV.getContext('2d');
CV.width = W;
CV.height = H;

function reCoord(){
 // coort = $('coor');
 // coort.innerHTML = str;
}
/* ------------------------------------------------ */
var id = 0;
var Draggable = function(PointParams, x, y, callbacks) {
   var elementIdSring;
  var t = this;
       
  switch (PointParams) {
   case 'point':
      POINTS.innerHTML += '<div id="p' + id + '" class="point"></div>';   
     elementIdSring = 'p'+String(id);
        break;
   case 'cp1':
      POINTS.innerHTML += '<div id="p' + id + '" class="point cp1"></div>';
      elementIdSring = 'p'+String(id);
        break;
      开发者_StackOverflow社区   case 'cp2':
      POINTS.innerHTML += '<div id="p' + id + '" class="point cp2"></div>';    
      elementIdSring = 'p'+String(id);
        break;     
                case 'limiter':
      POINTS.innerHTML += '<div id="l' + id + '" class="point limiter"></div>';    
      elementIdSring = 'l'+String(id);
        break;   
  }
 id++;
    coort = $('coor');
  coort.innerHTML += elementIdSring + ' ';
 var  e = $(elementIdSring);
  t.element = e;
  
  
  t.callbacks = {
    begin: function() {},
    end: function() {},
    drag: function() {}
  };
  if (callbacks != null) for (var v in callbacks) {
    switch (v) {
    case 'begin':
    case 'end':
    case 'drag':
      if (callbacks[v] instanceof Function)
        t.callbacks[v] = callbacks[v];
      break;
    }
  }
  t.move(x, y);
         var  e = $(elementIdSring);
  e.addEventListener('mousedown', function(ev) {
    if (ev.which == 1) {
      Draggable.Target = [t,
                          t.x - ev.clientX,
                          t.y - ev.clientY];
      t.callbacks.begin();
      ev.preventDefault();
      ev.stopPropagation();

    }
  }, false);
};

Draggable.prototype.move = function(x, y) {
reCoord();
  var s = this.element.style;
  s.left = (this.x = x) + 'px';
  s.top = (this.y = y) + 'px';   

};

Draggable.tracking = function(ev) {
    var t = Draggable.Target;
    str = 'X : ' +ev.clientX + ', ' + 'Y :' + ev.clientY ;
  if (t) {
    t[0].move(ev.clientX + t[1], ev.clientY + t[2]);
    t[0].callbacks.drag(); 

  }

};

Draggable.finish = function(ev) {
  var t = Draggable.Target;
  if (t) {
    t[0].move(ev.clientX + t[1], ev.clientY + t[2]);
    t[0].callbacks.end(); 
    coort = $('coor');
  coort.innerHTML = " ";
    Draggable.Target = null;
    
  }
};

window.addEventListener('mousemove',
                        Draggable.tracking, false);
window.addEventListener('mouseup',
                        Draggable.finish, false);

/* ------------------------------------------------ */



var linePoints = [
          new Draggable('point', 50, 175),
          new Draggable('cp1', 175,  225),
          new Draggable('cp2', 175, 120),
          new Draggable('point', 350, 120),
          
          new Draggable('point', 370, 175),
          new Draggable('cp1', 475,  225),
          new Draggable('cp2', 475, 175),
          new Draggable('point', 650, 165),
  
          new Draggable('point', 50, 275) ,
          new Draggable('cp1', 175, 225),
          new Draggable('cp2', 175, 325),
          new Draggable('point', 350, 325),
  

          new Draggable('point', 370, 275) ,
          new Draggable('cp1', 475, 225),
          new Draggable('cp2', 475, 275),
          new Draggable('point', 650, 285)
         ];




var Limits = [
          new Draggable('limiter', 50, 150),
          new Draggable('limiter', 650, 150),
          new Draggable('limiter', 50, 300) ,
          new Draggable('limiter', 650, 300)
 
         ];

/* ------------------------------------------------ */
window.addEventListener('mousemove',
                        Draggable.tracking, false);
window.addEventListener('mouseup',
                        Draggable.finish, false);
var MODE = 1;

function line(p0, p1, p2, p3, t) {
  return [(1 - t) * p0.x + t * p3.x,
          (1 - t) * p0.y + t * p3.y];
}

function quadratic(p0, p1, p2, p3, t) {
  var s = 1 - t;
  return [s*s*p0.x + 2*s*t*p1.x + t*t*p3.x,
          s*s*p0.y + 2*s*t*p1.y + t*t*p3.y];
}

function bezier(p0, p1, p2, p3, t) {
  var s = 1 - t;
  return [s*s*s*p0.x + 3*s*s*t*p1.x +
          3*s*t*t*p2.x + t*t*t*p3.x,
          s*s*s*p0.y + 3*s*s*t*p1.y +
          3*s*t*t*p2.y + t*t*t*p3.y];
}

function catmull(p0, p1, p2, p3, t) {
  var v = [(p2.x - p0.x)/2, (p2.y - p0.y)/2];
  var w = [(p3.x - p1.x)/2, (p3.y - p1.y)/2];
  return [(2*p1.x-2*p2.x+v[0]+w[0])*t*t*t +
          (-3*p1.x+3*p2.x-2*v[0]-w[0])*t*t +
          v[0]*t + p1.x,
          (2*p1.y-2*p2.y+v[1]+w[1])*t*t*t +
          (-3*p1.y+3*p2.y-2*v[1]-w[1])*t*t +
          v[1]*t + p1.y];
}

/* ------------------------------------------------ */
var TYPE = $('type');


TYPE.addEventListener('change', redraw, false);

function drawArrow(type, t, P0, P1, P2, P3) {
  var c, c0, c1;
  c0 = window[type](P0, P1, P2, P3, t - 0.1);
  c  = window[type](P0, P1, P2, P3, t);
  c1 = window[type](P0, P1, P2, P3, t + 0.1);
  CX.save();
  CX.translate(c[0], c[1]);
  CX.rotate(Math.atan2(c1[1] - c0[1], c1[0] - c0[0]));
  CX.beginPath();
  CX.moveTo(0, 0);
  CX.lineTo(-10, 10);
  CX.lineTo(-10, -10);
  CX.closePath();
  CX.stroke();
  CX.restore();
}

function locLiner(P0start,P3end, color){
 CX.strokeStyle = color;
    CX.beginPath();
  CX.moveTo(P0start.x, P0start.y);
    CX.lineTo(P3end.x, P3end.y);
   CX.stroke();
}

function locBesier(P0start, cp1, cp2, P3end){
    CX.strokeStyle = '#000';
    CX.beginPath();
    CX.moveTo(P0start.x, P0start.y);
    CX.bezierCurveTo(cp1.x, cp1.y,
                     cp2.x, cp2.y,
                     P3end.x, P3end.y);
    CX.stroke();
    CX.strokeStyle = '#ccc';
    CX.beginPath();
    CX.moveTo(P0start.x, P0start.y);
    CX.lineTo(cp1.x, cp1.y);
    CX.lineTo(cp2.x, cp2.y);
    CX.lineTo(P3end.x, P3end.y);
    CX.stroke(); 
     
}

function locQuadratic(P0start, cp1, P3end){
 CX.strokeStyle = '#000';  
   CX.beginPath();
  CX.moveTo(P0start.x, P0start.y);
    CX.quadraticCurveTo(cp1.x, cp1.y,
                        P3end.x, P3end.y);
    CX.stroke();

    CX.strokeStyle = '#ccc';
    CX.beginPath();
    CX.moveTo(P0start.x, P0start.y);
    CX.lineTo(cp1.x, cp1.y);
    CX.lineTo(P3end.x, P3end.y);
    CX.stroke();
  
}

function redraw() {
  var type = TYPE.value, i, c, c0, c1, t, d;
  CX.setTransform(1,0, 0,1, 0,0);
  CX.clearRect(0, 0, W, H);

  CX.setTransform(1,0, 0,1, -10,-10);
   
   for(i =0; i<Limits.length; i=i+2){locLiner(Limits [i], Limits[i+1], '#FF0000');} 

  CX.strokeStyle = '#000';
  CX.beginPath();

  switch (POINTS.className = type) {
  case 'line':
      for(i =0; i<linePoints.length; i=i+4){locLiner(linePoints[i], linePoints[i+3], '#000');}

    break;
  case 'quadratic':
for(i =0; i<linePoints.length; i=i+4){locQuadratic(linePoints[i], linePoints[i+1], linePoints[i+3]);}
      
      
    break;
  case 'bezier':
      for(i =0; i<linePoints.length; i=i+4){locBesier(linePoints[i], linePoints[i+1], linePoints[i+2], linePoints[i+3]);}
  
    break;

  default:
    return;
  }
 for(i =3; i<linePoints.length; i=i+16){locLiner(linePoints[i], linePoints[i+1]); CX.beginPath();
                                         CX.strokeStyle = '#000000'; 
            CX.fillStyle   = '#38A1DB';                          
   CX.moveTo(linePoints[i].x,linePoints[i].y);
                                         
    CX.bezierCurveTo(linePoints[i].x , (linePoints[i].y +( linePoints[i+1].y - linePoints[i].y)/2), linePoints[i+1].x, (linePoints[i].y +( linePoints[i+1].y - linePoints[i].y)/2), linePoints[i+1].x,linePoints[i+1].y);
      CX.bezierCurveTo(linePoints[i+1].x , (linePoints[i+1].y +( linePoints[i+8+1].y - linePoints[i+1].y)/2), linePoints[i+8+1].x, (linePoints[i+1].y +( linePoints[i+8+1].y - linePoints[i+1].y)/2), linePoints[i+8+1].x,linePoints[i+8+1].y);
    CX.bezierCurveTo(linePoints[i+8+1].x , (linePoints[i+8+1].y +( linePoints[i+8].y - linePoints[i+8+1].y)/2), linePoints[i+8].x, (linePoints[i+8+1].y +( linePoints[i+8].y - linePoints[i+8+1].y)/2), linePoints[i+8].x,linePoints[i+8].y);
           CX.bezierCurveTo(linePoints[i+8].x , (linePoints[i+8].y +( linePoints[i].y - linePoints[i+8].y)/2), linePoints[i].x, (linePoints[i+8].y +( linePoints[i].y - linePoints[i+8].y)/2), linePoints[i].x,linePoints[i].y);                                
   CX.fill(); 
    }

  CX.strokeStyle = '#39B7CD';

   for (i = 0; i < 100; i += 10) {
      for(j =0; j<linePoints.length; j=j+4){   drawArrow(type, (i + FRAMES % 10) / 100, linePoints[j], linePoints[j+1], linePoints[j+2], linePoints[j+3]);}
  }
  
  ++FRAMES;

}

setInterval(redraw, 1500 / FPS);

and some html:

<canvas id="canvas"></canvas>

<div id="points"></div>
<p id="coor"></p>
<select id="type">
  <option value="line">line</option>
  <option value="quadratic">quadratic</option>
  <option value="bezier" selected>bezier</option>
</select>

and some CSS:

@charset "UTF-8";

/* ------------------------------------------------ */

HTML,BODY,OL,UL,LI,DL,DT,DD,P,DIV,SPAN {
  margin:0;
  padding:0;
}

/* ------------------------------------------------ */

BODY {
  margin:10px;
  background:#eee;
  color:#000;
}

#canvas {
  background:#fff;
}

.point {
  position:absolute;
  width:9px;height:9px;
  margin:-4px 0 0 -4px;
  background:rgba(0, 0, 255, 0.5);
  border:rgba(128, 128, 255, 0.8);
  -moz-border-radius:4px;
  -webkit-border-radius:4px;
  border-radius:4px;
}

.limiter{
  border:rgba(128, 1, 1, 0.8);
  background:rgba(255, 1, 1, 0.5);
}

.line .cp1, .line .cp2
{
  display:none;
}

.quadratic .cp2{
  display:none;
}

.quadratic .cp1,
.bezier .cp1,
.bezier .cp2
{
  background:rgba(0, 255, 0, 0.5);
  border:rgba(128, 255, 128, 0.8);
}


Why don't you switch your creation of elements via innerHTML to something like

var el=document.createElement("DIV");
el.style.property="value";
el.addEventListener(myFunction, bubbleFlag);
POINTS.appendChild(el);


POINTS.innerHTML +=

Don't ever do that.

This serialises the entire DOM contents of POINTS into an HTML string, adds a new string, and re-parses the concatenated string into new elements for everything in the POINTS element. As well as being slow, this loses all non-serialisable information from the previous content of the element, such as form field values, event listeners and JS references.

As in kstrieder's answer, use DOM operations.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜