javascript 使用 Raphaeljs 的 rect 的 Onclick 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6787057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Onclick event for rect using Raphaeljs
提问by kavita
I am trying to draw a simple Rectangle with some text on it. Since a shape cannot have text on it, I am creating a set with the same coordinates for the text and the rect objects. I need to change something on onclick event. Hence, I have used the obj.node.onclick = statement and written a handler. My problem is that if the text object is used for onclick the event handler gets called only if i click on the text. If I use the rect for onclick I must click on the border area only. My requirement is that the click can come on the entire area of the shape along with the text in it.
我正在尝试绘制一个简单的矩形,上面有一些文字。由于形状上不能有文本,我正在为文本和矩形对象创建一个具有相同坐标的集合。我需要对 onclick 事件进行一些更改。因此,我使用了 obj.node.onclick = 语句并编写了一个处理程序。我的问题是,如果文本对象用于 onclick,则仅当我单击文本时才会调用事件处理程序。如果我将 rect 用于 onclick,我必须只单击边框区域。我的要求是点击可以出现在形状的整个区域以及其中的文本。
var paper = Raphael(10, 10, 320, 200);
var group = paper.set();
var c1 = paper.path("M35 60 L35 90");
var c2 = paper.rect(10, 10, 50, 50,10);
group.push(c2);
group.push(paper.text(35, 35, "Hello"));
c2.attr("fill", "blue");
c2.node.onclick = function () { c2.attr("fill", "red");};
I have tried to use a div to overlay on the rect and write text on it but no success. I can see the div in firebug but not on the webpage! I have given it style properties for top left width and height as well as stated the position as absolute. But no success.
我曾尝试使用 div 覆盖矩形并在其上写入文本但没有成功。我可以在 firebug 中看到 div,但在网页上看不到!我已经为它提供了左上角宽度和高度的样式属性,并将位置声明为绝对位置。但没有成功。
Please help me with this. Any help is appreciated! Kavita
请帮我解决一下这个。任何帮助表示赞赏!卡维塔
I tried using the frontlayer backlayer solution. I cloned the backlayer and added a click handler to it. I did not use 'this' at all. The event never got fired! Please help me with this! Kavita
我尝试使用frontlayer backlayer 解决方案。我克隆了 backlayer 并为其添加了一个点击处理程序。我根本没有使用“这个”。该事件从未被解雇!请在这件事上给予我帮助!卡维塔
回答by Arthur Clemens
Create a set for all elements in the button. Then add a click (or mouseup) handler to the group. Note that rects must have a fill, otherwise they don't get mouse events. For a transparent button use opacity 0.
为按钮中的所有元素创建一个集合。然后向该组添加一个单击(或鼠标向上)处理程序。请注意,矩形必须有填充,否则它们不会获得鼠标事件。对于透明按钮,使用不透明度 0。
var paper = Raphael(10, 10, 320, 200);
var group = paper.set();
var COLOR_NORMAL = 'blue';
var COLOR_HOVER = 'red';
var background = paper.rect(10, 10, 50, 50,10).attr({
fill: COLOR_NORMAL
});
var label = paper.text(35, 35, "Hello");
group.push(background);
group.push(label);
group.attr({
cursor: 'pointer',
}).mouseover(function(e) {
background.attr('fill', COLOR_HOVER);
}).mouseout(function(e) {
background.attr('fill', COLOR_NORMAL);
}).mouseup(function(e) {
alert("clicked");
});
回答by JFiedler
Here are two ways to do this. In both of them, I'm just adding an onclick for the text. In other words, have the same onclick for the rectangle and for the text.
这里有两种方法可以做到这一点。在他们两个中,我只是为文本添加一个 onclick 。换句话说,对于矩形和文本具有相同的 onclick。
1) Just add this line at the end
1)只需在最后添加这一行
group[group.length - 1].node.onclick = function () { c2.attr("fill", "red");};
2) Or, you could create another variable c3, like c2, and attach the onclick the same way. Here's how all of your code would look.
2) 或者,您可以创建另一个变量 c3,如 c2,并以相同的方式附加 onclick。以下是所有代码的外观。
var paper = Raphael(10, 10, 320, 200);
var group = paper.set();
var c1 = paper.path("M35 60 L35 90");
var c2 = paper.rect(10, 10, 50, 50,10);
var c3 = paper.text(35, 35, "Hello").attr({"font-size":36});
group.push(c2);
group.push(c3);
c2.attr("fill", "blue");
c2.node.onclick = function () { c2.attr("fill", "red");};
c3.node.onclick = function () { c2.attr("fill", "red");};
I made the text really large here so you could be sure you're clicking on the text and not the rectangle.
我在此处将文本设置得非常大,因此您可以确定单击的是文本而不是矩形。
回答by Chasbeen
It's nice to actually provide a 3 layer object because you can colour the back-layer how you like. The front layer is the same shape as your back layer but it has an opacity of zero so that you can see the text on the middle layer. I also don't like to use node for handling events but the natively available Raphael event handling mechanism. The below example is taken from one of the examples on my website, I have cut it down even further so it's more readily understood. Also note it is a button made up of a front and back layer circle with a text sandwiched between the two layers. They could just as easily be rectangles/rounded rectangles. The functionality includes the colours inverting on mouseover/mouseout...
实际上提供一个 3 层对象很好,因为您可以根据自己的喜好为后层着色。前层与后层形状相同,但不透明度为零,因此您可以看到中间层上的文本。我也不喜欢使用 node 来处理事件,而是使用本机可用的 Raphael 事件处理机制。下面的例子取自我网站上的一个例子,我已经把它进一步删减了,这样更容易理解。另请注意,它是一个由前后层圆圈组成的按钮,两层之间夹有文本。它们可以很容易地成为矩形/圆角矩形。该功能包括在鼠标悬停/鼠标移开时反转颜色...
button = function (paper, xpos, ypos, r, labeltext)
{
this.backLayer = paper.circle(xpos, ypos, r).attr({ fill: "#FFFF00", 'fill-opacity': 0 , stroke: "#FF0000",'stroke-width':5, 'stroke-opacity':0});
/*The text automatically centres itself as this is the default text positioning for Raphael text*/
this.label = paper.text(xpos, ypos, labeltext).attr({fill:'#ff0000', 'font-size':18});
/*Now we make a copy for the front layer and we also make the back layer opaque. So that you can see it's yellow fill*/
this.frontLayer = this.backLayer.clone();
this.backLayer.attr({'fill-opacity': 1, 'stroke-opacity':1});
/*Now make the back layer and the text referencable for the mouseover, mouseout and click event of the front layer*/
this.frontLayer.backLayer= this.backLayer;
this.frontLayer.label = this.label;
/*Add a preferred cursor by referencing the underlying DOM object of the frontLayer*/
this.frontLayer.node.style.cursor = 'pointer';
/*Now you can interact with the lower layers behind the invisible covering layer ( frontLayer ) in it's event methods*/
this.frontLayer.mouseover(
function (e) {
this.backLayer.animate({ fill: "#FF0000", stroke: "#FFFF00" }, 1000);
this.label.animate({ fill: "#FFFF00" }, 1000);
}
);
this.frontLayer.mouseout(
function (e) {
this.backLayer.animate({ fill: "#FFFF00", stroke: "#FF0000" }, 1000);
this.label.animate({ fill: "#FF0000" }, 1000);
}
);
this.frontLayer.click(
function (e) {
alert("Creating loads of custom buttons is easy\n\nYou made this one with the following specification:\n"+
"Button Text : "+this.label.attr("text")+"\n"+
"Button Centre @ X: "+this.backLayer.attr("cx")+"\n"+
"Button Centre @ Y: "+this.backLayer.attr("cy")+"\n"+
"Button Radius : "+this.backLayer.attr("r"));
}
);
}
/*Create the button*/
rappyButton = new button(paper, 250, 200, 75, "Raphael");
Hope that helped.
希望有所帮助。
回答by chris5marsh
You've used the set
property of Raphael (http://raphaeljs.com/reference.html#set). Have you tried adding the onclick
to that?
您已经使用了set
Raphael (http://raphaeljs.com/reference.html#set)的属性。你有没有试过添加onclick
?
group.click(function(event) {
c2.attr({fill: "red"});
});
回答by Manuel Leuenberger
What about using the same handler for the text and the rect, using a fill-opacity
of 0?
使用 a fill-opacity
of 0对文本和矩形使用相同的处理程序怎么样?
回答by Stuart Hallows
Consider just ignoring pointer events on the text nodes and letting them pass through to the parent rect.
考虑忽略文本节点上的指针事件并让它们传递到父矩形。
svg text {
pointer-events: none;
}
回答by roberthuttinger
onmousedown worked for me in IE 7,8, and 9
onmousedown 在 IE 7、8 和 9 中对我来说有效
st[0].onclick = function () {
myFunc(dataObj);
st.toFront();
R.safari();
};
st[0].onmousedown = function () {
myFunc(dataObj);
st.toFront();
R.safari();
};
I tried some other methods as well, abstracting the function to a variable but it didnt work. In my case I cannot add a rectangle to the display and have people click on this, it was a poor solution for several reasons.
我也尝试了其他一些方法,将函数抽象为一个变量,但没有奏效。在我的情况下,我无法向显示中添加矩形并让人们点击它,由于多种原因,这是一个糟糕的解决方案。
Hope this helps!
希望这可以帮助!