【问题标题】:Javascript dynamic onClickJavascript动态onClick
【发布时间】:2019-06-27 13:39:01
【问题描述】:

我在一个页面上有 2 个代码镜像组件,当您单击“运行”按钮时,我希望它只运行按钮上方的代码。

我遇到的问题是它只运行最后一个 codemirror 组件,并没有按照我喜欢的方式运行单个代码。

下面的按钮onClick函数有什么办法可以动态设置吗?

带有 onClick 按钮的 Codemirror 组件:

<div id="content">
        <section class="method first-of-group" id="intro">
          <div class="method-area method-area-expanded">
            <div class="method-copy">
              <h1 class="lesson-name">python title</h1>

            <div class="method-example">
              <div id="side-view">
                <div id="side-left">
                  <textarea id="yourcode" cols="40" rows="10">
my_name = "Sir Python"
print("Hello and welcome " + my_name + "!")
                    </textarea
                  >
                  <script type="text/javascript">
                    // insert codemirror
                    var myCodeMirror = CodeMirror.fromTextArea(yourcode, {
                      lineNumbers: true,
                      mode: "python"
                    });
                  </script>
                </div>
                <br />

                <div id="side-right">
                  <div id="console">
                    <pre id="output"></pre>
                  </div>
                  <!-- If you want turtle graphics include a canvas -->
                  <div id="mycanvas"></div>
                </div>
                <button type="button" onclick="runit()">Run</button>
              </div>
            </div>
          </div>
        </section>

        <section class="method first-of-group" id="intro">
          <div class="method-area method-area-expanded">
            <div class="method-copy">
              <h1 class="lesson-name">python title</h1>

            <div class="method-example">
              <div id="side-view">
                <div id="side-left">
                  <textarea id="authcode" cols="40" rows="10">
# This code will print out Hello World
print("Hello World")
                      </textarea
                  >
                  <script type="text/javascript">
                    // insert codemirror
                    var myCodeMirror = CodeMirror.fromTextArea(authcode, {
                      lineNumbers: true,
                      mode: "python"
                    });
                  </script>
                </div>
                <br />

                <div id="side-right">
                  <div id="console">
                    <pre id="output"></pre>
                  </div>
                  <!-- If you want turtle graphics include a canvas -->
                  <div id="mycanvas"></div>
                </div>
                <button type="button" onclick="runit()">Run</button>
              </div>
            </div>
          </div>
        </section>
      </div>

这里是onClick函数:

<script type="text/javascript">
      // output functions are configurable.  This one just appends some text
      // to a pre element.
      function outf(text) {
        var mypre = document.getElementById("output");
        mypre.innerHTML = mypre.innerHTML + text;
      }
      function builtinRead(x) {
        if (
          Sk.builtinFiles === undefined ||
          Sk.builtinFiles["files"][x] === undefined
        )
          throw "File not found: '" + x + "'";
        return Sk.builtinFiles["files"][x];
      }

      // Here's everything you need to run a python program in skulpt
      // grab the code from your textarea
      // get a reference to your pre element for output
      // configure the output function
      // call Sk.importMainWithBody()
      function runit() {
        var prog = myCodeMirror.getValue();
        var mypre = document.getElementById("output");
        mypre.innerHTML = "";
        Sk.pre = "output";
        Sk.configure({ output: outf, read: builtinRead });
        (Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = "mycanvas";
        var myPromise = Sk.misceval.asyncToPromise(function() {
          return Sk.importMainWithBody("<stdin>", false, prog, true);
        });
        myPromise.then(
          function(mod) {
            console.log("success");
                      ]
          },
          function(err) {
            console.log(err.toString());
          }
        );
      }
    </script>

【问题讨论】:

    标签: javascript codemirror skulpt


    【解决方案1】:

    问题在于您正在重用相同的变量名称myCodeMirror。由于页面上的脚本是按 DOM 顺序执行的,所以使用最后一个值。

    此外,您使用的是相同的 runit() 方法,没有区分要运行哪个镜像,因此它将始终在您设置的最后一个 CodeMirror 上运行。


    首先,您需要将 CodeMirror 存储在不同的变量中:

    var myCodeMirror1 = CodeMirror.fromTextArea(yourcode, {
        lineNumbers: true,
        mode: "python"
    });
    
    [...]
    
    var myCodeMirror2 = CodeMirror.fromTextArea(authcode, {
        lineNumbers: true,
        mode: "python"
    });
    

    然后每个按钮需要告诉runit使用哪一个:

    <button type="button" onclick="runit(myCodeMirror1)">Run</button>
    
    [...]
    
    function runit(mirrorToRun) {
        var prog = mirrorToRun.getValue();
        [...]
    }
    

    【讨论】:

    • 效果很好!有没有办法更新输出?目前提交的输出只进入顶部的codemirror组件并在那里更新。
    • @StackUnderFlow 这是同一个问题,您正在重用需要唯一的标识符 - 两个输出区域都有 id="output"。因此,当outf 执行document.getElementById("output") 时,它总是会找到第一个输出区域。要解决此问题,您需要为它们提供唯一的 id 值并(可能)将第二个参数传递给 outf 以告诉它使用什么 id
    猜你喜欢
    • 2019-05-15
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多