<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>NotionNext BLOG</title>
        <link>https://huanglvming.cn/</link>
        <description>这是一个由NotionNext生成的站点</description>
        <lastBuildDate>Thu, 24 Aug 2023 15:37:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2023, SuperLvming</copyright>
        <item>
            <title><![CDATA[你可能不知道的VSCode]]></title>
            <link>https://huanglvming.cn/article/vscode</link>
            <guid>https://huanglvming.cn/article/vscode</guid>
            <pubDate>Thu, 24 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[10条你可能不知道的VSCode使用技巧]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-6267d0dfd3c24b429b0b0dd15b0d7e73"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-7cc7357d88ef42c79f76567504189682"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text">古人云：“工欲善其事，必先利其器”，我们每天开发都离不开VSCode，更好的掌握VSCode，意味着更高的效率。</div></div><div class="notion-blank notion-block-58b3fff516644117b255da1fcf550fdd"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-c25f5ffbd9444e81bd3f5fa92eeefd83" data-id="c25f5ffbd9444e81bd3f5fa92eeefd83"><span><div id="c25f5ffbd9444e81bd3f5fa92eeefd83" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c25f5ffbd9444e81bd3f5fa92eeefd83" title="📝 10个你可能不知道的VSCode使用技巧"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 10个你可能不知道的VSCode使用技巧</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-fde0b5d9a38546ac9e7b3a09d165d139" data-id="fde0b5d9a38546ac9e7b3a09d165d139"><span><div id="fde0b5d9a38546ac9e7b3a09d165d139" class="notion-header-anchor"></div><a class="notion-hash-link" href="#fde0b5d9a38546ac9e7b3a09d165d139" title="1.打开setting.json"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.打开<code class="notion-inline-code">setting.json</code></span></span></h3><blockquote class="notion-quote notion-block-3bf79e47ea4c44d6935cffa50caf5cae"><div>这是最简单的，也是最重要的。</div></blockquote><div class="notion-text notion-block-418769b215384de98758952d9f6da287">不知道小伙伴们是否也曾遇到像我一样的困惑，如何才能打开<code class="notion-inline-code">setting.json</code>？听起来很可笑，但是不管我们是通过点击<code class="notion-inline-code">VSCode</code>的<code class="notion-inline-code">setting</code>，还是通过快捷键<code class="notion-inline-code">command+,</code> 打开的都是设置面板，像这样</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-91ec19268dbd472f8e591bd6b2259561"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F28effc85-4233-447a-b07c-855b1818d836%2FUntitled.png?table=block&amp;id=91ec1926-8dbd-472f-8e59-1bd6b2259561" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-e7b9471d9670421198cc4a5d68428a67">然而有时候我们希望打开的是<code class="notion-inline-code">setting.json</code> ，这样可以更快捷的编辑多项配置(粘贴网上刚复制好的<code class="notion-inline-code">json</code>)，这时候我们就可以点击编辑器右上角的这个按钮进行打开</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b60c3edd6998496cab0d02f4f4d9000b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fee3b378f-9de1-4135-b1cb-9cc2b95ad0c1%2FUntitled.png?table=block&amp;id=b60c3edd-6998-496c-ab0d-02f4f4d9000b" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-478e047a47eb40629079ddcd1fff45c7">我们还可以通过快捷键<code class="notion-inline-code">command+p</code> 呼出输入框，然后输入<code class="notion-inline-code">setting.json</code> 进行打开</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-baab6781cc574213be6ac915669b6b1d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fc6c74863-93a0-4653-a4dc-8270e82fffa8%2FUntitled.png?table=block&amp;id=baab6781-cc57-4213-be6a-c915669b6b1d" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d227bdaeebf54c03942921e275172ae8" data-id="d227bdaeebf54c03942921e275172ae8"><span><div id="d227bdaeebf54c03942921e275172ae8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d227bdaeebf54c03942921e275172ae8" title="2.关键的.vscode"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.关键的<code class="notion-inline-code">.vscode</code></span></span></h3><blockquote class="notion-quote notion-block-fdf5749ecac34928b6a38506f5280350"><div>在项目中配置<code class="notion-inline-code">.vscode</code> ，可以在保留团队各开发者的自定义配置时，又可以确保项目配置的大一统</div></blockquote><div class="notion-text notion-block-6b1bc699a1b44b05980c16b7236e257b">不知道小伙伴们是否也遇到过像我一样的困惑，打开某个项目时，<code class="notion-inline-code">prettier</code>格式化检验报错，提示当前项目使用的<code class="notion-inline-code">prettier</code>配置是<code class="notion-inline-code">.prettierrc.js</code> ，而我的<code class="notion-inline-code">VSCode Setting</code> 设置的是<code class="notion-inline-code">.prettierrc</code> ，于是我赶紧更新<code class="notion-inline-code">VSCode Setting</code> 的相关配置项为<code class="notion-inline-code">.prettierrc.js</code> ；打开另外一个项目时，<code class="notion-inline-code">prettier</code> 又报错了，因为当前项目使用的<code class="notion-inline-code">prettier</code>配置是<code class="notion-inline-code">.prettierrc</code> ，而我在上一个项目中把<code class="notion-inline-code">VSCode Setting</code> 的配置项设为<code class="notion-inline-code">.prettierrc.js</code> 🙃️</div><div class="notion-blank notion-block-a5decd173d374e1e97ae130a62c3ce8a"> </div><div class="notion-text notion-block-eb7da76d604c4afa80538a8c5f536d55">这种情况下，<code class="notion-inline-code">.vscode</code> 就变得非常重要了。<code class="notion-inline-code">VSCode</code> 的配置分为两类，一是<b>全局用户配置</b>，二是<b>当前工作区配置。</b><code class="notion-inline-code">VSCode</code> 每打开一个项目，项目文件夹的根目录就是一个工作区。可以在项目根目录下创建<code class="notion-inline-code">.vscode</code> 文件夹，从而设置该项目的工作区配置。</div><div class="notion-text notion-block-dc0219e79f66417189dcb2d1a71e9ef4"><code class="notion-inline-code">.vscode</code> 可以接收4中配置文件和若干个代码片段：</div><ul class="notion-list notion-list-disc notion-block-e09345a9f3094fe2a0e9ee0a7e303036"><li><code class="notion-inline-code">extensions.json</code> ：当前项目使用的插件</li></ul><ul class="notion-list notion-list-disc notion-block-2f4791e68c7b420182022b63e1e87716"><li><code class="notion-inline-code">settings.json</code> ：当前项目使用的<code class="notion-inline-code">VSCode</code> 配置</li></ul><ul class="notion-list notion-list-disc notion-block-1ac145bebb924df9a2a334c17feb6399"><li><code class="notion-inline-code">launch.json</code> ：当前项目的调试配置文件</li></ul><ul class="notion-list notion-list-disc notion-block-137ae22be4c6456f999d1bb996ad9c76"><li><code class="notion-inline-code">task.json</code> ：当前项目的任务配置</li></ul><ul class="notion-list notion-list-disc notion-block-b754858d70b84365af9eae52b4c6394c"><li><code class="notion-inline-code">xxx.code-snippets</code> ：当前项目的共享代码片段</li></ul><div class="notion-blank notion-block-d229b1fba18744f79020ed2beb0b5b75"> </div><div class="notion-text notion-block-4981f6fbc163435a96f7481921a30228">针对以上场景，如果当前项目使用的<code class="notion-inline-code">.prettierrc.js</code> 配置，那么我们可以修改<code class="notion-inline-code">.vscode</code> 中的<code class="notion-inline-code">settings.json</code> </div><div class="notion-text notion-block-2e613db2dd944a50994995eb0a7bf25f">设置好后，不管开发者的<code class="notion-inline-code">VSCode Setting</code> 是什么配置，永远都不会与本项目冲突，完美解决了<em>个性与标准并存</em>的问题。</div><div class="notion-blank notion-block-d016f738a25840ad8015e423372778bb"> </div><div class="notion-text notion-block-f97712e1fba6474fa3d9d76635f9bb44">除了<code class="notion-inline-code">settings.json</code> ，<code class="notion-inline-code">xxx.code-snippets</code> 也是非常值得推荐的配置，这可以配置当前项目比较高频的代码片段，比如</div><div class="notion-text notion-block-9207c721a77f4cf48acb5393b2af4403">设置好后，我们只需在项目文件中输出<code class="notion-inline-code">init</code> 并回车，就能自动生成代码</div><div class="notion-blank notion-block-6894c712d5da4240b7b4bff7caf37c77"> </div><div class="notion-text notion-block-0f6490346d0e4390bf53f3443dd6fc55">其他配置不一一举例，留给小伙伴自己去探索吧。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3127d17f24784d9c801acc0441cf6a4d" data-id="3127d17f24784d9c801acc0441cf6a4d"><span><div id="3127d17f24784d9c801acc0441cf6a4d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3127d17f24784d9c801acc0441cf6a4d" title="🤗 总结归纳"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🤗 总结归纳</span></span></h2><div class="notion-text notion-block-2b56ed2a97f44681ba0114e90a442867">总结文章的内容</div><div class="notion-blank notion-block-77d5efda94994ed4ac3df551b13e0925"> </div><div class="notion-callout notion-gray_background_co notion-block-500fb1f304414528a87d16da915d46a7"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"></div></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[谈谈 API 加速]]></title>
            <link>https://huanglvming.cn/article/speed-up</link>
            <guid>https://huanglvming.cn/article/speed-up</guid>
            <pubDate>Thu, 17 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[可以通过 CDN 和 加速器来实现 API 加速]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-1fb287580e9f45c483445f3da0301258"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-417b39fd701145fba5f425c8e7845623"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text">最近在做一个网页聊天的项目，前后端通过`stream`保持长链接，但感觉`stream`更新比较慢，反映在网页上的表现是聊天输出卡顿。</div></div><div class="notion-blank notion-block-c21edfd31c5e4415a565d0bb9248a291"> </div><div class="notion-text notion-block-57468cbb636d4acb8c766cb0ca362c4f">针对`stream`更新慢的问题，后端开发第一时间想到的是<b>API加速</b>，说的是“可以通过<b>CDN</b>来提高API响应速度”。我当时并没有想太多，心想由后端开发和SRE搞好<b>加速</b>就行，前端无非是换一个<b>API</b>链接。</div><div class="notion-blank notion-block-a52c4ba27ebf4d68bfc372fcd30bbb6b"> </div><div class="notion-text notion-block-1aed297d512c42718ca919e3d09774ca">后来SRE跟我说已经搞好了，我换了加速后的API连接进行测试，果然快了很多，响应速度几乎提升了一倍。中午吃饭的时候便和同事聊到：

