简体   繁体   English

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

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

I am trying to pass the canvas HTML element as a parameter, and I thought 'this' would work but I can't quite get it to. 我试图将canvas HTML元素作为参数传递,我以为“这”可行,但我不太明白。 Could someone help me use the 'this' keyword to pass the canvas to main() upon page-load, please? 有人可以帮我使用'this'关键字在页面加载时将画布传递给main()吗?

Doesn't work: 不起作用:

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

Works, but would like to use the 'this' keyword instead: 可以,但是想改用'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>

Doesn't work (onload not defined for canvas element): 不起作用(未为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>

Works, and uses 'this', but want the code to run without clicking: 可以使用'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>

I suggest you consider a different approach as you risk complicating the expressiveness of your overall scripting logic if you're mixing it into your HTML tags. 我建议您考虑使用另一种方法,因为如果将其混合到HTML标记中,可能会使整体脚本逻辑的表达复杂化。 More to your point, while you can't use onload in an HTML tag context to get any this beyond the window, you can create JS functions that are defined to execute after window.onload in any fashion you want. 更多的要贵点,但你不能在一个HTML标签的onload背景下使用得到任何this超出了窗口,您可以创建定义在任何你想要的方式在window.onload后执行JS功能。

You're already using JavaScript to define your canvas attributes, why not create the canvas in JS at the same time! 您已经在使用JavaScript定义画布属性,为什么不同时在JS中创建画布呢!

You can also see how this could be extended to open up your options on creating/appending more canvasses on the fly. 您还可以看到如何扩展此功能,以打开在动态创建/附加更多画布上的选项。

If this doesn't work for you, let me know if this was an abstracted question for an issue that I might be able to help with more directly. 如果这对您不起作用,请告诉我这是否是一个抽象问题,我可能可以直接解决。

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

Try this. 尝试这个。 I put javascript out from HTML for more cleaner code. 我从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> 

Your problem is with the use of onload . 您的问题是使用onload

Typically, a listener attached in-line is called as if wrapped in an outer function with it's this set to the element on which the listener is called. 通常,串联连接的侦听器被调用,就好像包裹在外部函数中一样, 函数设置为调用侦听器的元素。 However, that's not the case for onload listeners attached to the body element . 但是, 附加到body元素上的 onload侦听器不是这种情况。 Their execution is delayed and they are called with the global / window object set to this . 它们的执行被延迟,并且在全局 / 窗口对象设置为this的情况下调用它们。

So you can't use this the way you're trying to do it. 因此,您不能以这种方式使用它。

The following demonstrates that a the body's load listener is called with this as the global object, but the div's click listener is called with the div element as 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> 

Well so many ways to do things. 有很多做事的方法。

Element referencing in Javascript 用Javascript引用元素

To access a DOM element you need to id it by giving it a unique id . 要访问DOM元素,您需要通过为其赋予唯一id对其进行id

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

Note id Must be unique, if another element has the same id the browser will enter quirks mode (see below) 注意id必须是唯一的,如果另一个元素具有相同的id,浏览器将进入怪癖模式(请参见下文)

You can then access it directly using its id as a variable name. 然后,您可以使用其ID作为变量名称直接访问它。

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

There are some that prefer to use the slower and more painful. 有些人喜欢使用较慢和较痛苦的方法。

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

Or others use 或其他人使用

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

Get it in order 按顺序获取

All these methods have one problem. 所有这些方法都有一个问题。 When a browser parses a page it adds elements to the DOM one at a time from the top down. 当浏览器解析页面时,它会从上到下一次将元素添加到DOM中。

If you add some script above the elements you want to use, the script will not find the elements as they have not yet been created 如果在要使用的元素上方添加一些脚本,该脚本将找不到尚未创建的元素

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

So to make sure you add the script after the elements (and before the closing body tag see quirks mode below) 因此,请确保将脚本添加到元素之后(并且在结束body标签之前,请参见下面的怪癖模式)

Sometimes its just plain inconvenient for you to put the script after the content. 有时,将脚本放在内容之后只是很不便。 That is when you would put the code inside a function you call on the load event. 那是当您将代码放入在load事件中调用的函数中时。 The code in the function will not run until all the elements have been added to the page. 只有将所有元素都添加到页面后,该函数中的代码才能运行。

How you listen to that event is up to you, see below 如何收听该事件取决于您自己,请参见下文

Organizing an event 举办活动

It is considered bad form to assign an event handler directly 直接分配事件处理程序被认为是错误的形式

 myCanvas.onclick = function(){};

and even worse if you do 甚至更糟

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

with the road of enlightenment packed with those that say the following way is the way 启蒙之路充满了那些说以下方式是

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

All the above methods work, none of them are right or wrong, there are a few other ways as well. 以上所有方法均有效,对与错都不对,还有其他几种方法。 What method you use is up to you, I always recommend that you use the method you find easiest to remember and use. 哪种方法取决于您,我始终建议您使用最容易记住和使用的方法。

Careful of the quirks 小心怪癖

But there are some things you should not do. 但是有些事情你不应该做。 The reason is that some layouts make the browser think its back in the late 90's early 2000's, and you have not followed the rules (rules that nobody actually knew), to stop it's self looking stupid next to its peers it will switch to quirks mode which is not good and will generally slow everything down. 原因是某些布局使浏览器在2000年代末90年代初就想起了它,并且您没有遵循规则(没人真正知道的规则),以阻止它在同龄人旁边显得愚蠢,它将切换到怪癖模式。这不好,通常会使一切变慢。

One of the things that can trigger quirks mode is placing a script tag where it should not be. 可以触发怪癖模式的一件事是将脚本标记放置在不应放置的位置。

So NEVER put a script tag outside the body or head tags 因此,切勿将脚本标签放在身体或头部标签之外

The path to world peace is always put script tags where they belong. 通往世界和平的道路总是将脚本标签放到它们所属的位置。

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

The way to darkness. 黑暗之路。 Putting a script tag anywhere as follows 如下放置脚本标签

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

One way 单程

How I would do depends on the tide so currently 我该怎么办取决于目前的潮流

<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