这时,我们再去元素审查,修改样式代码, 发现样式改了, 浏览器文件系统中的样式代码改了, 编辑器中的样式代码也改了, 我们的需求到现在基本完成了, 但是如果再次修改,我们会发现右下角的文件系统里的样式文件出现了问号,说明现在是socket不通的状态, 并且编辑器中的代码是没有再次进行更改的。 其实这个问题是浏览器本身不支持这样多次更改, 产生 css 缓存后, 就不再进行热更新了, 禁掉缓存后也没有用, 但是我们尝试每次修改后, 强制刷新页面,在进行修改,发现是可以保证每次修改都生效的。
但是这样还要每次手动刷新还是不方便, 那么怎么解决这个问题呢, 其实只需要在每次热更新后, 我们调用一下浏览器的强制刷新即可, 我们在元素审查html文件中查看,会发现浏览器偷偷给我们添加了一段脚本。
我们把这段脚本拿下来看
// <![CDATA[ <-- For SVG support if ("WebSocket" in window) { (function () { function refreshCSS() { var sheets = [].slice.call(document.getElementsByTagName("link")); var head = document.getElementsByTagName("head")[0]; for (var i = 0; i < sheets.length; ++i) { var elem = sheets[i]; var parent = elem.parentElement || head; parent.removeChild(elem); var rel = elem.rel; if ( (elem.href && typeof rel != "string") || rel.length == 0 || rel.toLowerCase() == "stylesheet" ) { var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, ""); elem.href = url + (url.indexOf("?") >= 0 ? "&" : "?") + "_cacheOverride=" + new Date().valueOf(); } parent.appendChild(elem); } } var protocol = window.location.protocol === "http:" ? "ws://" : "wss://"; var address = protocol + window.location.host + window.location.pathname + "/ws"; var socket = new WebSocket(address); socket.onmessage = function (msg) { if (msg.data == "reload") window.location.reload(); else if (msg.data == "refreshcss") refreshCSS(); }; if ( sessionStorage && !sessionStorage.getItem("IsThisFirstTime_Log_From_LiveServer") ) { console.log("Live reload enabled."); sessionStorage.setItem("IsThisFirstTime_Log_From_LiveServer", true); } })(); } else { console.error( "Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading." ); } // ]]>
从这段脚本中,就可以大致知道浏览器的元素样式修改后, 为什么加载到最新的修改样式后的代码, 其实就是浏览器修改元素样式后,会发出socket消息, 我们在脚本中就能监听到样式更改的消息, 然后把样式文件饮用的地址后面修改一下时间戳防止缓存, 重新发送样式文件请求,获取最新样式代码, 那么我们既然找到了这个更新时机,那么其实只需要在更新是,增加一个刷新浏览器的操作即可
代码片段如下
//... socket.onmessage = function (msg) { if (msg.data == "reload") window.location.reload(); else if (msg.data == "refreshcss") { refreshCSS(); setTimeout(() => { window.location.reload(); }, 500); } }; //...
这时我们就完整的完成了从 审查元素 > 修改样式 > 代码更改成功 的完整链路, 也大体理清了,浏览器的webwork功能。
3、总结
我们经常用浏览器的源代码面板, 但是文件系统一直在旁边,从来没看关注过, 当我们使用起来才发现,原来chrome是支持代码编辑器功能的,进而我们想到了,能不能直接通过样式审查修改样式的时候,实时更新本地的样式代码,不用再像之前调好后复制在通过类找到代码,在修改保存,再回来刷新检查生没生效。 我们发现是可行的, 我们在启动静态服务时,浏览器会通过socket消息与我们本地的代码进行通讯, 会监听到样式更改后,通过refashCSS修改我们html 中 head 里的样式文件的引用,增加时间戳,防止缓存, 但是不支持多次修改,更新, 我们通过修改浏览器注入的脚本,增加了reload ,达到了最终的。无限修改样式也可以同步更新到本地代码。
4、完整代码
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <link rel="stylesheet" href="./index.css" /> <body> <div class="box">hello world</div> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> </body> <script> // <![CDATA[ <-- For SVG support if ("WebSocket" in window) { (function () { function refreshCSS() { var sheets = [].slice.call(document.getElementsByTagName("link")); var head = document.getElementsByTagName("head")[0]; for (var i = 0; i < sheets.length; ++i) { var elem = sheets[i]; var parent = elem.parentElement || head; parent.removeChild(elem); var rel = elem.rel; if ( (elem.href && typeof rel != "string") || rel.length == 0 || rel.toLowerCase() == "stylesheet" ) { var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, ""); elem.href = url + (url.indexOf("?") >= 0 ? "&" : "?") + "_cacheOverride=" + new Date().valueOf(); } parent.appendChild(elem); } } var protocol = window.location.protocol === "http:" ? "ws://" : "wss://"; var address = protocol + window.location.host + window.location.pathname + "/ws"; var socket = new WebSocket(address); socket.onmessage = function (msg) { if (msg.data == "reload") window.location.reload(); else if (msg.data == "refreshcss") { refreshCSS(); setTimeout(() => { window.location.reload(); }, 500); } }; if ( sessionStorage && !sessionStorage.getItem("IsThisFirstTime_Log_From_LiveServer") ) { console.log("Live reload enabled."); sessionStorage.setItem("IsThisFirstTime_Log_From_LiveServer", true); } })(); } else { console.error( "Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading." ); } // ]]> </script> </html>
index.css
.box { width: 300px; height: 400px; background-color: #5826ea; color: #a73751; font-size: 30px; } ul li { color: #ff0090; font-size: 20px; }