2015-11-23 2 views
1

Я пытаюсь прикрепить события javascript к элементам svg, используя код, который находится внутри «шаблона модуля». Я очень нуб в javascript, так как я уверен, что это будет видно из кода ниже. Я попытался воссоздать ситуацию, используя гораздо более простую версию кода, который я фактически использую. По иронии судьбы, я на самом деле дальше от того, чтобы заставить его работать с этим примером, но мой мозг борется с попыткой заставить его работать и исследовать в другом месте на этом сайте. Итак, я обращаюсь ко всем умным людям, чтобы узнать, могут ли они помочь. Проблема, с которой я сталкиваюсь (когда я ее заработал!) Заключается в том, что события javascript не являются привязкой к элементам DOM и просто срабатывают при загрузке страницы. Когда я снова запускаю событие (перемещая мышь), я получаю ошибку javascript, вызванную библиотекой D3 «Некопать TypeError: n.apply не является функцией»проблема с javascript событиями с использованием изменения в модуле шаблона

Если кто-то может заглянуть мимо стремительного усилия по воссозданию модулем и получить этот пример для работы - надеюсь, я смогу включить его в свой фактический код (единственная реальная разница между примером и реальным кодом заключается в том, что существует куча модулей «расширитель», а не все, что находится в одном).

С наилучшими пожеланиями

<!DOCTYPE html> 

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta charset="utf-8" /> 
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
</head> 
<body> 
    <div id="box1"></div> 
    <div id="box2"></div> 

    <script> 

     function mouseOver(i) { 
      return this.targets[i].select("#" + this.targets[i].container).select("circle").attr("fill", "blue"); 
     } 

     function mouseOut(i) { 
      return this.targets[i].select("#" + this.targets[i].container).select("circle").attr("fill", "green"); 
     } 

     var example = (function() { 

      return { 

       addRect: function addRect(container) { 
        this.box = d3.select("#" + container).append("svg"); 

        this.rect = this.box.append("rect") 
         .attr({ 
          "fill": "red", 
          "width": 50, 
          "height": 50, 
         }); 

       }, 

       addCircle: function addControl(targets) { 
        this.targets = targets 

        for (target in this.targets) { 
         tt = this.targets[target] 

         tt.circle = tt.box.append("circle") 
          .attr({ 
           "fill": "green", 
           "cx": -10, 
           "cy":-10, 
           "r": 10, 
           "transform": "translate(30,30)" 
          }) 
        }; 
       }, 

       addControl: function addControl(targets) { 
        this.targets = targets 

        for (target in this.targets) { 
         tt = this.targets[target] 

         tt.control = tt.box.append("rect") 
          .attr({ 
           "fill": "none", 
           "width": 50, 
           "height": 50, 
          }) 
          .on("mouseover", mouseOver(target)) 
          .on("mouseout", mouseOut(target)) 
        }; 

       }, 

      }; 
     })(); 


     var first = new example.addRect("box1"); 
     var second = new example.addRect("box2"); 

     var circs = new example.addCircle([first, second]); 
     var controls = new example.addControl([first, second]); 


    </script> 
</body> 
</html> 

ответ

1

задачи1: Событие увольняют на странице загрузки

Причина:

Вы делаете

.on("mouseover", mouseOver(target)) //this is wrong the second parameter should have been a function. 

что-то вроде этого

.on("mouseover", function(){mouseOver(target)}) 

Задача 2:

tt.control = tt.box.append("rect") 
          .attr({ 
           "fill": "none",//this should not be none else mouse over will not work as you expect 
           "width": 50, 
           "height": 50, 
          }) 
          .on("mouseover", mouseOver(target)) 
          .on("mouseout", mouseOut(target)) 

Это должно быть сделано с непрозрачностью 0, так что его не visble

for (target in this.targets) { 
      tt = this.targets[target] 
      tt.control = tt.box.append("rect") 
       .attr({ 
       "fill": "blue", 
       "width": 50, 
       "height": 50, 
       "opacity": 0 
       }) 

Задача 3:

Вы можете установить параметр DOM вместо передачи его в функцию. Что-то вроде этого

for (target in this.targets) { 
    tt = this.targets[target] 
    tt.control = tt.box.append("rect") 
     .attr({ 
     "fill": "blue", 
     "width": 50, 
     "height": 50, 
     "opacity": 0 
     }) 

     .on("mouseover", function() { 
     mouseOver(tt) 
     }) 
     .on("mouseout", function() { 
     mouseOut(tt) 
     }); 
     tt.control.node().dataset = tt;//binding the data to teh dom 
    }; 

И в случае мыши получить связанный объект, как это:

function mouseOver(target) { 
     //gettting the data from the dom 
     event.target.dataset.circle.attr("fill", "blue"); 
    } 

    function mouseOut(target) { 
     event.target.dataset.circle.attr("fill", "green"); 
    } 

Рабочего код here

Надеется, что это помогает!

+1

Работал безупречно! Большое спасибо. Я не использую «проблему» из «Задачи 2», но проблема 1 должна была быть очевидной, и я даже не представлял, что вы можете привязываться к DOM, как это: мне нужно будет прочитать об этом:) – cb1210