所以我有画布和路径:
var paper1 = Raphael(10, 50, 960, 560);
var mapShape1 = paper1.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z");
var mapShape2 = paper1.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z");
var mapShape3 = paper1.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z");
我按照这样的方式设置它们:(我相信这可以改进,有没有办法一次完成所有路径?)
function style1(shape){
shape.attr({
"fill": "#33CCFF",
"stroke": "000000",
"stroke-width": "5"
});
}
style1(mapShape1);
style1(mapShape2);
style1(mapShape3);
但我的问题是如何在所有路径上使用单个悬停功能,我有这个:
mapShape1.hover(
function(){
this.animate({
"fill": "#FF3300"
}, 500);
},
function(){
this.animate({
"fill": "#33CCFF"
}, 500)
}
);
但它一次只适用于一种形状,我想做
$(mapShape1, mapShape2, mapShape3).hover(...
但这不起作用。我错过了什么?
答案 0 :(得分:12)
正如lib3d所说,你应该使用Set。但是,不是使用forEach
循环设置内容并应用属性/功能,而是可以在集合本身上添加共享属性/功能,将其应用于集合的内容。稍后将详细介绍如何创建集合。
有两种方法可以创建一个集合并向其添加元素:显式和隐式。
这意味着您自己管理集合,并自行添加元素
var paper, shapeA, shapeB, shapeC, elementSet;
paper = Raphael(10, 50, 960, 560);
elementSet = paper.set();
shapeA = paper.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z");
shapeB = paper.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z");
shapeC = paper.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z");
// now add A and C to the set, as well as a rectangle
elementSet.push(
shapeA,
shapeC,
paper.rect(10, 10, 10, 10, 2)
);
通过这种方式,您可以完全控制进入集合的内容以及不进入集合的内容。
您还可以在绘制元素时标记起点和终点。在开始和终点之间绘制的任何元素都将添加到集合中。
var paper, shapA, shapeB, shapeC, elementSet;
paper = Raphael(10, 50, 960, 560);
paper.setStart();
shapeA = paper.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z");
shapeB = paper.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z");
shapeC = paper.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z");
paper.rect(10, 10, 10, 10, 2);
elementSet = paper.setFinish();
变量elementSet现在包含形状A,B和C以及矩形。
我个人建议总是使用显式方法。通过这种方式,您可以100%控制进入您设置的内容和不进入的内容。另外,我发现setStart()和setFinish()要向后命名,我们用“set”“开始”,我们不是“设置”“开始”。如果你现在意图这可能是显而易见的,但这正是模糊命名的危险 - 下一个开发者可能不知道并假设不同的东西。
对于我们创建的应用程序,我们必须绘制,删除,更新和重新定位复杂的元素组。为了实现这一目标,我们大量使用了套装。请注意,集合允许您在集合中的每个元素上应用属性,集合还允许您将其用作DTO。
例如以下作品:
var elementSet = paper.set();
elementSet.push(elemA, elemB, elemC);
elementSet.myApp.someDTO = {
property: value,
something: else
};
为了一致性和清晰度,我倾向于使用myApp
作为命名空间。
它的美妙之处在于即使someDTO包含Raphael元素,您在该集合上应用的任何内容都不会应用于DTO中的元素。这使得它可以在您需要时传递上下文,坐标等。
现在回到使用集合的好处。让我们在这里查看您的用例: 您想要应用属性并将鼠标悬停在任意数量的路径上。
如果我们在上面的显式示例中创建一个集合,我们最终会得到以下结果:
var paper, elementSet;
paper = Raphael(10, 50, 960, 560);
elementSet = paper.set();
elementSet.push(
paper.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z"),
paper.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z"),
paper.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z"),
);
现在在集合上应用样式:
elementSet.attr({
fill: '#33CCFF',
stroke: '#000000',
'stroke-width': 5
});
然后添加悬停:
elementSet.hover(
function(){
this.animate({
"fill": "#FF3300"
}, 500);
},
function(){
this.animate({
"fill": "#33CCFF"
}, 500)
}
);
设置也支持链接,如元素所示:
elementSet.push(
/* elements */
).attr({
/* attributes */
}).hover(
/* hover fn's
);
要查看最终结果,请a fiddle here
如果您想将onhover突出显示应用于所有元素,您可以再次应用该集上的属性:
onMouseOver: function () {
elementSet.animate({
fill: '#FF3300'
}, 500);
};
onMouseOut: function () {
elementSet.animate({
fill: '#33CCFF'
}, 500);
};
elementSet.hover(onMouseOver, onMouseOut);
可以找到here
的小提琴为了能够通过jQuery绑定悬停功能,必须访问元素的nodes。元素本身不是DOM节点,而是Raphael对象。通过使用element.node
,可以在该节点上使用jquery来添加行为。我个人的经验是,它的工作正常,但你永远不想通过jquery修改节点,因为这可能会导致真正的意外行为。
Raphael提供了您需要的所有功能,不需要使用jquery。
答案 1 :(得分:1)
为什么不给你的形状一个类,并让jquery选择类?
您可以执行以下操作:
function style1(shape){
shape.attr({
"fill": "#33CCFF",
"stroke": "000000",
"stroke-width": "5",
"class": '.js-path-hover'
});
}
style1(mapShape1);
style1(mapShape2);
style1(mapShape3);
然后您的悬停事件可以设置如下:
$('.js-path-hover').on('hover', functionNameHere);
如果raphael不允许你在这些svg对象上写一个类,那么你可以使用D3来选择它们并为它们添加一个类。我发现将D3,Raphael和jQuery结合起来非常强大。唯一的问题是你需要跟踪他们的每个限制。
答案 2 :(得分:0)
最简单的方法是将路径推入一个集合中,然后在集合上使用forEach来设置每个路径的样式。
然后,您将以相同的方式绑定悬停处理程序,首先将处理程序作为闭包变量引用。
答案 3 :(得分:0)
$(mapShape1, mapShape2, mapShape3).live('hover', function() { });
使用添加到DOM的动态元素,Live应该可以更好地工作 hover不适用于之后创建的元素,'on'仅适用于创建的dom elemetns,并且指定了第3个参数。