繁体   English   中英

Javascript“ this”传递画布以在页面加载时起作用

[英]Javascript 'this' to pass a canvas to function on page load

我试图将canvas HTML元素作为参数传递,我以为“这”可行,但我不太明白。 有人可以帮我使用'this'关键字在页面加载时将画布传递给main()吗?

不起作用:

<html>
    <head>
    <title>Draw on Canvas</title>
    </head>
    <body onload=main(this.firstChild)><canvas></canvas></body>
    <script>
        function main(canv) {
            cntx = canv.getContext("2d");
            cntx.rect(10, 10, 100, 100);
            cntx.fill();
        }
    </script>
</html>

可以,但是想改用'this'关键字:

<html>
    <head>
    <title>Draw on Canvas</title>
    </head>
    <body onload=main(document.body.firstChild)><canvas></canvas></body>
    <script>
        function main(canv) {
            cntx = canv.getContext("2d");
            cntx.rect(10, 10, 100, 100);
            cntx.fill();
        }
    </script>
</html>

不起作用(未为canvas元素定义onload):

<html>
    <head>
    <title>Draw on Canvas</title>
    </head>
    <body><canvas onload=main(this)></canvas></body>
    <script>
        function main(canv) {
            cntx = canv.getContext("2d");
            cntx.rect(10, 10, 100, 100);
            cntx.fill();
        }
    </script>
</html>

可以使用'this',但是希望代码无需单击即可运行:

<html>
    <head>
    <title>Draw on Canvas</title>
    </head>
    <body><canvas onclick=main(this)></canvas></body>
    <script>
        function main(canv) {
            cntx = canv.getContext("2d");
            cntx.rect(10, 10, 100, 100);
            cntx.fill();
        }
    </script>
</html>

我建议您考虑使用另一种方法,因为如果将其混合到HTML标记中,可能会使整体脚本逻辑的表达复杂化。 更多的要贵点,但你不能在一个HTML标签的onload背景下使用得到任何this超出了窗口,您可以创建定义在任何你想要的方式在window.onload后执行JS功能。

您已经在使用JavaScript定义画布属性,为什么不同时在JS中创建画布呢!

您还可以看到如何扩展此功能,以打开在动态创建/附加更多画布上的选项。

如果这对您不起作用,请告诉我这是否是一个抽象问题,我可能可以直接解决。

 <html> <head> <title>Draw on Canvas</title> </head> <body> <script> function createCanvasRect(x, y, width, height) { var canv = document.createElement('canvas'), cntx = canv.getContext('2d'); cntx.rect(x, y, width, height); cntx.fill(); return canv; } function load() { var canvas = createCanvasRect(10, 10, 100, 100); document.body.appendChild(canvas); } window.onload = load; </script> </body> </html> 

尝试这个。 我从HTML中删除了javascript,以获得更简洁的代码。

 function main() { console.log(this); var cntx = this.getContext("2d"); cntx.rect(10, 10, 100, 100); cntx.fill(); } window.onload = function() { main.call(document.getElementById('main')); } 
 <html> <head> <title>Draw on Canvas</title> </head> <body> <canvas id="main"></canvas> </body> </html> 

您的问题是使用onload

通常,串联连接的侦听器被调用,就好像包裹在外部函数中一样, 函数设置为调用侦听器的元素。 但是, 附加到body元素上的 onload侦听器不是这种情况。 它们的执行被延迟,并且在全局 / 窗口对象设置为this的情况下调用它们。

因此,您不能以这种方式使用它。

以下内容演示了将this作为全局对象调用body的负载侦听器,但使用div元素this调用div的click侦听器。

 <script> // Reference to global/window object var global = this; </script> <body onload="console.log(this === global)"> <div onclick="console.log(this.tagName)">clickable div</div> </body> 

有很多做事的方法。

用Javascript引用元素

要访问DOM元素,您需要通过为其赋予唯一id对其进行id

<canvas id="myCanvas"></canvas>

注意id必须是唯一的,如果另一个元素具有相同的id,浏览器将进入怪癖模式(请参见下文)

然后,您可以使用其ID作为变量名称直接访问它。

 var ctx = myCanvas.getContext("2d");

有些人喜欢使用较慢和较痛苦的方法。

 var ctx = document.getElementById("myCanvas").getContext("2d");

或其他人使用

 var ctx = document.querySelector("#myCanvas").getContext("2d");

按顺序获取

所有这些方法都有一个问题。 当浏览器解析页面时,它会从上到下一次将元素添加到DOM中。

如果在要使用的元素上方添加一些脚本,该脚本将找不到尚未创建的元素

<canvas id="topCan"></canvas>
<script> // this code is run when the browser finds it
    var ctx = topCan.getContext("2d"); // works as the element has been created
    var ctx1 = botCan.getContext("2d"); // no work as the element does not yet exist
</script>
<canvas id="botCan"></canvas>

因此,请确保将脚本添加到元素之后(并且在结束body标签之前,请参见下面的怪癖模式)

有时,将脚本放在内容之后只是很不便。 那是当您将代码放入在load事件中调用的函数中时。 只有将所有元素都添加到页面后,该函数中的代码才能运行。

如何收听该事件取决于您自己,请参见下文

举办活动

直接分配事件处理程序被认为是错误的形式

 myCanvas.onclick = function(){};

甚至更糟

 <canvas onclick = "myFuction(this)"></canvas>

启蒙之路充满了那些说以下方式是

 const canvas = document.querySelector("#myCanvas");   
 canvas.addEventListener("click",myFunction);
 function myFunction(){ /* code */}

以上所有方法均有效,对与错都不对,还有其他几种方法。 哪种方法取决于您,我始终建议您使用最容易记住和使用的方法。

小心怪癖

但是有些事情你不应该做。 原因是某些布局使浏览器在2000年代末90年代初就想起了它,并且您没有遵循规则(没人真正知道的规则),以阻止它在同龄人旁边显得愚蠢,它将切换到怪癖模式。这不好,通常会使一切变慢。

可以触发怪癖模式的一件事是将脚本标记放置在不应放置的位置。

因此,切勿将脚本标签放在身体或头部标签之外

通往世界和平的道路总是将脚本标签放到它们所属的位置。

<html>
   <head>
      <script></script> <!-- browser is your friend -->
   </head>
   <body>
      <script></script> <!-- browser thinks your great -->
      <p> some content </p>
      <script></script> <!-- and you know everything-->
   </body>
</html>

黑暗之路。 如下放置脚本标签

<script></script> <!-- wrong -->
<html>
   <script></script> <!-- wrong -->
   <head>

   </head>
   <script></script> <!-- oh so bad -->
   <body>
   </body>
   <script></script> <!-- oh so bad -->
</html>
<script></script> <!-- just playing with fire -->

单程

我该怎么办取决于目前的潮流

<html>
    <head>
    <title>Draw on Canvas</title>
    </head>
    <body>
        <!-- id the canvas with a unique id -->
        <canvas id = myCanvas></canvas>
        <script>  // script after the element you are accessing
            const ctx = myCanvas.getContext("2d");
            ctx.rect(10, 10, 100, 100);
            ctx.fill();
         </script> <!-- ensure the script is inside the body tag -->
     </body>
</html>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM