最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I select an SVG inside an `object` tag? - Stack Overflow

programmeradmin4浏览0评论

Here's how HTML page's contents look.

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

And here's how script.js looks.

var tooltip = d3.select("body")
    .append("div")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("visibility", "hidden")
    .text("Hello");

var svg=    d3.select("object").select("svg");
svg.selectAll('g')
    .on("mouseover",function(){
        return tooltip.style("visibility","visible");
    })
    .on("mousemove",function(){
        var offset=         20;
        var topPosition=    (event.pageY-offset)+"px";
        var leftPosition=   (event.pageX+offset)+"px";
        return tooltip.style("top",topPosition).style("left",leftPosition);
    })
    .on("mouseout", function(){
        return tooltip.style("visibility","hidden");
    });

When I open my HTML page, I see the SVG element with all the g elements in it. When I mouseover each g element, no tooltip appears. But if I replace object with the svg tag and its contents, the tooltip works. How do I make d3 select an SVG in an object tag?

Here's how HTML page's contents look.

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

And here's how script.js looks.

var tooltip = d3.select("body")
    .append("div")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("visibility", "hidden")
    .text("Hello");

var svg=    d3.select("object").select("svg");
svg.selectAll('g')
    .on("mouseover",function(){
        return tooltip.style("visibility","visible");
    })
    .on("mousemove",function(){
        var offset=         20;
        var topPosition=    (event.pageY-offset)+"px";
        var leftPosition=   (event.pageX+offset)+"px";
        return tooltip.style("top",topPosition).style("left",leftPosition);
    })
    .on("mouseout", function(){
        return tooltip.style("visibility","hidden");
    });

When I open my HTML page, I see the SVG element with all the g elements in it. When I mouseover each g element, no tooltip appears. But if I replace object with the svg tag and its contents, the tooltip works. How do I make d3 select an SVG in an object tag?

Share Improve this question asked Oct 19, 2017 at 21:59 UsernameUsername 3,66311 gold badges70 silver badges120 bronze badges 1
  • 1 Events on <g> element are only works when there is something under the pointer which belong to this <g> element, such as "circle", "rect", "path". – 1Cr18Ni9 Commented Oct 20, 2017 at 0:15
Add a ment  | 

3 Answers 3

Reset to default 8

You need to access the <object> contentDocument in order to access its contained elements.

To do this, you also need to wait until your <object> has loaded its content.

I'm not too much into d3, so it might not be the best d3 way of doing, but at least it works:
(but not in StackSnippet's null origined iframes...)

fetch('https://upload.wikimedia/wikipedia/mons/f/fd/Ghostscript_Tiger.svg')
  .then(r => r.blob())
  .then(b => obj.data = URL.createObjectURL(b));

obj.onload = function() { // wait for the svg has loaded

  var tooltip = d3.select("body")
    .append("div")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("visibility", "hidden")
    .text("Hello");

  var obj = this; // we're in the object's load event handler.
  var svg = d3.select(obj.contentDocument) // get the contentDocument
    .select("svg"); // then get the svg inside
  svg.selectAll('g')
    .on("mouseover", function() {
      return tooltip.style("visibility", "visible");
    })
    .on("mousemove", function() {
      var event = d3.event;
      var offset = 20;
      var topPosition = (event.pageY - offset) + "px";
      var leftPosition = (event.pageX + offset) + "px";
      return tooltip.style("top", topPosition).style("left", leftPosition);
    })
    .on("mouseout", function() {
      return tooltip.style("visibility", "hidden");
    });

};
<script src="https://d3js/d3.v4.min.js"></script>
<object id="obj" type="image/svg+xml"></object>

Fiddle

I have no experience with d3 but this might help. You need to wait untill your window is fully loaded.

// 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");
};

Just a short summery which methods work and which won't:

  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);
};

https://jsfiddle/hirschferkel/0wu3z1st/11/

发布评论

评论列表(0)

  1. 暂无评论