在Dojo中以编程方式更改按钮文本

时间:2014-01-10 09:36:57

标签: javascript dom dojo

到目前为止,这是我的代码:

dojoConfig = {parseOnLoad: true};

resetStopwatch();

require(["dojo/query", "dijit/form/ToggleButton", "dijit/form/Button", "dojo/dom", "dojo/dom-attr", "dojo/domReady!"], function(query, ToggleButton, Button, dom, domAttr){
  //query("#resume").style("display", "none");

  var timeUpdate, flag; 
  flag = false;

  new ToggleButton({
    showLabel: true,
    checked: false,
    onChange: function(val) {
      if (val) {
        this.set('label', 'Stop');

        var milliseconds = seconds = minutes = hours = 0;

        if(flag){
          // fetch current time in the stopwatch
          milliseconds = parseInt(domAttr.get("milliseconds", "innerHTML"));
          seconds      = parseInt(domAttr.get("seconds", "innerHTML"));
          minutes      = parseInt(domAttr.get("minutes", "innerHTML"));
          hours        = parseInt(domAttr.get("hours", "innerHTML"));
        }

        var startTime = new Date();
        timeUpdate = setInterval(function(){
          var timeElapsed = new Date().getTime() - startTime.getTime();

          // calculate hours                
          hours = parseInt(timeElapsed/1000/60/60);
          hours = prependZero(hours);
          domAttr.set("hours", "innerHTML", hours + " h ");

          // calculate minutes
          minutes = parseInt(timeElapsed/1000/60);
          if(minutes > 60)
            minutes = minutes % 60;
          minutes = prependZero(minutes);
          domAttr.set("minutes", "innerHTML", minutes + " m ");

          // calculate seconds
          seconds = parseInt(timeElapsed/1000);
          if(seconds > 60)
            seconds = seconds % 60;
          seconds = prependZero(seconds);
          domAttr.set("seconds", "innerHTML", seconds + " s ");

          // calculate milliseconds 
          milliseconds = timeElapsed;
          milliseconds = prependZero(milliseconds);
          if(milliseconds > 1000)
            milliseconds = milliseconds % 1000;
          if(milliseconds < 10)
            milliseconds = "00" + milliseconds.toString();
          else if(milliseconds < 100)
            milliseconds = "0" + milliseconds.toString();                
          domAttr.set("milliseconds", "innerHTML", milliseconds + " milli");

        },25);  // updated time after every 25ms

      } else {
        this.set('label', 'Resume');
        clearInterval(timeUpdate);
      }
    },
    label: "Start"
  }, "start_stop");

  /*var resumeButton = new Button({
        label: "Resume",
        onClick: function(){
            //clearInterval(timeUpdate);
            //resetStopwatch();        
        }
    }, "resume");  */  

  var resetButton = new Button({
    label: "Reset",
    onClick: function(){
      domAttr.set("start", 'label', "Start");
      clearInterval(timeUpdate);
      resetStopwatch();        
    }
  }, "reset");
});

function resetStopwatch(){
  require(["dojo/dom-attr"], function(domAttr){
    domAttr.set("hours",        "innerHTML", "00 h ");
    domAttr.set("minutes",      "innerHTML", "00 m ");
    domAttr.set("seconds",      "innerHTML", "00 s ");
    domAttr.set("milliseconds", "innerHTML", "000 milli");
  });
}

function prependZero(time){
  if(time < 10){
    time = "0" + time.toString();
    return time;
  }
  else
    return time;
}
#stopwatch, #buttons{
  text-align: center;
}

.claro *
{
  outline: none;
}
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css">

<div id="stopwatch">
  <span id="hours"></span>
  <span id="minutes"></span>
  <span id="seconds"></span>
  <span id="milliseconds"></span>
</div>
<div id="buttons" class="claro">
  <button id="start_stop"></button>
  <!--<button id="resume"></button>-->
  <button id="reset"></button>
</div>

考虑这个用例:点击Start&gt;一段时间后,点击Reset - 我计划再次将标签从Stop更改为Start。所以,我做了:

domAttr.set("start", 'label', "Start");   // line # 83

但这是一个错误:

Uncaught TypeError: Cannot call method 'setAttribute' of null 

不确定我在这里做错了什么。请帮忙!

2 个答案:

答案 0 :(得分:4)

在Dojo中,窗口小部件和DOM节点之间存在差异。您的开始按钮是一个小部件,因此使用DOM节点设置该小部件的标签将不起作用。要更改窗口小部件的标签,首先需要使用dijit/registry模块检索窗口小部件实例,或者已经引用窗口小部件(ToggleButton)。

之后,您可以使用适当的setter来更改小部件的标签。

在您的情况下,最好的办法是创建对新ToggleButton的本地引用,例如:

var startBtn = new ToggleButton({
    /** Your code */
});

然后执行以下操作:

startBtn.set("label", "Start");

像往常一样,我也更新了您的JSFiddle


如果您想使用dijit/registry模块(现在不需要),您可以使用小部件ID(或DOM ID)来获取对小部件的引用:

require(["dijit/registry"], function(registry) {
    registry.byId("start_stop").set("label", "Start");
});

但是,在这种情况下它没有用,因为您可以更轻松地引用窗口小部件,但请记住以备将来引用(或者如果您开始使用声明性窗口小部件)。

答案 1 :(得分:2)

作为the documentation states,您应该将domNode传递给domAttr.set,而不是字符串。 因此,不是传递字符串“start”,而是传入domNode(例如,使用data-dojo-attach-point)。

我认为您应该将其替换为“this.set('label','Start');”。

这可以解决您的问题:

var startButton = new ToggleButton({
    showLabel: true,
    checked: false,
    onChange: function(val) {
       // code
    },
    label: "Start"
}, "start_stop");

var resetButton = new Button({
    label: "Reset",
    onClick: function(){
        startButton.set('label', "Start");
        clearInterval(timeUpdate);
        resetStopwatch();        
    }
}, "reset");

});

请注意,我保存了对startButton的引用,因此它可以是来自resetButton的onClick中的引用。