更改 hide/show canvas 上的按钮属性

Change button attribute on hide/show canvas

在学习的同时,我不断回顾我所做的事情以正确理解它,进行更改和改进。目前,我正在检查我的 hide/show 函数。

我有 3 个按钮,它们控制各自 canvases 的可见性。 我的代码看起来像这样:

    function toggleRedDot(){
        document.getElementById('btnRed').click(); {
            if(canvas.style.visibility=='hidden'){
                canvas.style.visibility='visible';
                btnRed.style.color='Red';
            }else{
                canvas.style.visibility='hidden';
                btnRed.style.color='Black';
            }
        }
    };

除了按钮颜色外,绿色和蓝色切换功能完全相同。我的项目实际上有 7 个按钮和 canvases。我正在尝试将所有这些功能放入 1,这就是我现在拥有的:

    function toggle_visibility(id) 
    {
        var ele = document.getElementById(id);
        if (ele.style.visibility == 'hidden')
        {
            ele.style.visibility = 'visible';
        }
        else 
        {
            ele.style.visibility = 'hidden';                
        }
    }

我一直想不通现在如何更改相应的按钮颜色属性。这个想法是当 canvas 可见时按钮看起来 'on' 并且当 'off'.

时颜色恢复为黑色

我还需要 javascript 中的答案,因为这就是我正在学习的内容。 我也希望对我的 drawDots 函数做类似的事情,因为它们在 class 和位置上也不同。谢谢。

我做了一个片段:

  var canvas = document.getElementById('redDot');
  var ctxR = canvas.getContext('2d');
  var canvas1 = document.getElementById('greenDot');
  var ctxG = canvas1.getContext('2d');
  var canvas2 = document.getElementById('blueDot');
  var ctxB = canvas2.getContext('2d');

  var cw = canvas.width;
  var ch = canvas.height;

  drawDots();

  function toggle_visibility(id) {
    var ele = document.getElementById(id);
    if (ele.style.visibility == 'hidden') {
      ele.style.visibility = 'visible';
    } else {
      ele.style.visibility = 'hidden';
    }
  }

  function drawDots() {

    //   Red Dot
    ctxR.clearRect(0, 0, cw, ch);
    ctxR.save();
    ctxR.translate(cw / 2, ch / 2);
    ctxR.beginPath();
    ctxR.arc(-50, 0, 10, 0, 2 * Math.PI);
    ctxR.closePath();
    ctxR.fillStyle = 'Red';
    ctxR.fill();
    ctxR.restore();

    //   Green Dot
    ctxG.clearRect(0, 0, cw, ch);
    ctxG.save();
    ctxG.translate(cw / 2, ch / 2);
    ctxG.beginPath();
    ctxG.arc(0, 0, 10, 0, 2 * Math.PI);
    ctxG.closePath();
    ctxG.fillStyle = 'Green';
    ctxG.fill();
    ctxG.restore();

    //   Blue Dot
    ctxB.clearRect(0, 0, cw, ch);
    ctxB.save();
    ctxB.translate(cw / 2, ch / 2);
    ctxB.beginPath();
    ctxB.arc(50, 0, 10, 0, 2 * Math.PI);
    ctxB.closePath();
    ctxB.fillStyle = 'Blue';
    ctxB.fill();
    ctxB.restore();
  };
#wrapper {
  position: relative;
}
canvas {
  position: absolute;
  border: 1px solid red;
}
.red {
  color: Red;
}
.green {
  color: Green;
}
.blue {
  color: Blue;
}
<div id="btnWrapper">
  <button id="btnRed" class="red" title="Toggle Red Dot" onclick="toggle_visibility('redDot')">&#9737;</button>
  <button id="btnGreen" class="green" title="Toggle Green Dot" onclick="toggle_visibility('greenDot')">&#9737;</button>
  <button id="btnBlue" class="blue" title="Toggle Blue Dot" onclick="toggle_visibility('blueDot')">&#9737;</button>
</div>
<div id="wrapper">
  <canvas id="redDot" width="200" height="100"></canvas>
  <canvas id="greenDot" width="200" height="100"></canvas>
  <canvas id="blueDot" width="200" height="100"></canvas>
</div>

有多种方法可以解决这个问题。我选择的方式只是将按钮的 ID 与 canvas 的 ID 一起传递给 toggle_visibility。我还添加了一个小对象,以便可以通过按钮 ID 查找按钮的颜色。

以后要考虑的事情:

  • 因为DOMreads/writes有点贵,考虑把DOM读一次,把元素存到JS端
  • 考虑使用 JS 中的 addEventListener 而不是 HTML 中的 onclick
    • 您的标记会更清晰
    • 您不必传递 btnRedredDot 之类的参数,因为事件侦听器接收到的事件知道哪个元素触发了事件
  • 与其直接在 JS 中操作 visibility/color,不如使用 CSS class(或 classes)来执行您想要的操作,只需更改 class.

祝你好运! :)

var canvas = document.getElementById('redDot');
var ctxR = canvas.getContext('2d');
var canvas1 = document.getElementById('greenDot');
var ctxG = canvas1.getContext('2d');
var canvas2 = document.getElementById('blueDot');
var ctxB = canvas2.getContext('2d');

var cw = canvas.width;
var ch = canvas.height;

