daily-question-04(前端每日一题04)

541 阅读10分钟

在这里记录着每天自己遇到的一道印象深刻的前端问题,以及一道生活中随处可见的小问题。

强迫自己形成积累的习惯,鞭挞自己不断前行,共同学习。

Github 地址

2019/05/13 - 2019/05/19

  • 请解释 <script><script async><script defer> 的区别

    点击
    1. <script src="script.js"></script>

    没有 deferasync,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

    1. <script async src="script.js"></script>

    async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。

    1. <script defer src="myscript.js"></script>

    defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

  • html5 新标签有哪些?

    点击
    <article>
      标签定义外部的内容。比如来自一个外部的新闻提供者的一篇新的文章,或者来自
      blog 的文本,或者是来自论坛的文本。亦或是来自其他外部源内容。
    
      <aside>
        标签定义 article 以外的内容。aside 的内容应该与 article 的内容相关。
    
        <audio>
          标签定义声音,比如音乐或其他音频流。
    
          <canvas>
            标签定义图形,比如图表和其他图像。这个 HTML
            元素是为了客户端矢量图形而设计的。它自己没有行为,但却把一个绘图 API
            展现给客户端 JavaScript 以使脚本能够把想绘制的东西都绘制到一块画布上。
    
            <command>
              标签定义命令按钮,比如单选按钮、复选框或按钮。
    
              <datalist>
                标签定义可选数据的列表。与 input
                元素配合使用,就可以制作出输入值的下拉列表。
    
                <details>
                  标签定义元素的细节,用户可进行查看,或通过点击进行隐藏。与
                  <legend>
                    一起使用,来制作 detail
                    的标题。该标题对用户是可见的,当在其上点击时可打开或关闭
                    detail。
    
                    <figcaption>
                      标签定义 figure 元素的标题。”figcaption” 元素应该被置于
                      “figure” 元素的第一个或最后一个子元素的位置。 HTML5:
                      <figure><figcaption>PRC</figcaption></figure>
    
                      <figure>
                        标签用于对元素进行组合。使用
                        <figcaption>
                          元素为元素组添加标题。 HTML5:
                          <figure>
                            <figcaption>PRC</figcaption>
                            <p>
                              The People's Republic of China was born in 1949...
                            </p>
                          </figure>
    
                          <footer>
                            标签定义 section 或 document
                            的页脚。典型地,它会包含创作者的姓名、文档的创作日期以及/或者联系信息。
    
                            <header>
                              标签定义 section 或 document 的页眉。
    
                              <hgroup>
                                标签用于对网页或区段(section)的标题进行组合。
    
                                <nav>
                                  标签定义导航链接的部分。
    
                                  <section>
                                    标签定义文档中的节(section、区段)。比如章节、页眉、页脚或文档中的其他部分。
    
                                    <source />
                                    标签为媒介元素(比如
                                    <video><audio>
                                        )定义媒介资源。
    
                                        <video>
                                          标签定义视频,比如电影片段或其他视频流。
                                          HTML5:
                                          <video
                                            src="movie.ogg"
                                            controls="controls"
                                          >
                                            您的浏览器不支持 video 标签。
                                          </video>
                                        </video>
                                      </audio>
                                    </video>
                                  </section>
                                </nav>
                              </hgroup>
                            </header>
                          </footer>
                        </figcaption>
                      </figure>
                    </figcaption>
                  </legend></details
                >
              </datalist></command
            ></canvas
          >
        </audio>
      </aside>
    </article>
    
  • <a> 标签中 href="javascript:;" 表示什么意思??

    点击

    这里的 href="javascript:;" ,其中 javascript: 是伪协议,它可以让我们通过一个链接来调用 javascript 函数.而采用这个方式 javascript:; 可以实现 A 标签的点击事件运行时,如果页面内容很多,有滚动条时,页面不会乱跳,用户体验更好。

  • 实现数组扁平化的方法?

    参考文章: 《数组的去重与扁平化》

  • GitSVN 的区别?

    点击 > Git 和 SVN 孰优孰好,每个人有不同的体验。 > > Git是分布式的,SVN是集中式的 > > 这是 Git 和 SVN 最大的区别。若能掌握这个概念,两者区别基本搞懂大半。因为 Git 是分布式的,所以 Git 支持离线工作,在本地可以进行很多操作,包括接下来将要重磅推出的分支功能。而 SVN 必须联网才能正常工作。 > > Git 复杂概念多,SVN 简单易上手 > 所有同时掌握 Git 和 SVN 的开发者都必须承认,Git 的命令实在太多了,日常工作需要掌握add,commit,status,fetch,push,rebase等,若要熟练掌握,还必须掌握rebase和merge的区别,fetch和pull的区别等,除此之外,还有cherry-pick,submodule,stash等功能,仅是这些名词听着都很绕。 > > 在易用性这方面,SVN 会好得多,简单易上手,对新手很友好。但是从另外一方面看,Git 命令多意味着功能多,若我们能掌握大部分 Git 的功能,体会到其中的奥妙,会发现再也回不去 SVN 的时代了。 > > Git 分支廉价,SVN 分支昂贵 > > 在版本管理里,分支是很常使用的功能。在发布版本前,需要发布分支,进行大需求开发,需要 feature 分支,大团队还会有开发分支,稳定分支等。在大团队开发过程中,常常存在创建分支,切换分支的需求。 > > Git 分支是指针指向某次提交,而 SVN 分支是拷贝的目录。这个特性使 Git 的分支切换非常迅速,且创建成本非常低。 > > 而且 Git 有本地分支,SVN 无本地分支。在实际开发过程中,经常会遇到有些代码没写完,但是需紧急处理其他问题,若我们使用 Git,便可以创建本地分支存储没写完的代码,待问题处理完后,再回到本地分支继续完成代码。
  • 前端日志埋点方案?

    《小蝌蚪传记:200行代码实现前端无痕埋点》

  • npm、yarn 依赖包管理的原理,两者的区别 ?

    点击 首先,这两个都属于 js 包管理工具,都可以安装包或者模块, 两者命令有所不同

    yarn 是由 facebook、google等联合开发推出的,具有速度快离线工作从多个源安装安装版本统一更简洁的输出多注册来源处理更好的语义化的优点