“那个项目的接口使用<b>CDN加速</b>后，果然快了很多。”</div><div class="notion-text notion-block-f25da66422db4a7e80e487188c214d26">“API使用CDN加速？你确定吗？”</div><div class="notion-text notion-block-cab73a1c8e8b45e59de48598576af8ed">“额。。。总之是API加速了，我也不确定是不是使用了CDN。”</div><div class="notion-text notion-block-f6cafde6972e487ab9f9aa5cbeeee34f">“CDN不是用于缓存作用吗？API是动态结果，为什么要用CDN？即便用了，真的能加速？”</div><div class="notion-text notion-block-3f0d91875399489191547ced79041073">“额。。。”</div><div class="notion-blank notion-block-09eb73593e8c4302843f6889d8252785"> </div><div class="notion-text notion-block-16b25745d93a4fcab0fbd53f241816cf">虽然我相信即便API是动态结果，即便我们不需要依赖缓存，使用CDN后肯定也能达到加速的效果。但一时间也说不出个所以然，所以吃完饭赶紧向SRE请教。</div><div class="notion-blank notion-block-e7c51812267046ccbd37028655c50943"> </div><div class="notion-text notion-block-d84b7582cac34a7188bf73fce02c531d">诚然，CDN提速的一个重要原因是因为<b>缓存</b>，多个CDN节点组成的网络像一层膜一样横穿在请求端和响应端之间，当一个请求到达CDN层的时候，CDN如果检查到缓存中有该请求需要的结果，则直接响应请求结果，本次请求甚至无法穿过CDN这层“膜”；只在当CDN层匹配不到本次请求的结果时，才允许请求穿透这层“膜”，达到响应服务器，我们称之为<b>源站</b>，而穿透“膜”的这种行为，我们称之为<b>击穿CDN</b>。</div><div class="notion-blank notion-block-5677d14eea994e7087c6c67b64a7b047"> </div><div class="notion-text notion-block-2f14468efc054b0b8f094b3c4f2a8778">难道真的像同事说的那样，“API是动态结果，无法缓存，必然每次都击穿CDN，所以API无法使用CDN加速”？这么想的话，还是太低估了CDN在背后帮我们做的事情。所谓<b>缓存，</b>其实就是<b>静态资源缓存，</b>对应的是<b>静态内容加速</b>；与静态内容加速相对应的，是<b>动态内容加速</b>，指的是<span class="notion-orange_background">用户在请求一些动态内容时，不直接请求源站，而是由基于地理位置的DNS调度，请求最靠近用户的云服务节点，再由云服务节点通过优化过的传输网络（公网，但比普通BGP更优化的链路），转发请求到源站，达到优化和加速的目的。</span></div><div class="notion-blank notion-block-dc02b9cc27da41578d8b449346826e5b"> </div><div class="notion-text notion-block-7ebab3d214ab4c378b9955dce0506c59">所以即便没有缓存，使用CDN也能帮助我们更快的达到源站。</div><div class="notion-blank notion-block-359ab7601d2441809e176b92e6629b80"> </div><div class="notion-text notion-block-f47374d322de48909c95538acd6d9ec3">但是和SRE聊完后才知道，原来本次API加速，使用的并不是CDN（这是由于牵扯到一些业务原因，并非说CDN加速不好），而是使用了一种叫做<span class="notion-orange_background"><b>Anycast</b></span>的技术。</div><div class="notion-blank notion-block-560d5708d6cc4be496244a197228472b"> </div><blockquote class="notion-quote notion-block-2386e653a5454a7bac1890044d1c8e7b"><div><span class="notion-orange_background"><b>Anycast</b></span>又叫任播，是指一个发送方同最近的一组接收方之间的通信。当一个单播地址被分配到多于一个的接口上时，发到该接口的报文被网络路由到由路由协议度量的最近的目标接口上。<b>原理为，普通的IP是单播寻址，全程走公网，如果用Anycast的话，该公网IP用任播形式寻址，在腾讯云的多个节点都发路由，这样客户端的包只需要走公网到达最近的腾讯云节点即可，剩下来的路程是走更有保障的腾讯云内网。</b></div></blockquote><div class="notion-blank notion-block-9effacde0d1b48c5ae513837adeb14f6"> </div><div class="notion-text notion-block-a615b2aa7f584b769b6c7a1d0b699895">以上是摘抄了网络上的一些解释，<span class="notion-orange_background">按照我的理解，有点像是“直达专车”的概念，乘客只需找到最近的“直达专车”，一旦上车之后，它就会走直达通道，这比各种“中转”“并道”等来得更快。</span><span class="notion-default">希望我的理解没问题。</span></div><div class="notion-blank notion-block-d95a99c6359444afa7f2a766a560454c"> </div><div class="notion-text notion-block-e0913dbe19b74717a879a4fe80b90a7d">后来还了解到，除了以上的<b>CDN加速</b>和<b>Anycast，</b>能到达到加速目的的还有很多，虽然不懂，但还是记录一下吧：</div><ul class="notion-list notion-list-disc notion-block-93818d958459403b9d58e03805508684"><li>静态CDN服务</li></ul><ul class="notion-list notion-list-disc notion-block-e1463c89c50c457199f8d1dea60b702c"><li>动态内容加速</li></ul><ul class="notion-list notion-list-disc notion-block-9daa2131b29c4c25bbd3451ac79c365b"><li>全站加速（动态+静态加速）</li></ul><ul class="notion-list notion-list-disc notion-block-169135bc60f24ae1a48fc7a13fa87393"><li>Anycast 公网加速 AIA</li></ul><ul class="notion-list notion-list-disc notion-block-aa67648a408d4d099f583a45f5b27540"><li>CLB跨地域部署</li></ul><ul class="notion-list notion-list-disc notion-block-046e301bab1d46eab107e9f83a0118c0"><li>全球应用加速GAAP</li></ul><div class="notion-blank notion-block-ab4fcbafd36c42e7846389da253864a9"> </div><div class="notion-blank notion-block-ac03d0620c6340e7a8676eb6b78f0d0b"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[实现文本拷贝时保留段落样式]]></title>
            <link>https://huanglvming.cn/article/copy-plain-text</link>
            <guid>https://huanglvming.cn/article/copy-plain-text</guid>
            <pubDate>Thu, 17 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[实现文本拷贝时保留段落样式]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-557306c7a20e41fe8d6855ecff126d3c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-20d992fbe7114af1ae72c37f1852212b">今天收到也无妨反馈，直接点击站点上的文本拷贝按钮时，拷贝结果出现以下问题：</div><ul class="notion-list notion-list-disc notion-block-3d71ac47e45647d397644a3be8d8f2e1"><li>拷贝后，在富文本编辑内粘贴，文字携带背景色</li></ul><ul class="notion-list notion-list-disc notion-block-25bc05899440497c86595852aca57b0a"><li>拷贝后，文本内容包含HTML元素标签</li></ul><ul class="notion-list notion-list-disc notion-block-90ab04968b2148e29cfb8069ae32442a"><li>拷贝后，无法保持页面上的展示的段落样式</li></ul><div class="notion-blank notion-block-67e946ae06a44529b95368e0e7fba6b3"> </div><div class="notion-text notion-block-714be6b5e0504043b24db272145b678a">查看项目源码之后，发现原本使用的是<code class="notion-inline-code">react-copy-to-clipboard</code>,代码如下：</div><div class="notion-blank notion-block-9f249121362842b393743de25bb7be02"> </div><div class="notion-text notion-block-99158604bd5a446a899f3fa6d0e87a1c">再审查页面元素时，看到结构大概如下：</div><div class="notion-blank notion-block-bda4a7426719481282806ed170ae1569"> </div><div class="notion-text notion-block-561163d86d96402b8221d28dba2375e3">很明显，拷贝的元素对象内，包含&lt;br&gt;标签，而&lt;br&gt;在HTML中渲染会换行，从而显示段落效果。</div><div class="notion-blank notion-block-026c4c4661dd46fdb9912088cf28cad1"> </div><div class="notion-text notion-block-950aca4121284aa19b92b668e2abad88">先看第一个问题「拷贝后，在富文本编辑内粘贴，文字携带背景色」。在查看了<code class="notion-inline-code">react-copy-to-clipboard</code> 的文档后，发现可以配置`option.format`参数，参数值是`MIME type`，可以通过设置`option.format = “text/plain”`来解决问题。</div><blockquote class="notion-quote notion-block-8880362ea69d45bd947abaee769754ac"><div><code class="notion-inline-code">String</code>. Optional. Set the MIME type of what you want to copy as. Use <code class="notion-inline-code">text/html</code> to copy as HTML, <b><code class="notion-inline-code">text/plain</code></b><b> to avoid inherited styles showing when pasted into rich text edito</b></div></blockquote><div class="notion-blank notion-block-14c5d9287cdf4d0ba2deaaefcde6a119"> </div><div class="notion-text notion-block-0acc1286a467401c8115f18267f0e44d">再看第二个问题「拷贝后，文本内容包含HTML元素标签」。如上述分析，因为元素内包含了HTML标签元素，不管是通过`innerHTML`还是`innerText`，必然都会携带文本内的标签元素（因为此时标签被当作普通字符来获取）。</div><div class="notion-text notion-block-42d02303d1d24411a087f9f678e9c147">很简单，我们写一个正则匹配来将标签过滤就好了。</div><div class="notion-blank notion-block-908c5b4a49634471afec3b81e569de73"> </div><div class="notion-text notion-block-a50e65be3ea6402ca01b4311641b8b87">第二个问题虽然解决了，但同时我们也丢失了文本段落样式，查看了<code class="notion-inline-code">react-copy-to-clipboard</code> 之后，确定没有相关配置可以解决，所以只能放弃该组件。</div><div class="notion-text notion-block-0b5a7dbf493c4b7b96ccadc8323fab96">自己写了一个方法：</div><div class="notion-text notion-block-55a012ddc47a44b59e0ddf8a65673a4a">也可以这样：</div><div class="notion-text notion-block-dcb4858f130c471e8345aa926fdd7cb4">通过以上方法，就可以完全解决问题。</div><div class="notion-blank notion-block-a3dc72a23fdb412c968d790bbaee2266"> </div><div class="notion-callout notion-gray_background_co notion-block-f60917a5b659470988a6263ce9336a18"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text"><b>document.execCommand </b>和 	<b>navigator.clipboard.writeText </b>可能存在兼容性问题</div></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[读书笔记之 WeakMap]]></title>
            <link>https://huanglvming.cn/article/weakmap</link>
            <guid>https://huanglvming.cn/article/weakmap</guid>
            <pubDate>Wed, 16 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[浅谈WeakMap]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-fa220da62b084f6eb6bd596163690af1"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-3f29988225ae4f8a8066876cc0beb66f">之前了解的`Map`和`WeakMap`，只知道<b>`WeakMap`只允许使用对象作为键，而不能是原始值</b>，但却忽略了它还有一个很重要的特性，即<b>它不会阻止垃圾回收机制对作为键的对象(key object)的回收</b>。</div><div class="notion-blank notion-block-73fec874503c4e63bdfed288df9769e6"> </div><div class="notion-text notion-block-1d004c20897c4185b653750644b6ff10">为了更好的解释这句话的意思，先看以下代码：</div><div class="notion-blank notion-block-445c22d7792a4613b0d4715c97177546"> </div><div class="notion-text notion-block-6c9d6d5d04474150b29ed37273ca5dfc">如上，虽说`foo`最后被赋值为`null`，但是并不会被垃圾回收机制回收，原因是`foo`所引用的对象被存储在`array`中，我们仍然可以通过`array[0]`来获取`foo`所引用的对象的值。</div><div class="notion-blank notion-block-824b56cd75df403c9c6953461c465377"> </div><div class="notion-text notion-default notion-block-2bc73e9a1318427886eab48c2e172459">同理，如果我们将`foo`作为常规`Map`的键，只要`Map`对象存在，那么`foo`就无法被回收。</div><div class="notion-blank notion-block-d3313000ecf64fb2a2a0589974858f28"> </div><div class="notion-text notion-block-3917c7ca3c2b4265b4551444c30c2a8a">这时候`WeakMap`的特性就体现出来了，以上方法如果使用`WeakMap`来做，当设置`foo=null`时，`foo`的引用地址将会被覆盖，同时`WeakMap`对应的键值也会被删除，从而彻底释放`foo`的引用地址，即彻底被回收。</div><div class="notion-blank notion-block-d30f9a1d8d6a47f98ee572f0ecfa8f8c"> </div><div class="notion-callout notion-gray_background_co notion-block-f5a9a4ea05da4e358bfb7f3e4c97199c"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">为什么说“<em><b>weakmap将会是个空值集合</b></em>”？因为我们无法从技术角度准确知道垃圾回收机制何时将引用地址回收。笔者曾经在`chrome`控制台复现过这样的场景：</div></div><div class="notion-blank notion-block-700ddad85a88447eb72e109fab05596d"> </div><div class="notion-text notion-block-27010ef54bc044dca92c47555f87ce87">可见我们是无法准确知道垃圾回收机制何时回收某个引用地址。<!-- -->如有纰漏，欢迎指正。</div><div class="notion-blank notion-block-fcb9d58ee3dc46df9a5fe7898f83817c"> </div><div class="notion-blank notion-block-9aac479bbf8348e1ac55a3870b718401"> </div><div class="notion-blank notion-block-1c6117eb59994f39a2e40fa4da99267e"> </div><div class="notion-blank notion-block-a2de7558ffea4d7ea3d1b932af4948c4"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>