【问题标题】:Change button attribute on hide/show canvas更改隐藏/显示画布上的按钮属性
【发布时间】:2016-08-25 19:15:11
【问题描述】:

在学习的同时,我不断回顾我为正确理解它所做的工作,做出改变和改进。目前,我正在检查我的隐藏/显示功能。

我有 3 个按钮来控制它们各自画布的可见性。 我的代码确实是这样的:

    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 个按钮和画布。我正在尝试将所有这些功能放入 1 中,这就是我现在所拥有的:

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

我现在无法弄清楚如何更改相应的按钮颜色属性。这个想法是,当画布可见时按钮看起来“打开”,而当“关闭”时颜色恢复为黑色。

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

我做了一个sn-p:

		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>

【问题讨论】:

    标签: javascript html button canvas toggle


    【解决方案1】:

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

    未来需要考虑的事情:

    • 由于 DOM 读取/写入有些昂贵,请考虑读取一次 DOM 并将元素存储在 JS 端
    • 考虑在 JS 中使用 addEventListener 而不是在 HTML 中使用 onclick
      • 你的标记会更干净
      • 您不必传递 btnRedredDot 之类的参数,因为事件侦听器会收到一个知道哪个元素触发了该事件的事件
    • 与其直接在 JS 中操作可见性/颜色,不如使用一个(或多个)CSS 类来执行您想要的操作,然后只需更改类即可。

    祝你好运! :)

    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>

    【讨论】:

    • 在js端存储元素。你的意思是像 html 中的onclick 这样的东西吗?如果是这样,我还有一些类似onmouseoveronmouseout。我看了eventListeners,但当时我觉得有点过头了。我遇到的例子越多,我就越喜欢它,所以我会再次研究。最后一点是我想要做的。我给按钮一个类,我试图使用像document.getElementById(id).className 这样的东西。我还能做这样的事情吗,因为颜色已经在课堂上声明了,而不是var buttonIdToColor
    • 看起来我的最后一个问题已在下面得到解答。我使用了您的示例,但将dotIddot 更改为canvasIdcanvas。非常感谢。
    • 我现在想说的是,继续做你正在做的事情,但把这些想法记在脑海里。 @Blindman67 发布了一个很好的答案,其中包含了我提出的所有建议(最小化 DOM 访问,从 JS 端绑定事件处理程序,并使用 CSS 类而不是直接在元素上操作样式)。现在可能并不完全有意义,但每隔一段时间再回顾一下,最终会完全清楚。干杯! :)
    【解决方案2】:

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

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

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

    我没有操作元素样式,而是添加了 DOM 类,.black 用于按钮,.hide.show 用于画布。所以只需要设置元素的类名而不是它们的样式。如果您有一组复杂的样式要在它们之间切换,这会更容易。

    "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>

    【讨论】:

    • 这是来自 IE11 的错误: "message": "Syntax error","filename": "stacksnippets.net/js","lineno": 48,"colno": 53 And from Safari: "message": "Script error.","filename": "","lineno": 0,"colno": undefined 我以为是和i有关,所以我把var i=0;但它也没有工作。
    • @Cyb3rMann 是的,因为 IE11 不支持箭头功能。只需将 (col,i)=&gt; 替换为 function(col,i) 或使用类似 babel 的东西。
    • 谢谢,这更有意义,我读的是“等于或大于”:)
    猜你喜欢
    • 2014-09-02
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    相关资源
    最近更新 更多