1

我第一次使用 dat.gui 为我感兴趣的电视节目创建搜索系统。我首先创建了一个对象,其中节目标题作为键,搜索查询作为值。一切都很好,直到我将其付诸实践,并且每次都搜索最后一个密钥。当我这样做时,我担心会发生这种情况,但无论如何都想不到。我考虑过使用window['string']从字符串中设置变量名,但无法弄清楚它在我的情况下是如何工作的。

我正在使用用户脚本,所以我有一些限制。我的脚本如下:

NodeList.prototype.forEach = Array.prototype.forEach;

var shows = {
        'Agents of S.H.I.E.L.D.' : 'marvels agents of s.h.i.e.l.d.',
        'Arrow' : 'arrow s',
        'Brooklyn Nine-Nine' : 'brooklyn nine-nine',
        'Castle' : 'castle 2009',
        'Chicago Fire' : 'chicago fire',
        'Chicago P.D.' : 'chicago p.d.',
        'Constantine' : 'contanstine s',
        'Doctor Who' : 'doctor who',
        'Gotham' : 'gotham s',
        'Grimm' : 'grimm s',
        'Madam Secretary' : 'madam secretary',
        'NCIS LA' : 'ncis los angeles',
        'Resurrection' : 'resurrection',
        'Saturday Night Live' : 'saturday night live',
        'Scandal' : 'scandal s',
        'Scorpion' : 'scorpion s',
        'Stalker' : 'stalker s',
        'The 100' : 'the 100 s',
        'The Big Bang Theory' : 'the big bang theory',
        'The Blacklist' : 'the blacklist',
        'The Flash' : 'the flash',
        'The Tonight Show Starring Jimmy Fallon' : 'jimmy fallon',
        'Z Nation' : 'z nation'
    },
    show = function() {
        for (var k in shows) {
            this[k] = function() {
                document.getElementById('tsstac').value = shows[k].replace(/ /g, '.');
                document.querySelectorAll('[type=submit]')[0].click();
            };
        }
    };
window.onload = function() {
    var text = new show(),
        gui = new dat.GUI({
          resizable : false,
          hideable : false
        });
    for (var k in shows) {
        gui.add(text, k);
    }
    document.querySelectorAll('li.cr>div>span.property-name').forEach(function(v) {
    	v.style.width = '100%';
    });
};
<script src="http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<input type="text" id="tsstac" />
<input type="submit" />
<p>Regardless of which button is pressed, it'll always be the last query.</p>

无论按下什么按钮,都会搜索最后一个查询(Z Nation)。我该如何解决这个问题?

编辑:
我已经更新了代码,但仍然无法正常工作。

编辑:
代码不再创建复选框,而是创建按钮列表。问题依然存在,现在进行演示。

4

1 回答 1

1

由于 javascript 关闭问题,您会遇到此问题(请查看答案以获取更多信息);您的每个匿名函数都绑定到函数外部的相同变量(在您的情况下,您的“for(var k in show)”循环中的 k 的最终值)。

要解决此问题,您可以在 for 循环之外创建 dat.GUI 按钮的功能。我在这里创建了一个 CodePen:

http://codepen.io/BenSmith/pen/LEwje

例如,单击“Gotham”现在将根据您在示例中定义的行为使用值“gotham.s”填充输入控件。

实现这一点的代码是:

NodeList.prototype.forEach = Array.prototype.forEach;

var shows = {
  'Agents of S.H.I.E.L.D.' : 'marvels agents of s.h.i.e.l.d.',
  'Arrow' : 'arrow s',
  'Brooklyn Nine-Nine' : 'brooklyn nine-nine'
  // Object shortened for brevity
}; 

showsProperties = { 
  shows: "shows" 
};

window.onload = function() {
  var gui = new dat.GUI();

  // Get around the closure issue by implementing 
  // the dat.GUI button handler outside of the for loop
  var showHandler = function(show)
  {
    return function(){
      return show.replace(/ /g, '.');
    }
  }

  for(var key in shows)
  {  
    showsProperties[key] = showHandler(shows[key]);

    var showController = gui.add(showsProperties, key );

    showController.onFinishChange(function(value) {
      document.getElementById('showSearchField').value = value();
    });
  };

  document.querySelectorAll('li.cr>div>span.property-name').forEach(function(v) {
        v.style.width = '100%';
    });
};
于 2014-10-24T01:35:08.633 回答