【问题标题】:Adding event listener to a point将事件侦听器添加到某个点
【发布时间】:2011-05-29 14:57:45
【问题描述】:

(see problem in action) 通常我的问题是 - 我可以添加带有 innerHTML 的元素,我可以设置它们的样式,但我不能 addEventListeners 给它们添加样式。有没有人见过这样的问题? (see how it worked before I added html generation)

所以我有这么简单的 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;
         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);

还有一些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>

还有一些 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);
}

【问题讨论】:

  • 该死,一个问题的代码就这么多。

标签: javascript html events dom-events code-generation


【解决方案1】:

你为什么不把你通过innerHTML创建的元素转换成类似的东西

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

【讨论】:

  • @Kabumbus:不要在 HTML 文档上使用setAttribute,它比普通的 HTML DOM 属性更易阅读,而且在 IE 上存在错误。 div.id= ...div.className= ...。在 id 上运行 String() 没有任何作用。
  • 检查您的 /elementIdSring/ 是否真的独一无二 - 这就是它需要的。为什么你仍然需要 ID?当你绑定到创建的元素(通过 eventListener)时,你总是在事件处理程序中拥有 this-context。
【解决方案2】:
POINTS.innerHTML +=

永远不要那样做。

这会将POINTS 的整个DOM 内容序列化为一个HTML 字符串,添加一个新字符串,并将连接的字符串重新解析为POINTS 元素中所有内容的新元素。除了速度慢之外,这还会丢失元素先前内容中的所有不可序列化信息,例如表单字段值、事件侦听器和 JS 引用。

在 kstrieder 的回答中,使用 DOM 操作。

【讨论】:

  • 所以我明白了 - 将尽快尝试 - 问题是为什么我有清晰的 html 和 'innerHTML +='?
猜你喜欢
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多