我正在制作一个双栏数学页面,左侧有定理和定义,右侧有其他解释。
用户访问解释的方式是单击“可解释”类的文本。
页面加载后,我运行一个脚本,为每个“可解释”元素提供自己的onclick函数,该函数隐藏右侧面板上的文本(如果有的话),并用点击的元素说明重新填充它。
但是当我尝试运行它时,它告诉我可解释的元素是未定义的。
以下是相关函数和类的文本示例:
功能
<script type="text/javascript">
window.setTimeout(makeExplanations, 3000);
function makeExplanations(){
var explainables = document.getElementsByClassName("explainable");
var currentlyShowing = "";
for(var i = 0; i < explainables.length; i++){
console.log("id: " + explainables[i].id);
var element = explainables[i];
explainables[i].onclick = function(){
if(currentlyShowing != ""){
document.getElementById(currentlyShowing + 'e').style.display = "none";
}
var explanationDiv = document.getElementById(explainables[i].id + 'e')
explanationDiv.style.display = "inline";
explanationDiv.focus();
currentlyShowing = explainables[i].id;
};
}
}
</script>
我让它等待3秒钟才能执行,因为执行body onload=makeExplainables()
是不够的。 (可能与MathJax加载的方式有关 - 我不确定。)
可解释类的示例
<span class="explainable" id="595858535"><a href="#top">so either statement is vacuously true</a></span>. Thus, $X = Y$ holds,
and hence we declare that there exists only one set with no elements.</p>
及其揭示的解释
<div id="595858535e" style="display: none;">
<p>An if-then statement (a conditional) is vacuously true when the if portion is false in all cases.
For example, the statement "If 2 + 2 = 5, then pigs fly" is vacuously true, since its
antecedent (if 2 + 2 = 5) is always false.</p>
<p>In this case, the conditional in question is "there exists some $x \in X$ such that $x \notin Y$".
But since $X$ is an empty set, there does not exist any $x \in X$ such that anything. Hence, the
statement is vacuously true in all cases.</p>
<p>Another way to think about it is this: a conditional is only falsified if its antecedent ("if ...") is true
and its consequent ("then ... ") is false. If the antecedent is always false, then this can never happen.
Thus the statement as a whole is always true.</p>
</div>
当我尝试点击可解释的文字时出现Firebug错误:
16:23:44.704 "id: 595858535" zfc:89
16:23:44.704 "id: 595858536" zfc:89
16:23:53.045 TypeError: explainables[i] is undefined zfc:95
答案 0 :(得分:1)
所以,我终于通过将onclick函数中的explanation[i]
更改为this
来实现它。
我以为我正在制作一个闭包,即使在explanation[i]
结束后,makeExplanations()
变量也可以从onclick函数中访问,但我猜这是不正确的。
修正后的onclick函数如下所示:
explainables[i].onclick = function(){
if(currentlyShowing != ""){
document.getElementById(currentlyShowing + 'e').style.display = "none";
}
var explanationDiv = document.getElementById(this.id + 'e')
explanationDiv.style.display = "inline";
explanationDiv.focus();
currentlyShowing = this.id;
};
答案 1 :(得分:1)
该错误的真正原因是,当调用单击处理程序时,“i”已经达到了等于数组长度的值。因此,可解释的[i],即explainables [explainables.length]是未定的。
JS摆弄控制台日志以更好地解释你:http://jsfiddle.net/wV4Lh/6/
element.onclick = function(){
// length of array is 2 for this example
console.log("explainables length: " + explainables.length);
// value of i is 2 in the click handler
console.log("i: " + i);
// explainables[i] = explainables[2] is undefined
console.log("explainables[i] - ith: " + explainables[i]);
// explainables[0] is valid
console.log("explainables[0] - 0th: " + explainables[0]);
// explainables[1] is valid
console.log("explainables[1] - 1st: " + explainables[1]);
};
这清楚地表明,可解释性在点击处理程序的范围内,但是i =数组的长度值作为'for'循环已经完成了它在触发click事件之前的完整执行方式。
P.S:最初理解处理程序的这种行为的困难是由于处理程序工作的反直觉方式,即它不是与其它代码相关的顺序执行。处理程序仅在触发相应事件时执行,而不是在for循环中执行,在这种情况下。