drawDots();

var buttonIdToColor = {
  btnRed:   'red',
  btnGreen: 'green',
  btnBlue:  'blue'
};

function toggle_visibility(buttonId, dotId) {
  var button = document.getElementById(buttonId)
  var dot    = document.getElementById(dotId);

  if (dot.style.visibility == 'hidden') {
    dot.style.visibility = 'visible';
    button.style.color   = buttonIdToColor[buttonId];
  } else {
    dot.style.visibility = 'hidden';
    button.style.color   = 'black';
  }
}

function drawDots() {

  //      Red Dot
  ctxR.clearRect(0, 0, cw, ch);
  ctxR.save();
  ctxR.translate(cw / 2, ch / 2);
  ctxR.beginPath();
  ctxR.arc(-50, 0, 10, 0, 2 * Math.PI);
  ctxR.closePath();
  ctxR.fillStyle = 'Red';
  ctxR.fill();
  ctxR.restore();

  //      Green Dot
  ctxG.clearRect(0, 0, cw, ch);
  ctxG.save();
  ctxG.translate(cw / 2, ch / 2);
  ctxG.beginPath();
  ctxG.arc(0, 0, 10, 0, 2 * Math.PI);
  ctxG.closePath();
  ctxG.fillStyle = 'Green';
  ctxG.fill();
  ctxG.restore();

  //      Blue Dot
  ctxB.clearRect(0, 0, cw, ch);
  ctxB.save();
  ctxB.translate(cw / 2, ch / 2);
  ctxB.beginPath();
  ctxB.arc(50, 0, 10, 0, 2 * Math.PI);
  ctxB.closePath();
  ctxB.fillStyle = 'Blue';
  ctxB.fill();
  ctxB.restore();
};
#wrapper {
  position: relative;
}
canvas {
  position: absolute;
  border: 1px solid red;
}
.red {
  color: Red;
}
.green {
  color: Green;
}
.blue {
  color: Blue;
}
<div id="btnWrapper">
  <button id="btnRed" class="red" title="Toggle Red Dot" onclick="toggle_visibility('btnRed', 'redDot')">&#9737;</button>
  <button id="btnGreen" class="green" title="Toggle Green Dot" onclick="toggle_visibility('btnGreen', 'greenDot')">&#9737;</button>
  <button id="btnBlue" class="blue" title="Toggle Blue Dot" onclick="toggle_visibility('btnBlue', 'blueDot')">&#9737;</button>
</div>
<div id="wrapper">
  <canvas id="redDot" width="200" height="100"></canvas>
  <canvas id="greenDot" width="200" height="100"></canvas>
  <canvas id="blueDot" width="200" height="100"></canvas>
</div>

正如您所说,有超过 3 种颜色,我已经编写了一个示例来简化乘法按钮的创建。

按钮和 canvases 由它们的颜色唯一标识,因此我使用颜色查询 DOM 的引用并使用函数闭包(forEach 回调函数)保存引用需要的时候。

我实际上也会在该函数内创建按钮和 canvas,但您可能希望在 html 中创建它,因此在添加更多按钮时仍然需要创建如此乏味的标记。

我没有操纵元素样式,而是添加了 DOM classes,.black 用于按钮,.hide.show 用于canvas。所以所需要的只是设置元素的 class 名称而不是它们的样式。如果您有一组复杂的样式可以在它们之间切换,这将使它变得更容易。

"Red,Green,Blue".split(",").forEach((col,i)=>{
    var col_l = col.toLowerCase();
    var ctx = document.getElementById(col_l+ 'Dot').getContext('2d');
    var btn = document.getElementById("btn"+col);
    btn.title ="Toggle "+col +" Dot" ;
    btn.className = col_l ;
    ctx.canvas.className = "show";
    var cw = ctx.canvas.width;
    var ch = ctx.canvas.height;
    ctx.clearRect(0, 0, cw, ch);
    ctx.fillStyle = col;
    ctx.beginPath();
    ctx.arc(cw/2 -50 + i * 50, ch/2, 10, 0, 2 * Math.PI);
    ctx.fill();
    function toggle(){  // this function has closure over col_l ,ctx, and btn
        if (ctx.canvas.className == 'hide') {
           ctx.canvas.className = "show";
           btn.className = col_l ;
        }else{
           ctx.canvas.className = "hide";
           btn.className = "black";
        }
    }        
    btn.addEventListener("click",toggle);
});
#wrapper {
  position: relative;
}
canvas {
  position: absolute;
  border: 1px solid red;
}
 /* for canvas hide and show */
.hide {
    visibility : hidden;
}
.show {
    visibility : visible;
}
.red {
  color: Red;
}
.green {
  color: Green;
}
.blue {
  color: Blue;
}
.black {  /* "black" colour button */
  color: Black;
}
<!-- removed most of the stuff that is better added in code. -->
<div id="btnWrapper">  
  <button id="btnRed">&#9737;</button> 
  <button id="btnGreen">&#9737;</button>
  <button id="btnBlue">&#9737;</button>
</div>
<div id="wrapper">
  <canvas id="redDot" width="200" height="100"></canvas>
  <canvas id="greenDot" width="200" height="100"></canvas>
  <canvas id="blueDot" width="200" height="100"></canvas>
</div>