├── README.md ├── doc └── README.md ├── images └── example-demo.jpg ├── lib └── autoDevTool.js ├── package.json └── test └── index.html /README.md: -------------------------------------------------------------------------------- 1 | ![npm_version](https://img.shields.io/npm/v/auto_dev_tool.svg)[![Travis](https://img.shields.io/travis/rust-lang/rust.svg)](https://github.com/chokcoco/autoDevTools)![License](https://img.shields.io/npm/l/express.svg) 2 | 3 | #### [NPM -- autoDevTools](https://www.npmjs.com/package/auto_dev_tool) 4 | 5 | # autoDevTools 6 | 7 | 移动端控制台插件,解决移动端无法看到打印的 log ,上线后亦可使用,用于快速定位问题。 8 | 9 | 10 | ## Install 11 | 12 | ``` 13 | $ npm install auto_dev_tool --save-dev 14 | ``` 15 | 16 | 或者页面直接加载 autoDevTools.js,同时 autoDevTools.js 也支持 AMD 或 CMD 规范。 17 | 18 | ## Usage 19 | 20 | ```HTML 21 | 22 | 26 | ``` 27 | 28 | 29 | ### AMD: 30 | ```HTML 31 | 32 | 38 | ``` 39 | 40 | ## API 41 | 42 | - `log`:定义需要输出的日志。 43 | ```javascript 44 |  var devTool = new autoDevTool(); 45 | devTool.init(); 46 | 47 |  var name = "自定义日志title"; 48 | var data = { 49 | value:"" 50 | } 51 | 52 | devTool.log(name, data); 53 | ``` 54 | 适用如下场景: 55 | 56 | #### 普通变量输出 57 | 58 | ```javascript 59 | var a = 10; 60 | devTool.log("a", a); 61 | ``` 62 | 63 | #### error输出 64 | ```javascript 65 | try{ 66 | ... 67 | }catch(error) { 68 | devTool.log("error", error); 69 | } 70 | ``` 71 | 72 | #### json对象输出 73 | ```javascript 74 | var json = { 75 |  a: "dev", 76 | b: "tool" 77 | } 78 | devTool.log("json", json); 79 | ``` 80 | ## How to open 81 | 82 | 三指双击屏幕两次(间隔小于1s),可以唤出控制台。 83 | 84 | ![](https://github.com/chokcoco/autoDevTools/blob/master/images/example-demo.jpg) 85 | 86 | ## Update 87 | 88 | + 为保证性能,不污染 DOM 结构,控制台隐藏状态下,日志不会输出,要看到完整日志可以呼出控制台之后,点击刷新。此刷新功能页面刷新时控制台默认打开 89 | 90 | + 为保证页面所有操作都可以进行,提供控制台定位控制,如果控制台挡住了页面下方的某些交互按钮,可以点击上移按钮 91 | 92 | + 增加暂停、输出按钮,可以暂停日志打印,高频日志打印状态下,可以暂停观看日志; 93 | 94 | ## MIT 95 | 96 | License 97 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | # autoDevTools![npm_version](https://img.shields.io/npm/v/auto_dev_tool.svg) 2 | 3 | 移动端控制台插件,解决移动端无法看到打印的 log,上线后亦可使用,用于快速定位问题。 4 | 5 | ## 使用方法 6 | 7 | ### 初始化安装 8 | 9 | 使用 npm 安装包: 10 | 11 | `npm install auto_dev_tool --save-dev` 12 | 13 | 或者页面直接加载 autoDevTools.js,同时 autoDevTools.js 也支持 AMD 或 CMD 。 14 | 15 | ```HTML 16 | 17 | 21 | ``` 22 | 23 | #### AMD: 24 | ```HTML 25 | 26 | 32 | ``` 33 | ## 接口调用 34 | + `log`:定义需要输出的日志。 35 | ```javascript 36 |  var devTool = new autoDevTool(); 37 | devTool.init(); 38 | 39 |  var name = "自定义日志title"; 40 | var data = { 41 | value:"" 42 | } 43 | 44 | devTool.log(name, data); 45 | ``` 46 | 适用如下场景: 47 | #### 普通变量输出 48 | 49 | ```javascript 50 | var a = 10; 51 | devTool.log("a", a); 52 | ``` 53 | 54 | #### error输出 55 | ```javascript 56 | try{ 57 | ... 58 | }catch(error) { 59 | devTool.log("error", error); 60 | } 61 | ``` 62 | 63 | #### json对象输出 64 | ```javascript 65 | var json = { 66 |  a: "dev", 67 | b: "tool" 68 | } 69 | devTool.log("json", json); 70 | ``` 71 | ## 控制调试台唤出方法: 72 | 73 | 三指双击屏幕两次(间隔小于1s),可以唤出控制台。 74 | 75 | ![](https://github.com/chokcoco/autoDevTools/blob/master/images/example-demo.jpg) 76 | 77 | ## 优化 78 | 79 | + 为保证性能,不污染 DOM 结构,控制台隐藏状态下,日志不会输出,要看到完整日志可以呼出控制台之后,点击刷新。此刷新功能页面刷新时控制台默认打开 80 | 81 | + 为保证页面所有操作都可以进行,提供控制台定位控制,如果控制台挡住了页面下方的某些交互按钮,可以点击上移按钮 82 | 83 | + 增加暂停、输出按钮,可以暂停日志打印,高频日志打印状态下,可以暂停观看日志; 84 | 85 | ## MIT 86 | 87 | License 88 | -------------------------------------------------------------------------------- /images/example-demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chokcoco/autoDevTools/6ac1e3fae149bfbab9026fb8e4edf4a1ac02b9d1/images/example-demo.jpg -------------------------------------------------------------------------------- /lib/autoDevTool.js: -------------------------------------------------------------------------------- 1 | /** 2 | * autoDevTool v1.1.0 3 | * By Coco 4 | * Github: https://github.com/chokcoco/autoDevTools 5 | * 6 | * @License MIT 7 | */ 8 | (function(name, definition) { 9 | // 检测上下文环境是否为 AMD 或者 CMD 10 | if (typeof define === 'function') { 11 | define(definition); 12 | // 定义为普通 node 模块 13 | }else if(typeof module !== 'undefined' && module.exports) { 14 | module.exports = definition(); 15 | // 将模块的执行结果挂载在 window 变量中,在浏览器中 this 指向 window 对象 16 | } else { 17 | this[name] = definition(); 18 | } 19 | })('autoDevTool', function() { 20 | 21 | function autoDevTool() { 22 | this._version = '1.1.0'; 23 | this._times = 1; 24 | this._lastTapTime = null; 25 | this._container = null; 26 | this._isShow = false; 27 | this._position = true; 28 | this._isPause = false; 29 | 30 | this._logContainer = null; 31 | 32 | this._btnFilter = null; 33 | this._btnClear = null; 34 | this._btnRefresh = null; 35 | this._btnSwitch = null; 36 | this._btnPause = null; 37 | this._closeBtn = null; 38 | } 39 | 40 | /** 41 | * 创建记录遮罩 42 | * @return {} 43 | */ 44 | autoDevTool.prototype._createWrap = function() { 45 | var body = document.getElementsByTagName('body')[0]; 46 | 47 | this._container = document.createElement('div'); 48 | this._container.setAttribute('id', 'dev-tool'); 49 | this._container.style.cssText = "display:none;position:fixed;top:70%;bottom:0;left:0;width:100%;box-sizing:border-box;background:rgba(255,255,255,.9);z-index:9999;border:1px solid #ddd;" 50 | 51 | var navDom = '' 60 | +'
' 61 | +'
' 62 | +'
'; 63 | body.appendChild(this._container); 64 | 65 | this._container.innerHTML = navDom; 66 | 67 | this._logContainer = document.getElementById('autoDev-log'); 68 | this._btnClear = document.getElementById('autoDev-clear'); 69 | this._btnRefresh = document.getElementById('autoDev-refresh'); 70 | this._btnFilter = document.querySelectorAll('.autoDev-filter'); 71 | this._btnSwitch = document.getElementById('btn-devtool-switch'); 72 | this._btnPause = document.getElementById('btn-devtool-pause'); 73 | this._closeBtn = document.getElementById('autoDev-close'); 74 | } 75 | 76 | /** 77 | * 初始化检测 URL ,查看是否开启控制台,查看控制台位置 78 | * @return {} 79 | */ 80 | autoDevTool.prototype._checkInit = function() { 81 | var url = location.href; 82 | 83 | if (getCookie("isKeepTool") == 1) { 84 | this._show(); 85 | setCookie("isKeepTool", 0, 1); 86 | } 87 | 88 | if(getCookie("positionLocation") == 1) { 89 | this._positionBottom(); 90 | }else { 91 | this._positionTop(); 92 | } 93 | } 94 | 95 | /** 96 | * 遮罩层显示 97 | * @return {} 98 | */ 99 | autoDevTool.prototype._show = function() { 100 | this._container.style.display = "block"; 101 | this._isShow = true; 102 | } 103 | 104 | /** 105 | * 遮罩层关闭 106 | * @return {} 107 | */ 108 | autoDevTool.prototype._hide = function() { 109 | this._container.style.display = "none"; 110 | this._isShow = false; 111 | this._clear(); 112 | } 113 | 114 | /** 115 | * 日志内容清空 116 | * @return {} 117 | */ 118 | autoDevTool.prototype._clear = function() { 119 | this._logContainer.innerHTML = ""; 120 | } 121 | 122 | /** 123 | * 日志容器默认滚动到底部 124 | * @return {} 125 | */ 126 | autoDevTool.prototype._scrollTop = function() { 127 | this._logContainer.scrollTop = this._logContainer.scrollHeight; 128 | } 129 | 130 | /** 131 | * 默认定位在下方 132 | * @return {} 133 | */ 134 | autoDevTool.prototype._positionBottom = function() { 135 | this._container.style.top = "70%"; 136 | this._container.style.bottom = "0"; 137 | this._position = !this._position; 138 | 139 | this._btnSwitch.innerHTML = "↑"; 140 | } 141 | 142 | /** 143 | * 默认定位在上方 144 | * @return {} 145 | */ 146 | autoDevTool.prototype._positionTop = function() { 147 | this._container.style.top = "0"; 148 | this._container.style.bottom = "70%"; 149 | this._position = !this._position; 150 | 151 | this._btnSwitch.innerHTML = "↓"; 152 | } 153 | 154 | /** 155 | * 事件绑定 156 | * @return {} 157 | */ 158 | autoDevTool.prototype._eventBind = function() { 159 | var me = this; 160 | 161 | // 三指连点两次打开调试台 162 | window.addEventListener("touchend", function(e) { 163 | var nowTime = new Date(); 164 | var touches = e.touches.length; 165 | 166 | if (me._times === 1) { 167 | me._times++; 168 | me._lastTapTime = nowTime; 169 | 170 | setTimeout(function() { 171 | me._times = 1; 172 | }, 1000); 173 | return; 174 | } 175 | 176 | if (touches === 2 && me._times === 2 && (nowTime - me._lastTapTime < 1000)) { 177 | if (me._container.style.display == "none") { 178 | me._show(); 179 | } else { 180 | me._hide(); 181 | } 182 | 183 | me._times = 1; 184 | } 185 | }); 186 | 187 | // 清空按钮 188 | this._btnClear.addEventListener("click", function(e) { 189 | me._clear(); 190 | }); 191 | 192 | // 刷新按钮,保存控制台打开状态 193 | this._btnRefresh.addEventListener("click", function(e) { 194 | var url = location.href; 195 | 196 | setCookie("isKeepTool", "1", 1); 197 | 198 | location.href = url; 199 | }); 200 | 201 | // 关闭按钮 202 | this._closeBtn.addEventListener("click", function(e) { 203 | me._hide(); 204 | }); 205 | 206 | // 定位切换按钮 207 | this._btnSwitch.addEventListener("click", function(e) { 208 | if(me._position) { 209 | me._positionTop(); 210 | setCookie("positionLocation", "0", 24); 211 | } else { 212 | me._positionBottom(); 213 | setCookie("positionLocation", "1", 24); 214 | } 215 | }) 216 | 217 | // 暂停|播放按钮 218 | this._btnPause.addEventListener("click", function(e) { 219 | me._isPause = !me._isPause; 220 | me._btnPause.innerText = me._isPause ? "播" : "停"; 221 | 222 | this.style.backgroundColor = me._isPause ? "rgba(139,195,74,.6)" : "rgba(244,67,54,.6)"; 223 | }) 224 | 225 | var length = this._btnFilter.length; 226 | 227 | for (var i = 0; i < length; i++) { 228 | var navLi = this._btnFilter[i]; 229 | 230 | navLi.addEventListener("click", function(e) { 231 | var target = e.target; 232 | var id = target.getAttribute('id'); 233 | var logs = me._logContainer.querySelectorAll('p'); 234 | var logLength = logs.length; 235 | 236 | var idMapClass = { 237 | "autoDev-info": "autoDev-log-info", 238 | "autoDev-json": "autoDev-log-json", 239 | "autoDev-error": "autoDev-log-error" 240 | }; 241 | 242 | for (var j = 0; j < logLength; j++) { 243 | var elem = logs[j]; 244 | 245 | if (id === "autoDev-all") { 246 | elem.style.display = "block"; 247 | } else { 248 | if (idMapClass[id] === elem.getAttribute("class")) { 249 | elem.style.display = "block"; 250 | } else { 251 | elem.style.display = "none"; 252 | } 253 | } 254 | } 255 | }); 256 | } 257 | } 258 | 259 | /** 260 | * 打印 log 261 | * @param {Number} type 1 - 非object对象,2 - JSON对象或普通对象, 3 - Error对象 262 | * @param {String} name 输出名字 263 | * @param {String} data 输出数据 264 | * @return {} 265 | */ 266 | autoDevTool.prototype._log = function(type, name, data) { 267 | if(!this._isShow || this._isPause) { 268 | return; 269 | } 270 | 271 | var p = document.createElement('p'); 272 | var date = new Date(); 273 | var curTime = date.getHours() + ':' + date.getSeconds(); 274 | var timeString = "[" + curTime + "]"; 275 | var logType = ""; 276 | var typeArr = ["", "autoDev-log-info", "autoDev-log-json", "autoDev-log-error"]; 277 | var value = data !== undefined ? (":" + data) : ""; 278 | 279 | switch (true) { 280 | case type === 1: 281 | logType = "[Info] "; 282 | break; 283 | case type === 2: 284 | logType = "[Json] "; 285 | break; 286 | case type === 3: 287 | logType = "[Error] "; 288 | break; 289 | } 290 | 291 | p.style.cssText = "font-size:14px;line-height:24px;color:#333;margin-bottom:0px;border-bottom:1px solid rgba(0,0,0,.2);word-break:break-all;" 292 | p.setAttribute('class', typeArr[type]); 293 | p.innerHTML = timeString + logType + "" + name + "" + value; 294 | 295 | this._logContainer.appendChild(p); 296 | 297 | this._scrollTop(); 298 | } 299 | 300 | /** 301 | * 打印 log 接口 302 | * @param {String} name 输出名字 303 | * @param {String | JSON} data 304 | * @return {} 305 | */ 306 | autoDevTool.prototype.log = function(name, data) { 307 | var type = Object.prototype.toString.call(data || name); 308 | 309 | switch (true) { 310 | case type === "[object Object]": 311 | this._log(2, name, JSON.stringify(data)); 312 | break; 313 | case type === "[object Error]": 314 | this._log(3, name, data); 315 | break; 316 | default: 317 | this._log(1, name, data); 318 | } 319 | } 320 | 321 | /** 322 | * 设置 Cookie 值 323 | * @return {} 324 | */ 325 | function setCookie(name, value, Hours) { 326 | var d = new Date(), 327 | offset = 8, 328 | utc = d.getTime() + (d.getTimezoneOffset() * 60000), 329 | nd = utc + (3600000 * offset), 330 | exp = new Date(nd); 331 | 332 | exp.setTime(exp.getTime() + Hours * 60 * 60 * 1000); 333 | document.cookie = name + "=" + decodeURIComponent(value) + ";path=/;expires=" + exp.toGMTString() + ";"; 334 | } 335 | 336 | /** 337 | * 获取 cookie 值 338 | * @return {} 339 | */ 340 | function getCookie(name) { 341 | var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)")); 342 | if (arr != null) return encodeURIComponent(arr[2]); 343 | return null; 344 | } 345 | 346 | /** 347 | * 初始化方法 348 | * @return {} 349 | */ 350 | autoDevTool.prototype.init = function() { 351 | this._createWrap(); 352 | this._checkInit(); 353 | this._eventBind(); 354 | } 355 | 356 | /** 357 | * export 358 | */ 359 | return autoDevTool; 360 | }); 361 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "auto_dev_tool", 3 | "version": "1.1.0", 4 | "description": "A development debugging tool for mobile application. ", 5 | "main": "", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/chokcoco/autoDevTools.git" 12 | }, 13 | "keywords": [ 14 | "a", 15 | "mobile", 16 | "development", 17 | "debugging", 18 | "tool" 19 | ], 20 | "author": "Coco", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/chokcoco/autoDevTools/issues" 24 | }, 25 | "homepage": "https://github.com/chokcoco/autoDevTools" 26 | } 27 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 移动端自动化调试工具 6 | 7 | 24 | 25 | 26 |
27 |

移动端自动化调试工具 -- autoDevTool

28 |

A mobile development debugging tool

29 |

移动端调试插件,上线亦可使用,三指双击呼出

30 |

初始化方法:

31 |

页面直接加载 autoDevTools.js,同时 autoDevTools.js 也支持 AMD 或 CMD 规范。

32 |

控制调试台唤出方法:

33 |

三指双击屏幕两次(间隔小于1s),可以唤出日志控制台。

34 |

接口调用:

35 |

log:定义需要输出的日志

36 |

适用场景:

37 | 42 |
43 | 44 | 88 | 89 | 90 | --------------------------------------------------------------------------------