2019/05/06 - 2019/05/12

  • 如何有效避免回流与重绘 ?

    点击
    1. Display 的值会影响布局,从而影响页面元素位置变化,所以会更改渲染树的结构,慎用

    2. 使用 DocumentFragment 进行缓存操作,引发一次回流和重绘

    3. 使用 cloneNode (true or false) 和 replaceChild 技术,引发一次回流和重绘。

    4. 不要对元素进行 JS 动画流操作,尽量使用 CSS 动画属性,以减少回流的 Render Tree 的规模

  • 从输入 URL 到页面展现的详细过程 ?

    参考文章: 《输入URL至页面渲染》

  • 浏览器跨标签通信 ?

    localstorage 或者 cookie 或者 url 传递参数

  • 浏览器海量数据存储 ?

    点击

    cookie 用于短期存储用户身份,登录状态等较小的信息;localStorage/sessionStorage 用于长期存储数据,浏览器关闭不影响它们的内存,相比于 cookie,storage 能存储较多;IndexedDB 是浏览器提供的接近于 NoSQL 的数据库,允许存储大量数据。

  • 域名解析的过程?

    点击

    1、在浏览器中输入 www.qq.com 域名,操作系统会先检查自己本地的 hosts 文件是否有这个网址映射关系,如果有,就先调用这个 IP 地址映射,完成域名解析。

    2、如果 hosts 里没有这个域名的映射,则查找本地 DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。

    3、如果 hosts本地DNS解析器缓存 都没有相应的网址映射关系,首先会找 TCP/ip 参数中设置的 首选DNS服务器,在此我们叫它 本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。

    4、如果要查询的域名,不由 本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个 IP 地址映射,完成域名解析,此解析不具有权威性。

    5、如果 本地DNS服务器 本地区域文件与缓存解析都失效,则根据 本地DNS服务器 的设置(是否设置转发器)进行查询,如果未用转发模式,本地 DNS 就把请求发至 13 台根 DNS,根 DNS 服务器收到请求后会判断这个域名 (.com) 是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP本地DNS服务器 收到 IP 信息后,将会联系负责 .com 域的这台服务器。这台负责 .com 域的服务器收到请求后,如果自己无法解析,它就会找一个管理 .com 域的下一级 DNS 服务器地址(http://qq.com)本地DNS服务器。当 本地DNS服务器 收到这个地址后,就会找 http://qq.com 域服务器,重复上面的动作,进行查询,直至找到 www.qq .com 主机。

    6、如果用的是转发模式,此 DNS 服务器就会把请求转发至上一级 DNS 服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根 DNS 或把转请求转至上上级,以此循环。不管是 本地DNS服务器 用是是转发,还是根提示,最后都是把结果返回给 本地DNS服务器,由此 DNS 服务器再返回给客户机。

  • JavaScript 异常处理的方式,统一的异常处理方案

    参考文章:《JavaScript的异常处理》

  • 如何解决页面加载海量数据而不冻结前端 UI ?

    点击
    题目:10w 条记录的数组,一次性渲染到页面上,如何处理可以不冻结UI?
    

    分治思想,在一定的时间内多次加载数据,直至渲染完成,使用 window.requestAnimationFramedocument.createDocumentFragment() 实现

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>页面加载海量数据</title>
      </head>
    
      <body>
        <ul id="list-with-big-data">
          100000 数据
        </ul>
        <script>
          // 此处添加你的代码逻辑
          (function() {
            const ulContainer = document.getElementById('list-with-big-data');
    
            // 防御性编程
            if (!ulContainer) {
              return;
            }
    
            const total = 100000; // 插入数据的总数
            const batchSize = 4; // 每次批量插入的节点个数,个数越多,界面越卡顿
            const batchCount = total / batchSize; // 批处理的次数
            let batchDone = 0; // 已完成的批处理个数
    
            function appendItems() {
              // 使用 DocumentFragment 减少 DOM 操作次数,对已有元素不进行回流
              const fragment = document.createDocumentFragment();
    
              for (let i = 0; i < batchSize; i++) {
                const liItem = document.createElement('li');
                liItem.innerText = batchDone * batchSize + i + 1;
                fragment.appendChild(liItem);
              }
    
              // 每次批处理只修改 1 次 DOM
              ulContainer.appendChild(fragment);
              batchDone++;
              doAppendBatch();
            }
    
            function doAppendBatch() {
              if (batchDone < batchCount) {
                // 在重绘之前,分批插入新节点
                window.requestAnimationFrame(appendItems);
              }
            }
    
            // kickoff
            doAppendBatch();
    
            // 使用 事件委托 ,利用 JavaScript 的事件机制,实现对海量元素的监听,有效减少事件注册的数量
            ulContainer.addEventListener('click', function(e) {
              const target = e.target;
    
              if (target.tagName === 'LI') {
                alert(target.innerText);
              }
            });
          })();
        </script>
      </body>
    </html>