Javascript 未捕获的 ReferenceError:X 未定义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8893786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Uncaught ReferenceError: X is not defined
提问by RSilva
This code is being used on a Chrome Extension. When I call the "showOrHideYT()" function, i get a "Uncaught ReferenceError: showOrHideYT is not defined | (anonymous function) | onclick".
此代码用于 Chrome 扩展程序。当我调用“showOrHideYT()”函数时,我得到一个“Uncaught ReferenceError: showOrHideYT is not defined |(匿名函数)| onclick”。
This code will search for youtube links in a page, and it will add a button (it's really a div with an event) next to the link to show the iframe with the embedded video, pretty much like Reddit Enhancement Suite. Consider the code, per se, incomplete. I just want to know what am i missing when i call the "showOrHideYT(frameZES12345)" function.
此代码将搜索页面中的 youtube 链接,并在链接旁边添加一个按钮(它实际上是一个带有事件的 div)以显示带有嵌入视频的 iframe,非常类似于 Reddit Enhancement Suite。考虑代码本身是不完整的。我只想知道当我调用“showOrHideYT(frameZES12345)”函数时我错过了什么。
if needed, i can provide manifest.json.
如果需要,我可以提供 manifest.json。
Thanks
谢谢
function showOrHideYT(id)
{
var YTvidWidth = 420;
var YTvidHeight = 315;
frameYT=getElementById(id);
console.log(frameYT.style.visibility);
if (frameYT.style.visibility == "hidden")
{
frameYT.style.width = YTvidWidth+"px";
frameYT.style.height = YTvidHeight+"px";
frameYT.style.visibility = "visible";
}
if (frameYT.style.visibility == "visible")
{
frameYT.style.width = "0px";
frameYT.style.height = "0px";
frameYT.style.visibility = "hidden";
}
};
// DOM utility functions
function insertAfter( referenceNode, newNode ) {
if ((typeof(referenceNode) == 'undefined') || (referenceNode == null)) {
console.log(arguments.callee.caller);
} else if ((typeof(referenceNode.parentNode) != 'undefined') && (typeof(referenceNode.nextSibling) != 'undefined')) {
if (referenceNode.parentNode == null) {
console.log(arguments.callee.caller);
} else {
referenceNode.parentNode.insertBefore( newNode, referenceNode.nextSibling );
}
}
};
function createElementWithID(elementType, id, classname) {
obj = document.createElement(elementType);
if (id != null) {
obj.setAttribute('id', id);
}
if ((typeof(classname) != 'undefined') && (classname != '')) {
obj.setAttribute('class', classname);
}
return obj;
};
///////////////////////////////////////
$(document).ready(function() {
var vidWidth = 420;
var vidHeight = 315;
var linksSemID = document.getElementsByTagName("a") ;
for (var i = 0; i < linksSemID.length; i++){
if (/id=$/.test(linksSemID[i].href)) links[i].href += "1";
}
i=0;
var youTubeRegExp = /(?:v=)([\w\-]+)/g;
var forEach = Array.prototype.forEach;
var linkArray = document.getElementsByTagName('a');
forEach.call(linkArray, function(link){
linkArray.id="zes" + i++;
var linkTarget = link.getAttribute('href');
if (linkTarget!=null)
{
if (linkTarget.search(youTubeRegExp) !=-1)
{
console.log (linkTarget);
idVideo=linkTarget.match(/(?:v=)([\w\-]+)/g);
//idVideo = idVideo.replace("v=", "");
//add buton
botaoMais = document.createElement('DIV');
botaoMais.setAttribute('class','expando-button collapsed video');
botaoMais.setAttribute('onclick','showOrHideYT(frameZES'+ i +')');
insertAfter(link, botaoMais);
//add iframe
ifrm = document.createElement('IFRAME');
ifrm.setAttribute('src', 'http://www.youtube.com/embed/'+ idVideo);
ifrm.style.width = '0px';
ifrm.style.height = '0px';
ifrm.style.frameborder='0px';
ifrm.style.visibility = 'hidden';
ifrm.setAttribute('id', 'frameZES' + i);
insertAfter(link, ifrm);
}
}
});
});
回答by Rob W
When you use setAttribute
with a string, the event will be executed in the context of the page. The functions which are defined in a Content script are executed in a sandboxed scope. So, you have to pass a function reference, instead of a string:
当您使用setAttribute
字符串时,事件将在页面上下文中执行。在内容脚本中定义的函数在沙盒范围内执行。所以,你必须传递一个函数引用,而不是一个字符串:
Replace:
代替:
botaoMais.setAttribute('onclick','showOrHideYT(frameZES'+ i +')');
With:
和:
botaoMais.addEventListener('click', (function(i) {
return function() {
showOrHideYT("frameZES"+ i);
};
})(i));
Explanation of code:
代码说明:
(function(i) { ..})(i)
is used to preserve the value ofi
for each event.- Inside this self-invoking function, another function is returned, used as an event listener to
click
.
(function(i) { ..})(i)
用于保存i
每个事件的值。- 在这个自调用函数中,返回另一个函数,用作 的事件侦听器
click
。
回答by vaibhav
I see that you are using jQuery in your code. I personally think if we are using a library like jQuery, then we should not mix the native javascript code and jQuery code. You can use jQuery bind to bind your the functions you need to call on dom ready. Read below to know more.
我看到您在代码中使用了 jQuery。我个人认为,如果我们使用像 jQuery 这样的库,那么我们不应该混合使用原生 javascript 代码和 jQuery 代码。您可以使用 jQuery 绑定来绑定您需要在 dom 就绪时调用的函数。阅读下文以了解更多信息。
suppose you want to call a javascript function on a button click, Here is the HTML for the same.
假设您想在单击按钮时调用 javascript 函数,这是相同的 HTML。
<div id="clickme">
<input id= "clickmebutton" type="button" value = "clickme" />
</div>
suppose "test" is the function you need to call, here is the code for test function.
假设“test”是你需要调用的函数,这里是测试函数的代码。
function test() {
alert("hello");
}
you now need to bind the test function on the button click.
您现在需要在按钮单击时绑定测试功能。
$(document).ready(function() {
$("#clickmebutton").bind("click", function(){
// do what ever you want to do here
test();
});
});