1

I am working on a project in Typescript. And this problem involves three main files: simulator.ts, sim.js, simulator.html.

The sim.js file is auto-generated from simulator.ts

In simulator.html, I have loaded sim.js in <head>

However, I when I try to use document.getElementsByTagName("canvas")[0]; and assign it to a variable, the variable is undefined.

In my simulator.html:

<!doctype html>
<html lang="en" data-manifest="" data-framework="typescript">

<head>
    <meta charset="utf-8">
    <title>Traffic Simulator</title>
    <style>
        body {
            background: transparent;
            overflow: hidden;
        }
    </style>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>            
    <!-- preload index.js
    <script>
        $(document).ready(function(){
            $("script").attr('src','TrafficSimulation/js/index.js')
        });
    </script> -->

    <script src="/cdn/bluebird.min.js"></script>
    <script src="/cdn/pxtsim.js"></script>
    <script src="/sim/sim.js"></script>  
    <link rel="stylesheet" href="TrafficSimulation/css/style.css">    
</head>

<body>
    <div id="svgcanvas" style="height: 270;">
        <canvas>
            <div></div>
        </canvas>
        <div class="box">
            Number of Cars:<br>
            <br><input type="range" max="100" min="10" value="36" onChange="init();">
                <span class="car_no">10</span>
        </div>
        <script></script>                   
    </div>        
</body>

In my simulator.ts, I have defined the following variables globally in my namespace

    /// <reference path="../node_modules/pxt-core/typings/globals/bluebird/index.d.ts"/>
    /// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>

namespace pxsim {
    /**
     * This function gets called each time the program restarts
     */
    initCurrentRuntime = () => {
        runtime.board = new Board();
    };

    /**
     * Gets the current 'board', eg. program state.
     */
    export function board() : Board {
        return runtime.board as Board;
    }

    /**
     * Represents the entire state of the executing program.
     * Do not store state anywhere else!
     */
    export class Board extends pxsim.BaseBoard {
        public element : HTMLDivElement;

        constructor() {
            super();
            this.element = <HTMLDivElement><any>document.getElementById('svgcanvas');
        }

        initAsync(msg: pxsim.SimulatorRunMessage): Promise<void> {
            document.body.innerHTML = ''; // clear children
            document.body.appendChild(this.element);

            return Promise.resolve();
        }   
    }

    let requestAnimFrame: any = (function(){
      return  window.requestAnimationFrame || 
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame    || 
        window.oRequestAnimationFrame      || 
        window.msRequestAnimationFrame     ||  
        function( callback:any ){
        window.setTimeout(callback, 1000 / 60);
      };
    })();
    var car_no = 10;
    console.log("canvas: "+document.getElementById("canvas1"));
    var canvas: HTMLCanvasElement = document.getElementsByTagName("canvas")[0];
    var ctx: CanvasRenderingContext2D = <CanvasRenderingContext2D>canvas.getContext("2d");
Leo Li
  • 73
  • 1
  • 3
  • 10
  • Maybe you didn't use onload listener, so when the script runs, the HTML elements aren't loaded yet. Though I don't know about TS, check your generated JS file to confirm. – klenium Oct 29 '17 at 10:07
  • @klenium but I can get access to the document in `Board` class in the simulator.ts file – Leo Li Oct 29 '17 at 10:17
  • 1
    `document` is always available in javascript, the rest of the DOM is available only once it is loaded. – Vivick Oct 29 '17 at 10:26
  • 1
    @Vivick is it the same thing for typescript? – Leo Li Oct 29 '17 at 10:32
  • I don't think typescript's default behavior would be to put all your code in a `document.addEventListener("DOMContentLoaded" ,)` – Vivick Oct 29 '17 at 10:33
  • 1
    @LeoLi typescript *id* javascript! Just a bit syntactic sugar around it, but the same runtime behaviour! – Lux Oct 29 '17 at 10:45
  • @Lux yeah I know this, but in my typescript, I just could not get the correct DOM object by using keyword `document` – Leo Li Oct 29 '17 at 15:52
  • @LeoLi If the element isn't assigned to the `document` yet, of course you can't get its object. `document.getElementsByTagName` runs before the browser finished loading the page. You need to wait till the DOM loads. Also, `document` is not a keyword, it is just an object. – klenium Oct 29 '17 at 18:30
  • @klenium how do I ensure that the html has loaded the page before I use it? – Leo Li Oct 29 '17 at 18:45
  • Maybe try [this](https://stackoverflow.com/questions/14742194/declaring-an-htmlelement-typescript) example. – klenium Oct 29 '17 at 18:55

0 Answers0