使用 svg 在外部多边形事件上触发内部多边形事件
trigger events on inner polygons on outer polygon event with svg
我有一个 svg,其中有多个片段由 sectors.The 个扇区组成,点击后切换 class 并更改颜色。我需要内部扇区在外部扇区的点击事件中点亮
Here 是 fiddle link 相同。
我尝试提供 classes,例如 herbalLvl1、herbalLvl2、herbalLvl3,这样我可以在点击 HerbalLvl2 或 HerbalLvl3 时触发 herbalLvl1 上的点击事件。但是这些扇区已经有一个 class,我需要这些扇区只有一个 class 来切换动态创建的 class,如下所示:
var myclass=$(this).attr("class");
var classarray=myclass.split(" ");
var currentClass=classarray[0]; var thisClass=classarray[0];
var res=currentClass.split("clicked");
if(res.length==1)
{
$(this).removeClass(thisClass);
$(this).addClass(currentClass+'clicked');
console.log($(this).attr("class"));
}
else
if(res.length==2)
{
console.log('2');
$(this).removeClass(thisClass);
$(this).addClass(res[0]);
console.log($(this).attr("class"));
}
如果我向多边形添加另一个 class,那么 $(this).addClass(res[0]);
将 return 不同的值,因为 class 以以下方式被删除:
第 Load:herbal 页 herbalLvl1
点击select:草本Lvl1 草本点击
点击取消select: herbalclicked herbalLvl1clicked
n 依此类推,因为新添加的 classes 被附加到最后。
除了应用多个 classes 之外,有没有办法在 select 外环上实现 selecting 内环。
编辑 (或第二个答案!)
由于去除select多边形的能力显然是必要的...
您会注意到 deselection 比 selection 稍微复杂一些。
为什么?
因为 select 也 select 就是 "parents".
但是 deselect may 不是 deselect 它的 parents 因为 maybe 另一个兄弟是 select编辑...
所以必须检查那个案例!
我在代码中加入了尽可能多的注释。
;)
你的鼠标会喜欢 This Fiddle。
$("polygon").click(function() {
var myclass = $(this).attr("class");
var classarray = myclass.split(" ");
var currentClass = classarray[0];
// If the polygon clicked (the trigger) already has the "clicked" class ( Not a "UNIQUE" , see below for those )
if ($(this).hasClass(currentClass + 'clicked') && $(this).attr("data-sub") != "UNIQUE") {
console.log("already selected");
// Remove the "clicked" class.
$(this).removeClass(currentClass + 'clicked');
// Get the class and branch.
var thisSub = $(this).attr("data-sub");
var thisLevel = $(this).attr("data-level");
// Filter elements based on level and sub branch.
var foundAnother = false;
var foundEl = [];
// Filter function for each element of the current class.
$("." + currentClass).filter(function() {
// If the element has the same sub AND the same level as the current class.
if (($(this).attr("data-sub") == thisSub) && ($(this).attr("data-level") == thisLevel)) {
// If this element has the "clicked" class ( So another element that has same sub and level AND that was aleready clicked ).
if ($(this).hasClass(currentClass + 'clicked')) {
console.log("found another");
foundAnother = true;
// May be many elements... So push it to an array.
foundEl.push($(this));
}
}
// Keeping anyway all elements of the same sub in this filter. The found elements will be re-clicked later.
if ($(this).attr("data-sub") == thisSub) {
return true;
}
// For all element kept in the above, remove the "clicked" class. --- End filter function.
}).removeClass(currentClass + "clicked");
// Another check on each current class -> If there is element still having the "clicked" class except the "UNIQUE", set a flag.
var checkAll = false;
$("." + currentClass).each(function() {
if ($(this).hasClass(currentClass + "clicked") && $(this).attr("data-sub") != "UNIQUE") {
checkAll = true;
}
});
// If flag was'n raised in the above, remove the "clicked" class for ALL elements.
if (!checkAll) {
$("." + currentClass).removeClass(currentClass + "clicked");
}
// If some elements were found having the same sub and level as the trigger.
if (foundAnother) {
console.log(foundEl.length);
// Click them all !! (Kind of a short cut here!)
for (i = 0; i < foundEl.length; i++) {
foundEl[i].click();
}
}
// This else is for "UNIQUE" elements that have "clicked" class. So if a "UNIQUE clicked" element is clicked -> All the ellements having this current class should be unclicked.
} else if ($(this).hasClass(currentClass + 'clicked') && $(this).attr("data-sub") == "UNIQUE") {
console.log("UNIQUE FOUND");
$("." + currentClass).removeClass(currentClass + "clicked");
// Last else. If the trigger was not already clicked before.
} else {
// Add the appropriate "clicked" class.
$(this).addClass(currentClass + 'clicked');
// Markup error check... Since maybe it's the very first click it gets, have to check if it has all the required data atributes.
if (typeof($(this).attr("data-level")) == "undefined") {
console.log("data-level is missing");
return;
}
if (typeof($(this).attr("data-sub")) == "undefined") {
console.log("data-sub is missing");
return;
}
// Get the class and branch from this target.
var thisSub = $(this).attr("data-sub");
var thisLevel = $(this).attr("data-level");
// Filter elements based on level and sub branch.
$("." + currentClass).filter(function() {
if ((($(this).attr("data-sub") == thisSub) || ($(this).attr("data-sub") == "UNIQUE")) && ($(this).attr("data-level") < thisLevel)) {
return true;
}
}).addClass(currentClass + "clicked");
}
});
第一个回答 (不包括select)
如果您使用另一个属性而不是 class
来区分 "level" 和 "branch" 会怎么样?
像这样:<polygon class='herbal' data-level="2" data-sub="A"...
所以每个不同的字母 "branches"...
当 "level" 只有一个 "branch" 时,将 data-sub
设置为 "UNIQUE"`。
看看这个updated Fiddle。
代码:
$("polygon").click(function() {
var myclass = $(this).attr("class");
var classarray = myclass.split(" ");
var currentClass = classarray[0];
// Add the appropriate "clicked" class.
$(this).addClass(currentClass + 'clicked');
// Markup error check.
if (typeof($(this).attr("data-level")) == "undefined") {
console.log("data-level is missing");
return;
}
if (typeof($(this).attr("data-sub")) == "undefined") {
console.log("data-sub is missing");
return;
}
// Get the class and branch.
var thisSub = $(this).attr("data-sub");
var thisLevel = $(this).attr("data-level");
// Filter elements based on level and sub branch.
$("." + currentClass).filter(function() {
if ((($(this).attr("data-sub") == thisSub) || ($(this).attr("data-sub") == "UNIQUE")) && ($(this).attr("data-level") < thisLevel)) {
return true;
}
}).addClass(currentClass + "clicked");
});
我有一个 svg,其中有多个片段由 sectors.The 个扇区组成,点击后切换 class 并更改颜色。我需要内部扇区在外部扇区的点击事件中点亮
Here 是 fiddle link 相同。
我尝试提供 classes,例如 herbalLvl1、herbalLvl2、herbalLvl3,这样我可以在点击 HerbalLvl2 或 HerbalLvl3 时触发 herbalLvl1 上的点击事件。但是这些扇区已经有一个 class,我需要这些扇区只有一个 class 来切换动态创建的 class,如下所示:
var myclass=$(this).attr("class");
var classarray=myclass.split(" ");
var currentClass=classarray[0]; var thisClass=classarray[0];
var res=currentClass.split("clicked");
if(res.length==1)
{
$(this).removeClass(thisClass);
$(this).addClass(currentClass+'clicked');
console.log($(this).attr("class"));
}
else
if(res.length==2)
{
console.log('2');
$(this).removeClass(thisClass);
$(this).addClass(res[0]);
console.log($(this).attr("class"));
}
如果我向多边形添加另一个 class,那么 $(this).addClass(res[0]);
将 return 不同的值,因为 class 以以下方式被删除:
第 Load:herbal 页 herbalLvl1
点击select:草本Lvl1 草本点击
点击取消select: herbalclicked herbalLvl1clicked
n 依此类推,因为新添加的 classes 被附加到最后。
除了应用多个 classes 之外,有没有办法在 select 外环上实现 selecting 内环。
编辑 (或第二个答案!)
由于去除select多边形的能力显然是必要的...
您会注意到 deselection 比 selection 稍微复杂一些。
为什么?
因为 select 也 select 就是 "parents".
但是 deselect may 不是 deselect 它的 parents 因为 maybe 另一个兄弟是 select编辑...
所以必须检查那个案例!
我在代码中加入了尽可能多的注释。
;)
你的鼠标会喜欢 This Fiddle。
$("polygon").click(function() {
var myclass = $(this).attr("class");
var classarray = myclass.split(" ");
var currentClass = classarray[0];
// If the polygon clicked (the trigger) already has the "clicked" class ( Not a "UNIQUE" , see below for those )
if ($(this).hasClass(currentClass + 'clicked') && $(this).attr("data-sub") != "UNIQUE") {
console.log("already selected");
// Remove the "clicked" class.
$(this).removeClass(currentClass + 'clicked');
// Get the class and branch.
var thisSub = $(this).attr("data-sub");
var thisLevel = $(this).attr("data-level");
// Filter elements based on level and sub branch.
var foundAnother = false;
var foundEl = [];
// Filter function for each element of the current class.
$("." + currentClass).filter(function() {
// If the element has the same sub AND the same level as the current class.
if (($(this).attr("data-sub") == thisSub) && ($(this).attr("data-level") == thisLevel)) {
// If this element has the "clicked" class ( So another element that has same sub and level AND that was aleready clicked ).
if ($(this).hasClass(currentClass + 'clicked')) {
console.log("found another");
foundAnother = true;
// May be many elements... So push it to an array.
foundEl.push($(this));
}
}
// Keeping anyway all elements of the same sub in this filter. The found elements will be re-clicked later.
if ($(this).attr("data-sub") == thisSub) {
return true;
}
// For all element kept in the above, remove the "clicked" class. --- End filter function.
}).removeClass(currentClass + "clicked");
// Another check on each current class -> If there is element still having the "clicked" class except the "UNIQUE", set a flag.
var checkAll = false;
$("." + currentClass).each(function() {
if ($(this).hasClass(currentClass + "clicked") && $(this).attr("data-sub") != "UNIQUE") {
checkAll = true;
}
});
// If flag was'n raised in the above, remove the "clicked" class for ALL elements.
if (!checkAll) {
$("." + currentClass).removeClass(currentClass + "clicked");
}
// If some elements were found having the same sub and level as the trigger.
if (foundAnother) {
console.log(foundEl.length);
// Click them all !! (Kind of a short cut here!)
for (i = 0; i < foundEl.length; i++) {
foundEl[i].click();
}
}
// This else is for "UNIQUE" elements that have "clicked" class. So if a "UNIQUE clicked" element is clicked -> All the ellements having this current class should be unclicked.
} else if ($(this).hasClass(currentClass + 'clicked') && $(this).attr("data-sub") == "UNIQUE") {
console.log("UNIQUE FOUND");
$("." + currentClass).removeClass(currentClass + "clicked");
// Last else. If the trigger was not already clicked before.
} else {
// Add the appropriate "clicked" class.
$(this).addClass(currentClass + 'clicked');
// Markup error check... Since maybe it's the very first click it gets, have to check if it has all the required data atributes.
if (typeof($(this).attr("data-level")) == "undefined") {
console.log("data-level is missing");
return;
}
if (typeof($(this).attr("data-sub")) == "undefined") {
console.log("data-sub is missing");
return;
}
// Get the class and branch from this target.
var thisSub = $(this).attr("data-sub");
var thisLevel = $(this).attr("data-level");
// Filter elements based on level and sub branch.
$("." + currentClass).filter(function() {
if ((($(this).attr("data-sub") == thisSub) || ($(this).attr("data-sub") == "UNIQUE")) && ($(this).attr("data-level") < thisLevel)) {
return true;
}
}).addClass(currentClass + "clicked");
}
});
第一个回答 (不包括select)
如果您使用另一个属性而不是 class
来区分 "level" 和 "branch" 会怎么样?
像这样:<polygon class='herbal' data-level="2" data-sub="A"...
所以每个不同的字母 "branches"...
当 "level" 只有一个 "branch" 时,将 data-sub
设置为 "UNIQUE"`。
看看这个updated Fiddle。
代码:
$("polygon").click(function() {
var myclass = $(this).attr("class");
var classarray = myclass.split(" ");
var currentClass = classarray[0];
// Add the appropriate "clicked" class.
$(this).addClass(currentClass + 'clicked');
// Markup error check.
if (typeof($(this).attr("data-level")) == "undefined") {
console.log("data-level is missing");
return;
}
if (typeof($(this).attr("data-sub")) == "undefined") {
console.log("data-sub is missing");
return;
}
// Get the class and branch.
var thisSub = $(this).attr("data-sub");
var thisLevel = $(this).attr("data-level");
// Filter elements based on level and sub branch.
$("." + currentClass).filter(function() {
if ((($(this).attr("data-sub") == thisSub) || ($(this).attr("data-sub") == "UNIQUE")) && ($(this).attr("data-level") < thisLevel)) {
return true;
}
}).addClass(currentClass + "clicked");
});