javascript 如何在svg元素中放置复选框?

hsvhsicv  于 2023-01-08  发布在  Java
关注(0)|答案(2)|浏览(161)

假设我想创建一个小的正方形web元素,中间有一个圆圈和一个复选框。勾选复选框会改变圆圈的颜色。我提供了一个工作代码示例如下。我目前面临的问题是,我目前的实现将复选框放置在svg之下,而不是之内

因此我的问题:有没有办法把这个tickbox放在svg元素里面或者上面,并且用宽度和高度的百分比来指定它的位置?(例如,x =宽度/2,y =高度/2)

我希望这将是一个简单的问题,但我似乎找不到解决方案-也许我搜索了错误的关键字。我将感谢任何建议!

<!DOCTYPE html>
<html>

  <head>
    <script src="https://unpkg.com/mathjs/lib/browser/math.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
  </head>
  
  <!-- Create a div where the graph will take place -->
<div id="my_dataviz">
  <svg id="click" xmlns="http://www.w3.org/2000/svg" style="background-color:#cccccc">
      <defs>

      </defs>
  </svg>
</div>

<input type="checkbox" onclick='check()' id='myCheckbox'>

  <body>
    <script>
    
    // ===================================================
    // Set up basic viewport options
    // ===================================================
    
    // Get viewport sizes
    const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
    const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
      
    // Fit in a square window
    var height  = math.min([vw,vh])*0.75; 
    var width   = math.min([vw,vh])*0.75;

        // Create a svg
    var svg = d3.select("#click") // This selects the div
    .attr("width", width) // This defines the canvas' width
    .attr("height", height) // This defines the canvas' height
    
    // Plot a circle
    svg.append("circle")
      .attr("r", height/4)
      .attr("cx", width/2)
      .attr("cy", height/2)
      .attr("fill", "#ff0000")
      .attr("opacity", 0.75)
      .attr("id","circ");

        // Checking the box changes the color
    function check() {
    
        // If the box is ticked, make the circle green
        if (d3.select("#myCheckbox").property("checked")) {
      
        d3.select("#circ")
            .attr("fill", "#00ff00")
      
      // If the box is not ticked, make the circle red
      } else {
      
        d3.select("#circ")
            .attr("fill", "#ff0000")
      
      }
    }

    </script>
  </body>

</html>

编辑:按照HereticMonkey的建议,你建议如下编辑html部分吗?

<!-- Create a div where the graph will take place -->
<div id="my_dataviz" position="relative">
  <svg id="click" xmlns="http://www.w3.org/2000/svg" style="background-color:#cccccc" position="absolute">
      <defs>
      </defs>
  </svg>
      <input type="checkbox" onclick='check()' id='myCheckbox' top="0px"  left="-100px" position="absolute">
</div>
4xrmg8kj

4xrmg8kj1#

  • 沟渠D3
  • 将HTML放入SVG foreignObject

使用xy属性微调定位

  • 使用现代CSS :has选择器根据:checked状态为circle着色

FireFox尚不支持:https://caniuse.com/css-has
因此,添加您自己的JSonclick * inlineventhandler * 来为圆圈着色

配备:has选择器的现代版本

  • 无需JavaScript
<svg viewBox="0 0 200 200" style="height:180px">
  <style>
    svg:has(input:checked) circle {  fill:green  }
    input { zoom: 4 }
  </style>
  <circle cx="50%" cy="50%" r="49%" fill="red" />
  <foreignObject x="30%" y="31%" width="100%" height="100%">
      <input type="checkbox" CHECKED> 
  </foreignObject>
  <circle cx="50%" cy="50%" r="3" fill="black" />
</svg>

经典FireFox版本

  • 现在需要两个CHECKED设置来设置初始:已检查状态
<svg viewBox="0 0 200 200" style="height:180px">
  <style>
    circle[checked] {  fill:green  }
    input { zoom: 4 }
  </style>
  <circle cx="50%" cy="50%" r="49%" fill="red" CHECKED />
  <foreignObject x="30%" y="32%" width="100%" height="100%">
      <input type="checkbox" CHECKED
             onclick="this.closest('svg')
                          .querySelector('circle')
                          .toggleAttribute('checked')"> 
  </foreignObject>
  <circle cx="50%" cy="50%" r="3" fill="black" />
</svg>
x759pob2

x759pob22#

多亏了Heretic Monkey令人敬畏的建议,我已经让它工作起来了!

<!DOCTYPE html>
<html>

  <head>
    <script src="https://unpkg.com/mathjs/lib/browser/math.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    
    <style>
        #my_dataviz { position: relative; } 
        #click { background-color: #ccc; position: absolute; } 
        #myCheckbox { position: absolute; top: 0; left: 0; }
    </style>
    
  </head>
  
    <!-- Create a div where the graph will take place -->
  <div id="my_dataviz" position="relative">
    <g id="group">
    <svg id="click" xmlns="http://www.w3.org/2000/svg" style="background-color:#cccccc" position="absolute">
        <defs>
        </defs>
    </svg>
    <input type="checkbox" onclick='check()' id='myCheckbox' top="0px"  left="-100px" position="relative">
    </g>
  </div>

  <body>

    <script>
    
    // ===================================================
    // Set up basic viewport options
    // ===================================================
    
    // Get viewport sizes
    const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
    const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
      
    // Fit in a square window
    var height  = math.min([vw,vh])*0.75; 
    var width   = math.min([vw,vh])*0.75;

        // Create a svg
    var svg = d3.select("#click") // This selects the div
      .attr("width", width) // This defines the canvas' width
      .attr("height", height) // This defines the canvas' height
    
    // Plot a circle
    svg.append("circle")
      .attr("r", height/4)
      .attr("cx", width/2)
      .attr("cy", height/2)
      .attr("fill", "#ff0000")
      .attr("opacity", 0.75)
      .attr("id","circ");
      
        document.getElementById('myCheckbox').style.top = (width/2).toString()+"px";
    document.getElementById('myCheckbox').style.left = (height/2).toString()+"px";

        // Checking the box changes the color
    function check() {
    
        // If the box is ticked, make the circle green
        if (d3.select("#myCheckbox").property("checked")) {
      
        d3.select("#circ")
            .attr("fill", "#00ff00")
      
      // If the box is not ticked, make the circle red
      } else {
      
        d3.select("#circ")
            .attr("fill", "#ff0000")
      
      }
    }
    
      d3.select("#click")
        .append("input")
        .attr("type", "checkbox")
        .style("position", "absolute")
        .style("top", 100)
        .style("left", 100)

    </script>
  </body>

</html>

相关问题