Проблема присоединения событий JavaScript с использованием вариаций в шаблоне модуля
Я пытаюсь прикрепить события javascript к элементам svg, используя код, который находится внутри "шаблона модуля". Я очень noob в javascript, так как я уверен, это будет видно из кода ниже. Я попытался воссоздать ситуацию, используя гораздо более простую версию кода, который я на самом деле использую. По иронии судьбы, я на самом деле далек от того, чтобы заставить его работать с этим примером, но мой мозг болит от попыток заставить его работать и исследовать другие места на этом сайте. Итак, я обращаюсь ко всем умным людям, чтобы посмотреть, смогут ли они помочь. Проблема, с которой я сталкиваюсь (когда я заставляю ее работать!), Заключается в том, что события javascript не связаны с элементами DOM и просто запускаются при загрузке страницы. Когда я снова запускаю событие (перемещая мышь), я получаю ошибку javascript, вызванную библиотекой D3 "Uncaught TypeError: n.apply не является функцией"
Если кто-то сможет забыть о срочном стремлении воссоздать шаблон модуля и заставить этот пример работать - надеюсь, я смогу включить его в свой реальный код (единственное реальное отличие между примером и реальным кодом состоит в том, что существует множество модулей "расширителя", а не всего, что в одном).
С уважением
<!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, чтобы его не видно
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 the 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");
}
Рабочий код здесь.