// A few functions with some calls between them var obj = { someCoolFunction: function () { // Do some action }, anotherFunction: function () { // Do some action }, thirdFunction: function () { // Do some action obj.anotherFunction(); }, fourthFunction: function () { // Call anotherFunction and someFunction obj.anotherFunction(); obj.someCoolFunction(); }, allFunction: function (e) { obj.someCoolFunction(e); obj.anotherFunction(e); obj.thirdFunction(e); obj.fourthFunction(e); } } function WrapFunctions() { // Run over all objects in the obj for (fnc in obj) { if (typeof obj[fnc] == "function") { var currentelement = $("#debuglog"); (function (originalFnc, name) { // Redefine the function obj[fnc] = function () { // Write the function name in an LI and nest // deeper function calls in a UL var fncItem = $("<li>Called " + name + "</li>") var newparent = $("<ul></ul>"); currentelement.append(fncItem.append(newparent)); var olditem = currentelement; currentelement = newparent; // Call the original function originalFnc.call(this, arguments); // Reset the current container currentelement = olditem; }; })(obj[fnc], fnc); // Pass in the original function and its name } } }WrapFunctions(); $("#btnAction1").click(obj.someCoolFunction); $("#btnAction2").click(obj.anotherFunction); $("#btnAction3").click(obj.thirdFunction); $("#btnActionAll").click(obj.allFunction);
Click the buttons to see the call stack viewer in action<br /> <input type="button" value="Do Action 1" id="btnAction1" /> <input type="button" value="Do Action 2" id="btnAction2" /> <input type="button" value="Do Action 3" id="btnAction3" /> <input type="button" value="Do All Actions" id="btnActionAll" /> <ul id="debuglog"></ul>
#debuglog{ width: 300px; position: absolute; z-index: 1001; right: 10px; top: 20px; box-shadow: 3px 3px 15px 3px #000; width: 312px; padding: 10px; height: 400px; overflow: auto; } #resultItems ul{ margin-top: 0px; padding-left: 10px; margin-bottom: 0; } #resultItems li{ list-style-type: none; cursor: pointer; }