jsfiddle.net上JavaScript无法运行

74
以下代码在在线网站上运行正常,但我无法在jsfiddle上运行它。
例如,请查看此处
有谁能告诉我为什么它在jsfiddle上无法运行?
在控制台上记录以下内容:ReferenceError:fillList未定义ReferenceError:mySelectList未定义
如您所见,当代码作为嵌入式片段嵌入时,它可以正常工作。

function BetterSelect(oSelList) {
  this.objSelectList = oSelList;
  this.objSelectList.onchange = this.selectionChanged;
}
BetterSelect.prototype.clear = function() {
  this.objSelectList.options.length = 0;
}
BetterSelect.prototype.fill = function(aValues) {
  this.clear();
  for (var i = 0; i < aValues.length; i++) {
    this.objSelectList.options[i] = new Option(aValues[i]);
  }
}
BetterSelect.prototype.find = function(strToFind, bSelect) {
  var indx = -1;
  this.objSelectList.options.selectedIndex = -1;
  for (var i = 0; i < this.getCount(); i++) {
    if (this.objSelectList.options[i].text == strToFind) {
      indx = i;
      if (bSelect)
        this.objSelectList.options.selectedIndex = i;
    }
  }
  return indx;
}
BetterSelect.prototype.getCount = function() {
  return this.objSelectList.options.length;
}
BetterSelect.prototype.selectionChanged = function() {
  alert("selection changed!");
}

var mySelectList = null;
window.onload = function() {
  mySelectList = new BetterSelect(document.getElementById('theList'));
}

function fillList() {
  mySelectList.fill(["one", "two", "three", "four", "five"]);
}

function findIt() {
  mySelectList.find(document.getElementById('txtToFind').value, true);
}
<form action="" method="post">
  <select multiple="multiple" name="Select1" id="theList" style="width: 152px; height: 226px">
  </select>
  <br />
  <input name="Button1" type="button" value="Fill The List" onclick="fillList()" />
  <input name="Button4" onclick="mySelectList.clear()" type="button" value="Clear The List" />
  <br />
  <input name="Button2" onclick="alert(mySelectList.getCount())" type="button" value="What's The Count?" />
  <br />
  <input name="Text1" type="text" id="txtToFind" />
  <input name="Button3" type="button" value="Search" onclick="findIt()" />
</form>


3
请参考可能的重复问题:Simple example doesn't work on JSFiddle - Bergi
4个回答

92
您定义的函数被定义在一个"onload"函数中,因此之前它们是可以被引用的,但由于它们是在该函数中定义的,所以它们只能从该函数内部引用。您可以在HTML中将它们引用为全局变量。有三种选择:
a)(最简单、最快,但不理想)- 将function blah(){}更改为window.blah = function(){}; 使函数成为全局变量。
b)(理想的方式)-使用无侵入式JavaScript仅从JS中附加DOM元素的行为,这意味着将HTML与JS分离。
c) 让jsfiddle不在onload上包装内容。将onLoad更改为no wrap(body或head)。
因此,您可以在仅使用JS的情况下执行以下操作,而不是<p onclick="lol()" id="foo">var e = document.getElementById('foo'); e.onclick = lol; 我建议选择b,因为它鼓励最佳实践。

1
谢谢。那么代码是如何在实际网站上运行的呢? - Leahcim
6
因为在实际网站上这些函数并不是定义在另一个函数内的。jsfiddle会将你的JS代码放进一个函数中。请在http://fiddle.jshell.net/mjmitche/afPrc/show/页面中查看源代码。 - meder omuraliev
4
谢谢。虽然需要这种变通方法,但这实在很荒谬。 - Jonah

49
在你的fiddle中,在左侧的下拉菜单中选择no wrap (head),点击Run即可运行。 查看示例 → 当选择onLoad时,你的函数只能在$(document).ready(function() {});的闭包内定义。

Nowrap是一个不错的选择,除非你试图从会话中读取cookies。 - Ruslan López
似乎不再有任何nowrap选项,尽管它仍然在文档中提到(这些文档似乎已经过时)。 - CpnCrunch
它仍然在那里。它在Javascript面板的设置下拉菜单中。 - jmargolisvt

6

我发现了相同的问题,并通过更改JavaScript设置中的Load Type来解决:

在下拉菜单的JavaScript设置中,选择No wrap-in<head>No wrap-in<body>。请参考下面的图片。

JavaScript设置菜单


似乎不再有任何 JavaScript 菜单。 - CpnCrunch
@CpnCrunch 不是的。菜单仍然在JavaScript代码部分的右上角。 - Don D
好的,谢谢,你是对的。我一直在看窗口的顶部和左侧。我从没想过菜单选项会在子窗口中的一个里面。 - CpnCrunch

0

看这里:

https://dev59.com/Om445IYBdhLWcg3wTIdf#4935684

或者看这个更好:

https://dev59.com/Om445IYBdhLWcg3wTIdf#19110630

这是我测试的内容:

function testJSON() { 
    var jsonString = '{"param1":"123","param2":"XXX78","param3":"11378"}'; 
    var tmp_obj = eval('(' + jsonString + ')');
    document.getElementById("result").innerHTML =  tmp_obj.param2;
}

function testJSON() { 
    var jsonString = '{"param1":"123","param2":"XXX78","param3":"11378"}'; 
    var tmp_obj = JSON.parse(jsonString);
    document.getElementById("result").innerHTML =  tmp_obj.param2;
} 

使用第二种方法更好。

P.S. > 我来自{{link1:如何使用JS解析JSON字符串中的参数?}}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接