Javascript 如何在`object`标记中选择SVG?

Javascript 如何在`object`标记中选择SVG?,javascript,d3.js,svg,Javascript,D3.js,Svg,下面是HTML页面内容的外观 <!DOCTYPE html> <html> <head> <script src="https://d3js.org/d3.v4.min.js"></script> </head> <body> <object type="image/svg+xml" data="Map-edited.svg"></object> <sc

下面是HTML页面内容的外观

<!DOCTYPE html>
<html>
<head>
    <script src="https://d3js.org/d3.v4.min.js"></script>   
</head>
<body>
    <object type="image/svg+xml" data="Map-edited.svg"></object>
    <script src="script.js"></script>
</body>
</html>

当我打开HTML页面时,我看到SVG元素中包含所有
g
元素。当我将鼠标悬停在每个
g
元素上时,不会显示任何工具提示。但是如果我用
svg
标记及其内容替换
object
,工具提示就会起作用。如何使d3在
对象
标记中选择SVG?

您需要访问
以访问其包含的元素

为此,您还需要等待
加载其内容

我不太喜欢d3,所以它可能不是最好的d3方式,但至少它是有效的:
(但不在StackSnippet的空源iFrame中…)

fetch('https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg')
.then(r=>r.blob())
。然后(b=>obj.data=URL.createObjectURL(b));
obj.onload=function(){//等待svg加载
变量工具提示=d3。选择(“主体”)
.附加(“div”)
.style(“位置”、“绝对”)
.风格(“z指数”、“10”)
.style(“可见性”、“隐藏”)
.text(“你好”);
var obj=this;//我们在对象的加载事件处理程序中。
var svg=d3.select(obj.contentDocument)//获取contentDocument
.选择(“svg”);//然后将svg放入
svg.selectAll('g'))
.on(“鼠标悬停”,函数(){
返回工具提示样式(“可见性”、“可见”);
})
.on(“mousemove”,function(){
var事件=d3.0事件;
var偏移=20;
变量topPosition=(event.pageY-offset)+“px”;
变量leftPosition=(event.pageX+偏移量)+“px”;
返回工具提示.style(“顶部”,顶部位置).style(“左侧”,左侧位置);
})
.on(“mouseout”,函数(){
返回工具提示样式(“可见性”、“隐藏”);
});
};


简单总结一下哪些方法有效,哪些方法无效:

  d3.select(obj.node().contentDocument).select('svg').selectAll('g') // get the contentDocument
  console.log('node > svg > g => works!',nsvg)

  var obj1 = d3.select('#obj'); // we're in the object's load event handler.
  var ng = d3.select(obj1.node().contentDocument).selectAll('g') // get the contentDocument
  console.log('node > g => works!',ng)

  var obj2 = d3.select('#obj'); // we're in the object's load event handler.
  var svg = d3.select(obj2.contentDocument).select('svg').selectAll('g') // get the contentDocument
  console.log('select svg > g => fails!',svg)

  var obj3 = d3.select('#obj'); // we're in the object's load event handler.
  var g = d3.select(obj3.contentDocument).selectAll('g') // get the contentDocument
  console.log('select g => fails!',g)

  var getElement = document.getElementById('obj').contentDocument
  var gElements = d3.select(getElement).select('svg').selectAll('g')
  console.log("gElements > d3.select svg > g => works!", gElements);

  var svg2 = document.getElementById('obj').contentDocument.getElementsByTagName('g')
  console.log("getElementById => works!", svg2);
};

我没有d3方面的经验,但这可能会有所帮助。 您需要等待,直到您的窗口完全加载

// object of my SVG
<object id="fridge" data={FridgePicture} ></object>

window.onload = function() {
    // Get the fridgeObject by ID
    var fridgeObj = document.getElementById("fridge");
    // Get the SVG document inside the Object tag
    var fridgeDoc = fridgeObj.contentDocument;
    // From here you can get an item you wish e.g:
    var rightDoor = fridgeDoc.getElementById("RightDoor");
};
//我的SVG的对象
window.onload=函数(){
//通过ID获取fridgeObject
var fridgeObj=document.getElementById(“冰箱”);
//在对象标记内获取SVG文档
var fridgeDoc=fridgeObj.contentDocument;
//从这里您可以获得您想要的物品,例如:
var rightDoor=fridgeDoc.getElementById(“rightDoor”);
};

元素上的事件只有在指针下有属于该元素的内容时才起作用,例如“circle”、“rect”、“path”。“D3在这里似乎很无用…”在这一点上,您可以看出,实际上您对D3并没有太多的兴趣:D3选择和DOM元素是不同的。@GerardoFurtado我刚才说的是
D3.select(“…”).node()
,它返回一个DOM元素(我以前在脚本中已经获得了访问权限,原因与此无关)。我希望你的意思是真的而不是事实上的,因为我从来没有假装进入d3,恰恰相反。@GerardoFurtado,我完全改变了这一行,以表明这个调用确实是绝对不需要的。我只是告诉你,
d3.select(whatever)
不返回“whatever”DOM元素,但我很后悔留下了评论。@GerardoFurtado是的,因为我从来没有这样说过。我对d3不太了解,因为可能有一些内置程序我不知道如何访问contentDocument,但我知道d3.select返回了什么,这非常有用。谢谢为了提取SVG及其组件,必须学习的不同函数的数量是疯狂的。所以像这样的小例子真的很有帮助。
// object of my SVG
<object id="fridge" data={FridgePicture} ></object>

window.onload = function() {
    // Get the fridgeObject by ID
    var fridgeObj = document.getElementById("fridge");
    // Get the SVG document inside the Object tag
    var fridgeDoc = fridgeObj.contentDocument;
    // From here you can get an item you wish e.g:
    var rightDoor = fridgeDoc.getElementById("RightDoor");
};