Search code examples
javascripthtmlvisual-studio-codelit

Javascript functions stop working when using import at top of script, even without trying to use what's imported


I'm trying to recreate a simple program of mine using lit instead of just basic js, but adding import statements seems to break every function.

Things seem to work just fine with "type": "module" alone in my package.json, but the second I change type="text/javascript" to type="module" in my script link within my html, or when I add:

import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';

to the top of my app.js, or even both in combination, none of my functions seem to work anymore.

I tried changing the scope of my functions as suggested in this thread: Functions not working when ```type="module"``` or import , but that didn't seem to have any effect.

Here is an example of one such function:

function initialize()
{
    xWins = window.sessionStorage.getItem('xWins');
    oWins = window.sessionStorage.getItem('oWins');
    draws = window.sessionStorage.getItem('draws');
    if(xWins == null) { xWins = 0; }
    if(oWins == null) { oWins = 0; }
    if(draws == null) { draws = 0; }
    document.getElementById('numXWins').innerHTML = "X WINS: " +xWins;
    document.getElementById('numOWins').innerHTML = "O WINS: " +oWins;
    document.getElementById('numDraws').innerHTML = "DRAWS: " +draws;
}

Is there something I'm missing? How can I keep my functions working after I add import statements?

EDIT: Added my index.html for completion's sake

<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="style.css">
    <script type="text/javascript" src="./app.js" defer></script>
    <script src="https://unpkg.com/mathjs/lib/browser/math.js"></script>
</head> 
<body onload="initialize();">
    <h3>Tic Tac Toe</h3>
    <p id="rules">Rules: One player chooses X's, the other chooses O's. Take turns drawing your symbols onto a square. The first to get three in a row wins!</p>    
    <table id="scoreboard">
        <thead>
            <tr>
                <td id="numXWins">X WINS</td>
                <td id="numOWins">O WINS</td>
                <td id="numDraws">DRAWS</td>
            </tr>
        </thead>
        <tbody>
            <td>0</td>
            <td>0</td>
            <td>0</td>
        </tbody>
    </table>
    <br>
    <table id="gameboard">
        <tr>
            <td><input type="button" name="gamecell" value="   " class="0,0" onclick="play(this);"></td>
            <td><input type="button" name="gamecell" value="   " class="0,1" onclick="play(this);"></td>
            <td><input type="button" name="gamecell" value="   " class="0,2" onclick="play(this);"></td>
        </tr>
        <tr>
            <td><input type="button" name="gamecell" value="   " class="1,0" onclick="play(this);"></td>
            <td><input type="button" name="gamecell" value="   " class="1,1" onclick="play(this);"></td>
            <td><input type="button" name="gamecell" value="   " class="1,2" onclick="play(this);"></td>
        </tr>
        <tr>
            <td><input type="button" name="gamecell" value="   " class="2,0" onclick="play(this);"></td>
            <td><input type="button" name="gamecell" value="   " class="2,1" onclick="play(this);"></td>
            <td><input type="button" name="gamecell" value="   " class="2,2" onclick="play(this);"></td>
        </tr>
    </table>
    <p id="caption" value="Current Turn: X">Current Turn: X</p>
    <input type="button" id="rematch" value="Rematch?" onclick="rematch();">
</body>
</html>

Solution

  • The best thing you can do is that everything is an element, like for example in the snippet below.

    <script type="module">
    import {
      LitElement,
    } from "https://unpkg.com/lit-element/lit-element.js?module";
    import {html} from "https://unpkg.com/lit/static-html.js?module";
    
    class MyElement extends LitElement {
      
      constructor() {
        super();
      }
      
      play(e) {
        console.log('play');
        e.target.value = 'X';
      }
      
      rematch() {
        console.log('rematch');
      }
      
      render() {
        return html`
          <h3>Tic Tac Toe</h3>
        <p id="rules">Rules: One player chooses X's, the other chooses O's. Take turns drawing your symbols onto a square. The first to get three in a row wins!</p>    
        <table id="scoreboard">
            <thead>
                <tr>
                    <td id="numXWins">X WINS</td>
                    <td id="numOWins">O WINS</td>
                    <td id="numDraws">DRAWS</td>
                </tr>
            </thead>
            <tbody>
                <td>0</td>
                <td>0</td>
                <td>0</td>
            </tbody>
        </table>
        <br>
        <table id="gameboard">
            <tr>
                <td><input type="button" name="gamecell" value="   " class="0,0" @click="${this.play}"></td>
                <td><input type="button" name="gamecell" value="   " class="0,1" @click="${this.play}"></td>
                <td><input type="button" name="gamecell" value="   " class="0,2" @click="${this.play}"></td>
            </tr>
            <tr>
                <td><input type="button" name="gamecell" value="   " class="1,0" @click="${this.play}"></td>
                <td><input type="button" name="gamecell" value="   " class="1,1" @click="${this.play}"></td>
                <td><input type="button" name="gamecell" value="   " class="1,2" @click="${this.play}"></td>
            </tr>
            <tr>
                <td><input type="button" name="gamecell" value="   " class="2,0" @click="${this.play}"></td>
                <td><input type="button" name="gamecell" value="   " class="2,1" @click="${this.play}"></td>
                <td><input type="button" name="gamecell" value="   " class="2,2" @click="${this.play}"></td>
            </tr>
        </table>
        <p id="caption" value="Current Turn: X">Current Turn: X</p>
        <input type="button" id="rematch" value="Rematch?" @click="${this.rematch}">`
      }
    }
    
    customElements.define("my-element", MyElement);
    </script>
    <my-element></my-element>