I'd like to be able to programmatically add a class of console to the <body> tag if Firebug's console.log() was called anywhere on a page. Then I could put some obnoxious message on the screen to remind me not to deploy code with those statements still in it.
The very similar to Eric Meyer's Diagnostic CSS.
Is it possible?
Hehehe. It's an easy mistake to make, isn't it.
Option 1: Always write if(window.console) console.log(...); instead of just console.log(..);
Option 2:
function mydebug(thingtodebug) {
if(window.console) console.log(thingtodebug);
}
..then always use mydebug() instead of console.log();. You could include an else clause that throws up an alert box if console isn't defined.
Option 3:
if(!window.console) {
var console={
log : function() {alert("Don't call console.log");}
}
}
...this will do pretty much exactly what you're asking.
The trouble is that all these options involve including extra code in your live system just to help you avoid embarrassment. (and of course, it'd be even more embarrassing if you miss that alert box!)
If you want to avoid this, a better solution might be to have a separate script that scans your code for any occurrences of console.log. You could run this script as part of your deployment process.
Hope that helps.
This works for me (using jQuery):
$(document).ready(function() {
var body = $('body'),
console = window.console;
console.debug = function() {
if (!body.hasClass('console')) {
body.addClass('console');
console.debug = oldDebug;
}
}
console.debug('foo');
});
It will only add the class the first time our custom function is called. Then it sets console.debug to the original function.
That's the cool thing with javascript, you can override nearly everything :)
It's quite simple. Just override the default console object with your own:
<!DOCTYPE html>
<html>
<head>
<title>Console Test</title>
<script>
var oldConsole = (typeof window.console === "object") ? window.console : null;
var console = {
log: function() {
oldConsole.log(arguments);
document.body.className = "console";
alert('applied class');
}
};
</script>
</head>
<body>
<input type="button" value="click me" onclick="console.log('this is a test');">
</body>
</html>
Live example.
Related
I am using console.log(...) for debugging purposes. However the console gets messages from iframes too(I am using iframes in my HTML code). How can I see only the logs that I sent and not the logs that came from iframes?
This is kinda old post, but still, for those who will come here for help:
In Chrome you can check the "Selected context only" (screenshot here) option, and it'll be this.
How about adding a snippet in your JavaScript to catch errors thrown by the iFrames?
You could replace [IFRAME ERROR MESSAGE] with the errors your iFrame is throwing. If the snippet catches an error from an iFrame, it will do nothing, otherwise, it will output the error to the console:
window.onerror = function (msg, url, line) {
if (msg == "[IFRAME ERROR MESSAGE]") {
return true
}
else {
//do nothing
}
}
Make sure to put this code as early as possible in your script.
Reference
Reference 2
Working example (save it as test.html and open in chrome):
<button onclick="myfunction()">x is not defined</button>
<button onclick="myfunction2()">y is not defined</button>
<script>
window.onerror = function (msg, url, line) {
if (msg == "Uncaught ReferenceError: x is not defined") {
return true
}
else {
//do nothing
}
}
function myfunction(){
console.log(x);
}
function myfunction2(){
console.log(y);
}
</script>
In this example, you will see that no errors will be outputted in the console when you click the first button, but you will see errors when you click the second button.
Just filter out (using the Chrome's filter box) the log messages from the iFrame.
In Chrome's Console tab you have a Filter box, type there the name of the file you want to filer out, with a minus sign "-" before the file name.
You can filter multiply files, using space as a delimiter.
For example:
-LogUtil.js -FrameService.js
Or instead of typing, just right click on a log message, and select Hide message from <file_name>.
You can add something like "?nofrm=1" to the src attribute of the page's script tags you want to see logs for. Then in Chrome you can type "nofrm" into the filter to get logs from only them scripts. Add "?nofrm=1" to the url if you want to log inline scripts too.
I wrote a logger service for the client side. I used a pattern by which I can filter out the logs/errors etc which are being produced by my script and not by the iframes.
function logger(){
var pattern="PC:";
var info=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.info.apply(console, arguments);
}
var log=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.log.apply(console, arguments);
}
var warning=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.warn.apply(console, arguments);
}
var debug=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.debug.apply(console, arguments);
}
var error=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.error.apply(console, arguments);
}
return {
info:info,
log:log,
warning:warning,
debug:debug,
error:error
}
}
Here "PC:" is the pattern
You can filter the logs by source / hide from other scripts than you own. It will of course only be a solution if you get logs from a smaller number of scripts
I am currently trying to receive data using JSONP. When I hit
https://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=barack%20obama&callback=callbackForJsonpApi
I get the response perfectly fine:
callbackForJsonpApi({RESPONSE HERE})
But when I go to https://api.forecast.io/forecast/APIKEYHERE/37.8267,-122.423?callback=callbackforJsonApi I get:
typeof callbackforJsonApi === 'function' && callbackforJsonApi({ RESPONSE HERE})
Can anyone explain why I have that "typeof" part prepended to one response but not the other?
This is my site.dart file:
void main() {
// listen for the postMessage from the main page
window.onMessage.listen(dataReceived);
ScriptElement script = new Element.tag("script");
script.src = "https://api.forecast.io/forecast/APIKEY/37.8267,-122.423?callback=callbackforJsonApi";
document.body.children.add(script);
}
dataReceived(MessageEvent dataReceived) {
var data = JSON.parse(dataReceived.data);
print(data['responseData']);
}
This is my partial html:
<html>
<body>
<script type="text/javascript">
function callbackForJsonpApi(s) {
var data = JSON.stringify(s);
window.postMessage(data, '*');
}
</body>
</html>
I can't explain why these are different; seems like a bit of an oversight on Google's part (presumably they should be the same).
Both of them are valid; but the one with the extra check looks best; it's only trying to call the function if it exists (and is a function); which will stop a JavaScript error if you haven't declared the function.
If you're pulling this in server-side and spitting the code into your page; you should probably try and make your code tolerate both of these; just in case you happen to get different behaviour in the future (eg. if Google make these consistent).
I would like to add new attribute to select box which name and id are 'firm_id'. So far I have tried with this code, its working fine in mozila but not working in IE.
I am doing this with javascript because select box is coming from ajax.
The function sbmtfrm() is not calling in IE.
Error: Message: 'FB' is undefined.
May be FB is a object called in my js lib files, but now i am writing code within a another saperate script tag.
<script type="text/javascript">
function sbmtfrm()
{
alert('now submitting...');
document.frmsearch.submit();
}
function setOnclickAtt(name)
{
alert("'"+name+"'" + document.getElementById(name).getAttribute('onchange'));
alert(document.getElementById(name));
if(document.getElementById(name))
{
alert('attrr changed');
var ref = document.getElementById(name);
ref.setAttribute('onchange', 'sbmtfrm();');
alert("now new atrr = " + document.getElementById(name).getAttribute('onchange'));
}
else
{
alert('again');
setTimeout("setOnclickAtt('firm_id')",100);
}
}
setOnclickAtt('firm_id');
</script>
Any suggestion or ideas would be greatly appreciated.
Thanks a lot.
I think IE is picky when it comes to event handling. Try:
ref.onchange = sbmtfrm;
instead of:
ref.setAttribute('onchange', 'sbmtfrm();');
Also, I think the error message has nothing to do with this issue. It´s wrong but it´s another issue.
I'm trying to stub/mock/override a function call during testing which writes a log to a DB.
function logit(msg) {
writeMessageToDb(msg);
}
function tryingToTestThisFunction(){
var error = processSomething();
if (error) {
logit(error);
}
}
I'd like logit() to simply print to the console during testing...and doing a "isTesting()" if/else block inside the logit() function is not an option.
Is this possible without including some additional mocking framework. I'm currently using JsTestDriver for unit testing and have not had a chance to evaluate any mocking frameworks. An ideal solution at the moment would be to handle this without another framework.
I use Jasmine and Sinon.js (using Coffeescript), here's how I stub out the confirm() method to, for example, just return true.
beforeEach ->
#confirmStub = sinon.stub(window, 'confirm')
#confirmStub.returns(true)
afterEach ->
#confirmStub.restore()
In javascript the latest definition is the prevalent.
so just redefine the logit method after the first definition.
function logit(msg) {
console.log(msg);
}
example : http://www.jsfiddle.net/gaby/UeeQZ/
I have been working on exactly the same problem. The developers gave me an HTML5 app to test, so of course I can't change their code for testing. I decided to use qunit and sinon, along with sinon-qunit.
For a newb to JavaScript unit testing like me, I was going nuts with the sinon documentation and various examples on the web, as most of it seems for an implied environment that isn't mentioned. The code below is a complete page, so I hope nothing is left for confusion.
The function that I have to call is caller() and I can't do anything about stubme() because it's in the developer's code. However, I can add sinonstub() in my test code. But how to get it to work with sinon? The sinon documentation really confused me for a while, but below is the simple solution. The stub4stubme object can be used to control the stub action, and also get the information about what's happening with the stub calls.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="qunit-1.12.0.css" type="text/css" media="screen" />
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="sinon-1.7.3.js"></script>
<script src="qunit-1.12.0.js"></script>
<script src="sinon-qunit-0.8.0.js"></script>
<script>
// Dev code in another file
function stubme() {
return "stubme";
}
function caller() {
return "caller " + stubme();
}
// End of dev code
var sinonstub = function () {
return "u haz bin stubbed";
};
test("Stubbing global environments", function () {
equal(caller(), "caller stubme");
var stub4stubme = this.stub(window, "stubme", sinonstub);
equal(caller(), "caller u haz bin stubbed");
ok(stubme.called);
});
</script>
</body>
</html>
Javascript is not only runtime linked, but is the last word wins linked as well. This means you can redeclare the method with the behavior you want in your test (since your test has the last word):
function yourTest(){
oldImpl = logit; // An even better approach is to do this in a setup.
logit = function(msg){ Console.log.apply(console, s.call(arguments));};
// do you assertions: assert.... yada.
logit = oldImpl; // Do this to keep your test isolated from the others you'll be executing in this test run. An even better approach is to do this in a teardown.
}
can you just override the method on the window object? In Chrome console this works
function test() {console.log('test')};
window.test();
just override the logit function, this can be called anytime later than logit is defined.
(function(){
//keep handle to original logit method.
var ol = logit;
//shorter lookup path for slice
var s = Array.prototype.slice;
//logit override
logit = function() {
//if in testing
if (typeof IsTesting == "function" && !!IsTesting()) {
//log the arguments
console.log.apply(console, s.call(arguments));
} else {
//otherwise, call the original function.
ol.apply(this, s.call(arguments))
}
}
}());
For some reason my javascript code is messed up. When run through firebug, I get the error proceedToSecond not defined, but it is defined!
JavaScript:
<script type = "text/javascript">
function proceedToSecond () {
document.getElementById("div1").style.visibility="hidden";
document.getElementById("div2").style.visibility="visible";
}
function reset_Form() {
document.personalInfo.reset();
}
function showList() {
alert("hey");
if (document.getElementsById("favSports").style.visibility=="hidden") {
document.getElementsById("favSports").style.visibility="visible");
}
}
//function showList2() {
//}
</script>
HTML:
<body>
<!--various code -->
<input type="button" onClick="proceedToSecond()" value="Proceed to second form"/>
</body>
The actual problem is with your
showList function.
There is an extra ')' after 'visible'.
Remove that and it will work fine.
function showList()
{
if (document.getElementById("favSports").style.visibility == "hidden")
{
// document.getElementById("favSports").style.visibility = "visible");
// your code
document.getElementById("favSports").style.visibility = "visible";
// corrected code
}
}
There are a couple of things to check:
In FireBug, see if there are any loading errors that would indicate that your script is badly formatted and the functions do not get registered.
You can also try typing "proceedToSecond" into the FireBug console to see if the function gets defined
One thing you may try is removing the space around the #type attribute to the script tag: it should be <script type="text/javascript"> instead of <script type = "text/javascript">
I just went through the same problem. And found out once you have a syntax or any type of error in you javascript, the whole file don't get loaded so you cannot use any of the other functions at all.
important: in this kind of error you should look for simple mistakes in most cases
besides syntax error, I should say once I had same problem and it was because of bad name I have chosen for function. I have never searched for the reason but I remember that I copied another function and change it to use. I add "1" after the name to changed the function name and I got this error.