75t*_*one 2 javascript jquery events svg
在页面上,我有一张美国和加拿大的SVG地图,以及省和州的HTML列表.悬停在任何省份上,无论是列表中的名称还是地图上的描述,都应该使名称和描述变为不同的颜色.所有名称和路径都已经有了逻辑ID /类.
这是我的代码的小提琴.(这是一个可怕的程序混乱,所以请原谅我.)
jQuery的事件函数不适用于SVG,虽然我知道有一个jQuery插件可能会有所帮助,但我认为这将是一个很好的机会来使用比我习惯的更大比例的vanilla Javascript.
代码中最相关的部分是makeMapInteractiveJavascript第46到69行的函数:
function makeMapInteractive(provinces) {
for(var province in provinces) { // Iterate over every state/province code
var $HTMLtargets = $('ul.provinces li.' + province);
var $SVGtargets = $('path#{0}, g#{0} path'.format(province));
var $allTargets = $HTMLtargets.add($SVGtargets);
// I tried it first with $().each(); when that didn't work,
// I commented it out and tried without it. Neither one works.
/* $allTargets.each(function() {
this.addEventListener('mouseover', function(e) {
console.log(e);
$HTMLtargets.css('color', '#990000');
$SVGtargets.attr('fill', '#990000');
}, false)
}); */
for(var i = 0; i < $allTargets.length; i++) {
$allTargets.get(i).addEventListener('mouseover', function(e) {
$HTMLtargets.css('color', '#990000');
$SVGtargets.attr('fill', '#990000');
}, false);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我试图告诉它要做的是为每个元素添加一个鼠标悬停监听器,触发对该元素所涉及的所有元素的更改.
实际发生的事情是,将鼠标悬停在整个页面上的任何内容中会触发最后一个添加的事件监听器,即怀俄明州的事件监听器.就像我更改$allTargets变量一样,它将所有先前添加的侦听器更改为其新值中包含的元素.但我无法看到这是怎么回事,因为我将事件监听器应用于该变量内的DOM元素,而不是jQuery对象本身.
有人能解释到底发生了什么吗?我知道我在这里使用jQuery,但是我想要使用的答案不超过我已经使用过的; 这是我需要增加的香草Javascript技能.
问题是你$HTMLtargets和$SVGtargets变量不是你希望它们在你的事件处理程序回调中,因为当事件触发(稍后某个时间)时,你的外部for循环已经完成,因此这两个变量都在它们的结束值上.
您将需要一个闭包来为每个事件处理程序单独捕获这些变量.这是一种方法:
// create closure to freeze the target variables
(function(hTargets, sTargets) {
for(var i = 0; i < $allTargets.length; i++) {
$allTargets.get(i).addEventListener('mouseover', function(e) {
hTargets.css('color', '#990000');
sTargets.attr('fill', '#990000');
}, false);
}
})($HTMLtargets, $SVGtargets);
Run Code Online (Sandbox Code Playgroud)
仅供参考,我更改了闭包内部变量的名称,以便更明显地发生了什么.不需要将参数的名称更改为立即执行的函数表达式,因为它们将覆盖先前定义的函数表达式,但我认为如果更改名称会更清楚.
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |