两个相见恨晚的 Chrome devtool 开发技巧(一)

前言

前段时间给公司分享前端技术, 因为部门中不光是前端,还有后端、数据。 所以选择了分享 浏览器 相关的, 这个不光前端每天在用,研发人员日常也都离不开使用浏览器。 在准备过程中,学习到了两个让我很惊喜的开发技巧,顿感多年前端白干,相见恨晚, 今天先分享浏览器的 workspaces 功能, 完成一个面向浏览器编程, 无限修改浏览器中的样式,即可修改本地代码中样式的功能

1、 源代码面板的 Workspaces

提到源代码管理面板, 大家想到的肯定都是打断点,进行源码调试的地方, 实际上这里的功能远不止于此。 这里浏览器其实还给内置了文件系统, 可以让我们在浏览器中编辑代码,改页面的同时更改本地代码,这不就是面向浏览器编程吗。

Workspaces是什么: 工作区(Workspaces)是源代码管理面板中的一个概念,它提供了一种组织和管理项目代码的方式。一个工作区可以包含一个或多个相关的代码仓库,并帮助团队协作、版本控制和代码审查。

2、 常用的开发模式

讲这个之前,先简单回顾一下,我们之前的开发、包括学习css及html的时候,是不是都是左边一个编辑器,右边一个浏览器,在浏览器的元素审查中,找到元素,对元素进行样式调整后,在复制到编辑器中, 保存,然后回到页面来刷新。(应该不会还有人连浏览器上可以调整完代码,再复制到编辑器吧~)

我们先上一个图,演示一下之前的模式, 上一个最简单的html、css代码

演示如下

output.gif

代码如下

<style>
    .box {
      width: 100px;
      height: 300px;
      background-color: aqua;
      color: blue;
    }

    ul {
    }

    ul li {
      color: red;
      font-size: 20px;
    }
  </style>
  <body>
    <div class="box">hello world</div>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
  </body>

3. 理想的开发模式

那么, 我们可以直接在浏览器中编辑好,然后不打开编辑器保存代码吗?
答案是可以的, 就是用浏览器源代码面板中的 文件系统功能

image.png

添加文件的时候,文件夹最好是英文命名, 然后浏览器会有个提示, 是否允许浏览器有访问权限, 点击允许

image.png

我们把刚才新建的包含html文件的文件夹添加到这里,然后在编辑器中安装 Live-sever 插件,使用live-sever 打开

image.png

此时我们打开文件系统中的demo.html 文件,在上面编辑,保存, 页面就会同步刷新,然后看一下代码,也已经进行了修改, 那么到此,浏览器已经可以变身成编辑器了, 我们可以在这里进行 command+p 查找文件, command+f查找, 复制粘贴,基本编辑器的功能都可以在这里使用了

output1.gif

但是到此,我们只不过是把编辑器的功能搬到了浏览器, 还是没有很简化我的操作,像我们一开始讲的, 如果我们可以在元素审查的时候更改样式, 直接去修改代码可以实现吗, 答案也是可以的。

为了能一边看元素审查面板,一边看源代码面板。我们把源代码面板移到底部

image.png

此时更改,样式文件,会发现,无法生效, 原因是, 如果想通过元素审查里面直接更改样式, 需要我们的样式文件不能是内部样式表,而是外部引入,原理是,修改样式时,浏览器会发送socket请求给html,并且修改html中的css引用,并且会发送新的css引用链接,下面我们会在看这段脚本解释这里。现在我们先把代码修改成link导入,再次启动live sever服务

// 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>
</html
// css
.box {
    width: 300px;
    height: 400px;
    background-color: #ea269b;
    color: #3748a7;
    font-size: 30px;
  }
  ul li {
    color: #00ff33;
    font-size: 20px;
  }

此时我们再次进行审查元素, 修改样式,看下面的效果

output2.gif

这时,我们再去元素审查,修改样式代码, 发现样式改了, 浏览器文件系统中的样式代码改了, 编辑器中的样式代码也改了, 我们的需求到现在基本完成了, 但是如果再次修改,我们会发现右下角的文件系统里的样式文件出现了问号,说明现在是socket不通的状态, 并且编辑器中的代码是没有再次进行更改的。 其实这个问题是浏览器本身不支持这样多次更改, 产生 css 缓存后, 就不再进行热更新了, 禁掉缓存后也没有用, 但是我们尝试每次修改后, 强制刷新页面,在进行修改,发现是可以保证每次修改都生效的。

但是这样还要每次手动刷新还是不方便, 那么怎么解决这个问题呢, 其实只需要在每次热更新后, 我们调用一下浏览器的强制刷新即可, 我们在元素审查html文件中查看,会发现浏览器偷偷给我们添加了一段脚本。

image.png

我们把这段脚本拿下来看

// <![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);
      }
    };
//...

output3.gif

这时我们就完整的完成了从 审查元素 > 修改样式 > 代码更改成功 的完整链路, 也大体理清了,浏览器的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;
  }

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYOBkAj3' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片