来看一个简易的 Javascript 调试包:jscript.debug.js,包含两个函数,第一个用来遍历对象的各个属性;第二个是一个通用的 Debug 函数(其实 说‘对象’比较‘精确些’,呵呵),用来规定各种错误级别及其各种提示、错误信息的格式化显示,还是《Javascript 实战》上面的经典例子,先看源码:
/** * jscript.debug package * This package contains utility functions for helping debug JavaScript. * */ /*命名空间*/ if (typeof jscript == 'undefined') { jscript = function() { } } jscript.debug = function() { } /** * This simple function is one of the handiest: pass it an object, and it * will pop an alert() listing all the properties of the object and their * values.(这个函数用来遍历对象的属性及其相应的值,并显示出来) * * @param inObj The object to display properties of. */ jscript.debug.enumProps = function(inObj) { var props = ""; var i; for (i in inObj) { props += i + " = " + inObj[i] + "\n"; } alert(props); } // End enumProps(). /** * This is a very simple logger that sends all log messages to a specified * DIV.(这是一个简单的 debug 日志记录系统) */ jscript.debug.DivLogger = function() { /** * The following are faux constants that define the various levels a log * instance can be set to output.(下面的常量用来定义错误级别) */ this.LEVEL_TRACE = 1; this.LEVEL_DEBUG = 2; this.LEVEL_INFO = 3; this.LEVEL_WARN = 4; this.LEVEL_ERROR = 5; this.LEVEL_FATAL = 6; /** * These are the font colors for each logging level.(定义各种错误的显示颜色) */ this.LEVEL_TRACE_COLOR = "a0a000"; this.LEVEL_DEBUG_COLOR = "64c864"; this.LEVEL_INFO_COLOR = "000000"; this.LEVEL_WARN_COLOR = "0000ff"; this.LEVEL_ERROR_COLOR = "ff8c00"; this.LEVEL_FATAL_COLOR = "ff0000"; /** * logLevel determines the minimum message level the instance will show.(需要显示的最小错误级别,默认为 3) */ this.logLevel = 3; /** * targetDIV is the DIV object to output to. */ this.targetDiv = null; /** * This function is used to set the minimum level a log instance will show. *(在这里定义需要显示的最小错误级别) * @param inLevel One of the level constants. Any message at this level * or a higher level will be displayed, others will not. */ this.setLevel = function(inLevel) { this.logLevel = inLevel; } // End setLevel(). /** * This function is used to set the target DIV that all messages are * written to. Note that when you call this, the DIV's existing contents * are cleared out.(设置信息显示的 DIV,调用此函数的时候,原有的信息将被清除) * * @param inTargetDiv The DIV object that all messages are written to. */ this.setTargetDiv = function(inTargetDiv) { this.targetDiv = inTargetDiv; this.targetDiv.innerHTML = ""; } // End setTargetDiv(). /** * This function is called to determine if a particular message meets or * exceeds the current level of the log instance and should therefore be * logged.(此函数用来判定现有的错误级别是否应该被显示) * * @param inLevel The level of the message being checked. */ this.shouldBeLogged = function(inLevel) { if (inLevel >= this.logLevel) { return true; } else { return false; } } // End shouldBeLogged(). /** * This function logs messages at TRACE level. *(格式化显示 TRACE 的错误级别信息,往依此类推) * @param inMessage The message to log. */ this.trace = function(inMessage) { if (this.shouldBeLogged(this.LEVEL_TRACE) && this.targetDiv) { this.targetDiv.innerHTML += "<div style='color:#" + this.LEVEL_TRACE_COLOR + ";'>" + "[TRACE] " + inMessage + "</div>"; } } // End trace(). /** * This function logs messages at DEBUG level. * * @param inMessage The message to log. */ this.debug = function(inMessage) { if (this.shouldBeLogged(this.LEVEL_DEBUG) && this.targetDiv) { this.targetDiv.innerHTML += "<div style='color:#" + this.LEVEL_DEBUG_COLOR + ";'>" + "[DEBUG] " + inMessage + "</div>"; } } // End debug(). /** * This function logs messages at INFO level. * * @param inMessage The message to log. */ this.info = function(inMessage) { if (this.shouldBeLogged(this.LEVEL_INFO) && this.targetDiv) { this.targetDiv.innerHTML += "<div style='color:#" + this.LEVEL_INFO_COLOR + ";'>" + "[INFO] " + inMessage + "</div>"; } } // End info(). /** * This function logs messages at WARN level. * * @param inMessage The message to log. */ this.warn = function(inMessage) { if (this.shouldBeLogged(this.LEVEL_WARN) && this.targetDiv) { this.targetDiv.innerHTML += "<div style='color:#" + this.LEVEL_WARN_COLOR + ";'>" + "[WARN] " + inMessage + "</div>"; } } // End warn(). /** * This function logs messages at ERROR level. * * @param inMessage The message to log. */ this.error = function(inMessage) { if (this.shouldBeLogged(this.LEVEL_ERROR) && this.targetDiv) { this.targetDiv.innerHTML += "<div style='color:#" + this.LEVEL_ERROR_COLOR + ";'>" + "[ERROR] " + inMessage + "</div>"; } } // End error(). /** * This function logs messages at FATAL level. * * @param inMessage The message to log. */ this.fatal = function(inMessage) { if (this.shouldBeLogged(this.LEVEL_FATAL) && this.targetDiv) { this.targetDiv.innerHTML += "<div style='color:#" + this.LEVEL_FATAL_COLOR + ";'>" + "[FATAL] " + inMessage + "</div>"; } } // End fatal(). } // End DivLogger().
源码看完后,我们来测试一下这个“小包”,来看下面的测试源码:
<div id="jscript_debug_div" style="font-family:arial; font-size:10pt; font-weight:bold; display:none; background-color:#ffffe0; padding:4px;"> <a href="javascript:void(0);" id="enumPropsLink" onClick="jscript.debug.enumProps(document.getElementById('enumPropsLink'));"> enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) </a> <br><br> <div id="divLog" style="font-family:arial; font-size: 12pt; padding: 4px; background-color:#ffffff; border:1px solid #000000; 50%; height:300px; overflow:scroll;">Log message will appear here</div> <script> var log = new jscript.debug.DivLogger(); log.setTargetDiv(document.getElementById("divLog")); log.setLevel(log.LEVEL_DEBUG); </script> <br> <a href="javascript:void(0);" onClick="log.trace('Were tracing along now');"> DivLogger.log.trace() - Try to add a TRACE message to the above DIV (won't work because it's below the specified DEBUG level); </a><br> <a href="javascript:void(0);" onClick="log.debug('Hmm, lets do some debugging');"> DivLogger.log.debug() - Try to add a DEBUG message to the above DIV </a><br> <a href="javascript:void(0);" onClick="log.info('Just for your information');"> DivLogger.log.info() - Add a INFO message to the above DIV </a><br> <a href="javascript:void(0);" onClick="log.warn('Warning! Danger Will Robinson!');"> DivLogger.log.warn() - Add a WARN message to the above DIV </a><br> <a href="javascript:void(0);" onClick="log.error('Dave, there is an error in the AE-35 module');"> DivLogger.log.error() - Add a ERROR message to the above DIV </a><br> <a href="javascript:void(0);" onClick="log.fatal('Game over man, game over!!');"> DivLogger.log.fatal() - Add a FATAL message to the above DIV </a><br> <br><br> </div>
上面的测试代码里面的 <script> 段进行了 debug 的实例化,设置了显示信息的 DIV,而且设置了显示信息的最小级别为:LEVEL_DEBUG:
var log = new jscript.debug.DivLogger(); log.setTargetDiv(document.getElementById("divLog")); log.setLevel(log.LEVEL_DEBUG);
来看看效果如何呢:
enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值)
DivLogger.log.trace() - Try to add a TRACE message to the above DIV (won't work because it's below the specified DEBUG level);
DivLogger.log.debug() - Try to add a DEBUG message to the above DIV
DivLogger.log.info() - Add a INFO message to the above DIV
DivLogger.log.warn() - Add a WARN message to the above DIV
DivLogger.log.error() - Add a ERROR message to the above DIV
DivLogger.log.fatal() - Add a FATAL message to the above DIV
Log message will appear here
DivLogger.log.trace() - Try to add a TRACE message to the above DIV (won't work because it's below the specified DEBUG level);
DivLogger.log.debug() - Try to add a DEBUG message to the above DIV
DivLogger.log.info() - Add a INFO message to the above DIV
DivLogger.log.warn() - Add a WARN message to the above DIV
DivLogger.log.error() - Add a ERROR message to the above DIV
DivLogger.log.fatal() - Add a FATAL message to the above DIV
在点击“enumProps()-Shows all ……”(第一个 link )的时候浏览器弹出的框如下图所示(Opera),详细地列出了你所点击的 a 标签对象的所有属性及值:
其中的信息很多,在别的浏览器下可能显示不全,信息代码摘录如下:(Opera 下)
accessKey = all = [object HTMLCollection] attributes = [object NamedNodeMap] baseURI = http://localhost/Javascript/Chapter03_package/packagesTest_main.htm?param1=test1¶m2=test2 charset = childElementCount = 0 childNodes = [object NodeList] children = [object HTMLCollection] className = clientHeight = 0 clientLeft = 0 clientTop = 0 clientWidth = 543 contentEditable = inherit coords = currentStyle = [object CSSStyleDeclaration] dir = document = [object HTMLDocument] firstChild = [object Text] firstElementChild = null hash = host = hostname = href = javascript:void(0); hreflang = id = enumPropsLink innerHTML = enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) innerText = enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) isContentEditable = false lang = lastChild = [object Text] lastElementChild = null localName = A name = namespaceURI = null nextElementSibling = [object HTMLBRElement] nextSibling = [object Text] nodeName = A nodeType = 1 nodeValue = null offsetHeight = 16 offsetLeft = 9 offsetParent = [object HTMLBodyElement] offsetTop = 300 offsetWidth = 543 outerHTML = <a href="javascript:void(0);" id="enumPropsLink" onclick="jscript.debug.enumProps(document.getElementById('enumPropsLink'));"> enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) </a> outerText = enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) ownerDocument = [object HTMLDocument] parentElement = [object HTMLDivElement] parentNode = [object HTMLDivElement] pathname = void(0); port = prefix = null previousElementSibling = null previousSibling = [object Text] protocol = javascript: rel = rev = scrollHeight = 16 scrollLeft = 0 scrollTop = 0 scrollWidth = 543 search = shape = sourceIndex = 50 spellcheck = true style = [object CSSStyleDeclaration] tabIndex = 0 tagName = A target = text = enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) textContent = enumProps()-Shows all the properties of this link(显示此链接标签对象的所有属性和值) title = type = unselectable = onclick = function anonymous(event) { jscript.debug.enumProps(document.getElementById('enumPropsLink')); } onmousedown = null onmouseup = null onmouseover = null onmousemove = null onmouseout = null onkeypress = null onkeydown = null onkeyup = null onload = null onunload = null onfocus = null onblur = null ondblclick = null oncontextmenu = null onloadstart = null onprogress = null onsuspend = null onstalled = null onloadend = null onemptied = null onplay = null onpause = null onloadedmetadata = null onloadeddata = null onwaiting = null onplaying = null onseeking = null onseeked = null ontimeupdate = null onended = null oncanplay = null oncanplaythrough = null onratechange = null ondurationchange = null onvolumechange = null focus = function focus() { [native code] } blur = function blur() { [native code] } toString = function toString() { [native code] } removeNode = function removeNode() { [native code] } click = function click() { [native code] } insertAdjacentElement = function insertAdjacentElement() { [native code] } insertAdjacentHTML = function insertAdjacentHTML() { [native code] } insertAdjacentText = function insertAdjacentText() { [native code] } removeAttributeNode = function removeAttributeNode() { [native code] } contains = function contains() { [native code] } scrollIntoView = function scrollIntoView() { [native code] } getBoundingClientRect = function getBoundingClientRect() { [native code] } getClientRects = function getClientRects() { [native code] } getAttribute = function getAttribute() { [native code] } getAttributeNS = function getAttributeNS() { [native code] } hasAttribute = function hasAttribute() { [native code] } hasAttributeNS = function hasAttributeNS() { [native code] } setAttribute = function setAttribute() { [native code] } setAttributeNS = function setAttributeNS() { [native code] } removeAttribute = function removeAttribute() { [native code] } removeAttributeNS = function removeAttributeNS() { [native code] } getAttributeNode = function getAttributeNode() { [native code] } getAttributeNodeNS = function getAttributeNodeNS() { [native code] } setAttributeNode = function setAttributeNode() { [native code] } setAttributeNodeNS = function setAttributeNodeNS() { [native code] } getElementsByTagName = function getElementsByTagName() { [native code] } getElementsByTagNameNS = function getElementsByTagNameNS() { [native code] } getElementsByClassName = function getElementsByClassName() { [native code] } querySelector = function querySelector() { [native code] } querySelectorAll = function querySelectorAll() { [native code] } dispatchEvent = function dispatchEvent() { [native code] } insertBefore = function insertBefore() { [native code] } replaceChild = function replaceChild() { [native code] } removeChild = function removeChild() { [native code] } appendChild = function appendChild() { [native code] } hasChildNodes = function hasChildNodes() { [native code] } cloneNode = function cloneNode() { [native code] } normalize = function normalize() { [native code] } isSupported = function isSupported() { [native code] } hasAttributes = function hasAttributes() { [native code] } isSameNode = function isSameNode() { [native code] } isEqualNode = function isEqualNode() { [native code] } getFeature = function getFeature() { [native code] } compareDocumentPosition = function compareDocumentPosition() { [native code] } addEventListener = function addEventListener() { [native code] } removeEventListener = function removeEventListener() { [native code] } lookupPrefix = function lookupPrefix() { [native code] } isDefaultNamespace = function isDefaultNamespace() { [native code] } lookupNamespaceURI = function lookupNamespaceURI() { [native code] } selectNodes = function selectNodes() { [native code] } selectSingleNode = function selectSingleNode() { [native code] } ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 TEXT_NODE = 3 CDATA_SECTION_NODE = 4 ENTITY_REFERENCE_NODE = 5 ENTITY_NODE = 6 PROCESSING_INSTRUCTION_NODE = 7 COMMENT_NODE = 8 DOCUMENT_NODE = 9 DOCUMENT_TYPE_NODE = 10 DOCUMENT_FRAGMENT_NODE = 11 NOTATION_NODE = 12 DOCUMENT_POSITION_DISCONNECTED = 1 DOCUMENT_POSITION_PRECEDING = 2 DOCUMENT_POSITION_FOLLOWING = 4 DOCUMENT_POSITION_CONTAINS = 8 DOCUMENT_POSITION_CONTAINED_BY = 16 DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32
由于浏览器的不同,显示的信息会有差别。