整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          外國人眼中的古都南京:歷史文化和現代生活融為一體

          媒稱,南京是一座現代化城市,但它有一種古老的蘊味,這座城市的歷史遺韻使建筑與自然環境很和諧。

          據英國廣播公司網站5月13日報道,南京首次建都于公元229年,長期以來是中國最重要(和最大)的內河港口之一,也是公認的中國四大古都之一。這里發現了距今約60萬年的直立人化石;明朝時期環繞這座城市的石頭城墻距今已有600年的歷史,而今仍然與現代的摩天大樓屹立在一起,使這座城市跟其復雜多變的過去有了永恒的視覺聯系。

          原籍英格蘭設菲爾德、現居住在南京的中學教師弗雷婭·德魯說:“從北京西路附近民國時期的低層建筑、新街口附近高聳的摩天大樓到老浦口蜿蜒的陋屋小巷,南京的建筑千差萬別。”

          <iframe data-filtered="filtered" frameborder="0" height="0" src="http://cpro.baidustatic.com/cpro/ui/c.html" width="0"></iframe>

          報道稱,雖然這種并列毗鄰在其他城市可能看上去不協調,但在南京行得通。2018年來到這里的蘇格蘭教師埃德·庫勒姆說:“這座城市的道路,往往綠樹成蔭,起起伏伏;老舊居住區緊挨著非常現代化的建筑。南京無疑是一座現代化城市,但它有一種古老的蘊味,這座城市的歷史遺韻使建筑與自然環境很和諧。”

          報道還稱,作為一個外來人口不斷增加的大學城,南京的節奏不同于熙熙攘攘的北京,也不同于極其新潮的上海,而是新來者樂于接受的平和折衷。

          庫勒姆解釋說,盡管擁有830萬人口,但南京是中國為數不多的很容易讓人獲得安寧和平靜的大城市之一。他說:“在浦口(南京西北部的一個地區),坐30分鐘的公共汽車就能把你送到老山風景區的邊緣。這片大面積的森林覆蓋的丘陵有許多小路和小徑,很容易把喧鬧的人群拋在身后。”

          報道稱,就在南京市中心,玄武湖提供了一個躲避喧囂的安靜之處,玄武湖公園內有寺廟、茶館和餐廳。為了更好地了解南京的歷史,庫勒姆建議到老門東走一走,就在秦淮河以北,是一條經過整修的步行街。老門東是該市歷史最悠久的商業街之一,其特色是擁有古典的木結構建筑(修舊如舊),內有紀念品商店,還有供應當地特色美食的小餐館,比如鹽水鴨、肉丸和美味糕點等等。

          報道還稱,與北京或西安的城墻不同,南京的老城墻不是幾何形狀的,而是繞著湖和山而建。因此,自然景觀往往出現在意想不到的城區。像長江、鐘山、玄武湖這些處于城市中心的自然景觀給人帶來的驚喜,正是新居民們喜歡生活在這里的原因所在。

          庫勒姆說:“對我來說,生活在南京意味著避開熙熙攘攘的大街,轉入老街小巷,可能遇到幾處院落、幾泓碧水或幾片幽林。正是這種巨大的多元性讓南京具有了自己的魅力。”

          庫勒姆說,“對于喜歡避開線性基線重擊聲的人們”,這座城市還有許多低調的夜總會和現場音樂演出場所。對于想念老家食物的人來說,這里并不缺少迎合外國人和留學生的外國餐廳和咖啡館。在城市里轉一圈很容易。南京擁有一個覆蓋該市大部分地區的高效、寬敞的地鐵系統,不過自行車也是一個選項,這里有適合騎車的寬闊、筆直的道路。

          原標題:外國人眼中的古都南京:歷史文化和現代生活融為一體

          frame優缺點

          優點:

          1. 網頁嵌套:通過 iframe,可以將另一個網頁嵌入到當前頁面中。這對于集成第三方內容(如地圖、視頻、社交媒體插件等)非常方便,可以在不離開當前頁面的情況下展示外部內容。
          2. 安全隔離:每個 iframe 都有獨立的文檔對象模型(DOM),這意味著它們之間的操作相互隔離。這可以防止外部網頁影響當前頁面的樣式和腳本。
          3. 并行、異步加載:iframe 可以并行且異步加載其嵌套的網頁,不會阻塞當前頁面的渲染和加載。這可以提高頁面的整體性能和加載速度。

          缺點:

          1. 性能問題:每個iframe都需要加載渲染,會增加頁面加載時間和資源消耗
          2. SEO 問題:搜索引擎可能無法正確地解析 iframe 內的內容,這可能會影響頁面的搜索引擎優化(SEO)。
          3. 跨域限制:由于瀏覽器的同源策略限制,嵌套在 iframe 中的網頁只能與同域的父頁面進行受限的通信。跨域通信需要通過特殊的技術手段(如跨文檔消息傳遞)來實現。
          4. 響應式問題:在移動設備等小屏幕上,iframe 可能需要滾動或者縮放才能適應屏幕,這可能會導致用戶體驗下降。

          ?H5新特性

          • 新增選擇器 document.querySelector、document.querySelectorAll
          • 拖拽釋放(Drag and drop) API
          • 媒體播放的 video 和 audio
          • 本地存儲 localStorage 和 sessionStorage
          • 離線應用 manifest
          • 桌面通知 Notififications
          • 語意化標簽 article、footer、header、nav、section
          • 增強表單控件 calendar、date、time、email、url、search
          • 地理位置 Geolocation
          • 多任務 webworker
          • 全雙工通信協議 websocket
          • 歷史管理 history
          • 跨域資源共享(CORS) Access-Control-Allow-Origin
          • 頁面可見性改變事件 visibilitychange
          • 跨窗口通信 PostMessage
          • Form Data 對象
          • 繪畫 canvas

          ?自定義元素

          HTML 提供了一系列內置的元素(如 <div>、<p> 等),而自定義元素則是由開發者自定義的,可以用來擴展 HTML 語義和功能。

          在傳統的 HTML 中,我們只能使用已定義的標簽來創建元素,如 <div>、<p>、<span> 等。但隨著 Web 技術的不斷發展,HTML5 引入了自定義元素的功能,允許開發者創建自己的標簽,并賦予其特定的行為和樣式。

          CSS

          ?BFC

          帶你用最簡單的方式理解最全面的BFC嗶哩嗶哩bilibili

          BFC,即塊級格式化上下文(Block Formatting Context),是CSS中的一個概念。它是指一個獨立的渲染區域,其中的元素按照一定的規則進行布局和渲染。

          BFC的主要作用是控制元素在布局上的行為,包括外邊距的塌陷、浮動元素對周圍元素的影響以及清除浮動等。以下是BFC的一些特性和應用:

          1. 外邊距折疊:在BFC中,垂直方向上的相鄰元素的外邊距會發生折疊(合并)現象,從而避免了不必要的間距。但在同一個BFC的元素中,父子元素之間的外邊距不會發生折疊。
          2. 清除浮動:BFC可以包裹浮動元素,使其不對其他元素造成影響。通過創建一個新的BFC,可以清除浮動帶來的高度塌陷問題。
          3. 阻止浮動元素重疊:在BFC中,浮動元素會受到BFC邊界的限制,從而阻止其與其他元素的重疊。這有助于解決一些浮動布局導致的錯位或溢出問題。
          4. 自適應兩欄布局:BFC可以使用浮動或者overflow: hidden;等方式創建,結合盒模型和清除浮動,可以實現一些常見的布局需求,如自適應兩欄布局。

          創建BFC的方式有多種,包括:

          • 給元素添加 float 屬性。
          • 給元素添加 display: inline-block;、display: table-cell;、display: table-caption; 等屬性。
          • 給元素添加 overflow 屬性為除 visible、clip 之外的值。

          總而言之,BFC是一種控制元素布局行為的機制,它可以解決一些常見的布局問題,如外邊距塌陷、浮動元素重疊等。了解BFC的使用和原理對于前端開發中復雜布局的實現非常有幫助。

          ?實現水平居中

          1. 行內元素:text-align:center
          2. 塊級元素:
            1. margin: 0 auto(確定寬度的情況下)
            2. transform + 絕對定位
            3. display:flex + justify-content:center
            4. 子display:inline-block + 父text-align:center
            5. display:table + margin:auto

          ?實現垂直居中

          1. 對于文字:設置line-height
          2. flex + align-items
          3. transform + 定位
          4. display:table + verticle-align:middle

          ?水平垂直居中

          ① 使用Flexbox:通過將父容器設置為display: flex;,然后使用justify-content: center;和align-items: center;屬性來水平和垂直居中子元素。

          .parent {
            display: flex;
            justify-content: center;
            align-items: center;
          }

          ② 使用Grid布局:通過將父容器設置為display: grid;,然后使用place-items: center;屬性來水平和垂直居中子元素。

          .parent {
            display: grid;
            place-items: center;
          }

          ③ 使用絕對定位和transform屬性:將子元素的位置設置為絕對定位,并且使用top: 50%;和left: 50%;將元素的左上角移動到父容器的中心,然后使用transform: translate(-50%, -50%);將元素的中心與父容器的中心對齊。

          .parent {
            position: relative;
          }
          
          .child {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
          }

          ④ 使用表格布局:將父容器設置為display: table;,然后將子元素設置為display: table-cell;vertical-align: middle;以實現水平和垂直居中。(文本水平垂直居中)

          .parent {
            display: table;
          }
          
          .child {
            display: table-cell;
            vertical-align: middle;
            text-align: center;
          }

          ⑤父flex + 子margin:auto

          ⑥絕對定位均設0 + margin:auto

          ?圣杯布局&雙飛翼布局

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Document</title>
              <style>
                  /* 
                      思路:
                          1、容器寬度設為100%來填充整個頁面寬度
                          2、為左右中三者設置float:left,以此可以顯示在一行
                          3、為left和right部分設置負的margin值,讓它們移到center行中,但注意,現在的left和right將center左右部分覆蓋了
                          4、解決覆蓋問題,有兩種方式:
                              (1) 為center左右設置內邊距,但這時會將頁面撐大,所以我們要將內邊距合并到100%的寬度里,這里我們想到了用怪異盒模型
                              (2) 用定位的方式解決,為容器wrapper設置內邊距,然后為left和right設置相對定位,并為其移動到左右兩邊
          ?
                      擴展:
                          與雙飛翼布局的區別?
                              圣杯布局通過設置負邊距與容器內邊距來使三欄顯示于一列,而雙飛翼布局則為中間列額外包裹添加外邊距來防止左右兩側遮擋,兩者實現效果相似
                  
                  */
                  .item {
                      height: 100px;
                      /* 這里設置浮動是為了讓三者可以并排顯示 */
                      float: left;
                  }
          ?
                  .center {
                      /* 為了防止左右兩塊與center重疊,我們要為其設置內邊距 */
                      /* padding: 0 300px; */
                      /* 方式一:將盒子模型設為怪異盒模型,防止padding將左右頂開 */
                      /* box-sizing: border-box; */
                  }
          ?
                  .center {
                      width: 100%;
                      background-color: green;
                  }
          ?
                  .wrap {
                      padding:0 300px;
                  }
          ?
                  .left {
                      width: 300px;
                      background-color: yellow;
                      /* 為了讓left塊和center在同一行,需要用負的margin值讓它向回移動 */
                      margin-left: -100%;
                      /* 方式二:設relative */
                      position: relative;
                      left: -300px;
                  }
          ?
                  .right {
                      width: 300px;
                      background-color: red;
                      /* 為了讓right塊和center在同一行,需要用負的margin值讓它向回移動 */
                      margin-left: -300px;
                      /* 方式二:設relative */
                      position: relative;
                      right: -300px;
                  }
              </style>
          </head>
          <body>
              <!-- 圣杯布局分左右中三部分 -->
              <div class="wrap">
                  <!-- 為了讓中間內容先渲染,寫在上面 -->
                  <div class="item center"></div>
                  <div class="item left"></div>
                  <div class="item right"></div>
              </div>
          </body>
          </html>

          clearfix

          .clearfix::after {
              content: "";
              clear: both;
              display: block;
          }

          clearfix通過為父元素添加偽元素,并為其添加清除浮動效果來解決浮動元素引起的高度塌陷問題,這里設置display:table主要有兩方面作用:

          1. 生成獨立的BFC,從而避免浮動元素對其周圍其他元素的影響
          2. 表格布局有自動調整單元格高度的特性,即表格單元格會根據內容自動撐開高度。通過將偽元素設置為 display: table,可以使其撐開父元素的高度,從而讓父元素正確地包含浮動元素。

          ?flex

          對于軸線:

          • 設定主軸方向
            • flex-direction:
              • row(default)
              • row-reverse
              • column
              • column-reverse
          • 是否換行
            • flex-wrap:
              • nowrap(default)
              • wrap
              • wrap-reverse
          • 前兩者可以合并
            • flex-flow:
              • row nowrap(default)
          • 主軸對齊方式
            • justify-content:
              • flex-start(default) 左對齊
              • flex-end 右對齊
              • center
              • space-between 兩端對齊,中間間隔相同
              • space-around 每個成員兩側的間隔相等
              • space-evenly 均勻分布,兩側靠邊間隔與元素之間間隔也相同
          • 成員在交叉軸(主軸外的另一個軸)的對齊方式,默認可以理解為y軸
            • align-items:
              • flex-start 交叉軸起點對齊
              • flex-end 交叉軸終點對齊
              • center
              • baseline 文字基線對齊
              • stretch(default) 若未設置高度,則默認占滿整個交叉軸
          • 多根軸線(多行)的對齊方式(多根主軸在交叉軸上的對齊方式)
            • align-content:
              • flex-start 與交叉軸起點對齊
              • flex-end 與交叉軸終點對齊
              • center
              • space-between 交叉軸兩端對齊,中間平均分布
              • space-around 每根軸線兩側間隔都相同
              • space-evenly 均勻分布,兩側靠邊間隔與元素之間間隔也相同
              • stretch(default) 占滿整個交叉軸

          對于其中的每一項:

          • order 值為數字,為排序的權重
          • flex-grow 值為數字,意為成員的放大比例,默認為0,若都設為1,則會放大等分剩余空間(忽略其原本寬度,全部等分)
          • flex-shrink 值為數字,意為成員的縮小比例,默認為1,若空間不足,則會縮小相同比例,若設為0,則不縮小,若都不縮小,則會超出
          • flex-basis 值為長度,意為在未分配剩余空間時,成員占據的主軸空間大小,默認為auto,即為成員的本來大小
          • flex 為flex-grow flex-shrink flex-basis的簡寫,默認為0 1 auto ,后兩者可選,我們常用這個屬性,其實本質大多數用的都是flex-grow
          • align-self 單個成員的交叉軸對齊方式
            • auto(default) 繼承自父元素 如果沒有父元素,則默認為stretch
            • flex-start
            • flex-end
            • center
            • baseline
            • stretch

          ?清除浮動

          浮動的原理是讓圖片脫離文檔流,直接浮在桌面上。我們一般布局的時候都是只設置寬度不設置高度,讓內容來自動填充高度。但使用浮動后會讓原本填充的高度消失,父元素高度為0,后續添加內容布局會產生混亂,造成高度塌陷,這時候就可以利用清除浮動來解決父元素高度塌陷的問題。

          浮動導致的問題及其解決方案:

          • 父元素高度塌陷
            • 父元素固定寬高(適用于寬高確定的板塊)
            • 在浮動元素后面新加一個空標簽,并設置clear: both;
              • 優點:簡單
              • 缺點:添加了許多空的div,語義化差
            • overflow: hidden
              • 優點:簡單易用,瀏覽器支持好
              • 缺點:要設置width和zoom,且有時會裁剪掉部分元素
            • clearfix::after(主流做法)
          .clearfix:after{/*偽元素是行內元素 正常瀏覽器清除浮動方法*/
              content: "";
              display: block;
              height: 0;
              clear:both;
              visibility: hidden;
          }
          .clearfix{
              *zoom: 1;/*ie6清除浮動的方式 *號只有IE6-IE7執行,其他瀏覽器不執行*/
          }
          • 同級非浮動元素被覆蓋
            • 給被遮蓋的元素也設置浮動
            • 為被遮蓋的元素觸發BFC(寬度足夠會同行顯示)
            • 為被遮蓋的元素設置clear: both;(會換行顯示)

          ?Grid布局

          ①定義grid布局:

          • display: grid/inline-grid

          ②設置行與列的布局

          • grid-template-rows / grid-template-columns
            • 基本使用:grid-template-rows(grid-template-columns): 100px 100px 200px,設置三行(列),高度(寬度)分別為100 100 200px
            • repeat():grid-template-rows(grid-template-columns): repeat(3, 100px),設置三行(列),高度(寬度)均為100px
              • auto-fill:grid-template-rows(grid-template-columns): repeat(auto-fill, 100px),不定有幾行/幾列,能裝多少裝多少,當可用空間不足以容納更多的列時,會創建空的隱式網格項來填充空白區域
              • auto-fit:盡量將每一列放入網格容器中,使得不留下空白的空間,當可用空間不足以容納更多的列時,會自動調整已有的網格項的大小,以填充剩余空白區域
            • fr:占比,與flex-grow類似,grid-template-rows(grid-template-columns): 100px 1fr 2fr,除去100px,剩下按1:2劃分
            • minmax():grid-template-rows(grid-template-columns): 1fr 1fr minmax(100px, 2fr),表示第三行(列)最少為100px,最大不能超過前兩行(列)的兩倍
            • auto:自動調整,grid-template-rows(grid-template-columns): 100px auto 100px,實現自由適配的三欄布局
          • row-gap / columns-gap / gap:行間距列間距以及二合一寫法

          ③劃分區域自定義放置元素

          • grid-template-areas:劃分區域
            grid-template-columns: 120px  120px  120px;
              grid-template-rows: repeat(3, 300px);
              grid-template-areas:
                ". header  header"
                "sidebar content content"
                "sidebar .  .";
          • 定義三行三列,通過grid-template-areas來劃分區塊,并為其命名, . 表示空
        1. grid-area:放置元素
        2.   .sidebar {
              grid-area: sidebar;
            }
            ?
            .content {
              grid-area: content;
            }
            ?
            .header {
              grid-area: header;
            }
          • 規定哪個類的內容放在哪個區塊中

          ④劃分區域自動填充元素

          • grid-auto-flow
            • row 默認值,按行進行依次填充
            • column,按列進行依次填充
            • 附加值dense,是否緊湊填充,可以自動在后方找到合適大小的塊填充到前面的單元格中,防止按序填充時出現元素過大填充不滿的現象

          ⑤自由安排元素位置

          • grid-column-start、grid-column-end、grid-row-start、grid-row-end:分別對應網格的上邊框位置、下邊框位置、左邊框位置、右邊框位置,通過這四個元素將內容定位到網格中(左上方頂點為1,向右向下遞增)
            • span:聲明項目跨度(占幾個格子),在start中設置,end就可以不用設置
          • 簡寫形式:grid-area: 2 / 1 / 4 / 3(其中,2表示起始行,1表示起始列,4表示結束行,3表示結束列)

          ⑥所有元素在單元格內的對齊方式

          • justify-items / align-items:水平/垂直對齊方式
            • start
            • end
            • center
            • stretch(默認)
          • place-items:水平和垂直的合并形式,寫兩個就是左水平右垂直,寫一個就是兩者共用

          ⑦單個元素在單元格內的對齊方式

          • justify-self、align-self、place-self:與⑥中用法完全一致,只是針對單個元素使用

          ⑧單元格在容器內的對齊方式

          • justify-content / align-content:水平/垂直對齊方式
            • start(默認)
            • end
            • center
            • stretch
            • space-between
            • space-around
            • space-evenly
          • place-content為上兩者的合并形式

          ⑨多出來的東西怎么放?隱式網格

          • grid-auto-columns / grid-auto-rows:定義隱式網格的單元格長寬

          一些面試題

          1. 請解釋什么是CSS Grid布局?
          2. Grid布局中有哪些主要的概念和術語?
          3. 請解釋Grid容器和Grid項之間的區別是什么?
          4. 如何在父元素上應用Grid布局?
          5. 請解釋Grid布局中的行和列是如何定義的?
          6. 如何指定Grid項在網格中的位置?
          7. Grid布局中的重疊和層疊是如何處理的?
          8. 如何控制Grid項的大小和對齊方式?
          9. 請解釋Grid布局的自動布局機制。
          10. 如何媒體查詢和響應式設計與Grid布局結合使用?

          ?選擇器

          基本選擇器:id class 標簽 層次選擇器:后代、子代、兄弟、通用 結構選擇器:第一個、最后一個、奇數偶數個、偽類、偽元素 屬性選擇器:屬性

          ?animation有哪些屬性

          CSS 的 animation 屬性用于為元素添加動畫效果。以下是 animation 屬性的一些常用子屬性:

          1、animation-name: 定義動畫的名稱。

          .animation {
            animation-name: myAnimation;
          }
          ?
          @keyframes myAnimation {
            0% { opacity: 0; }
            100% { opacity: 1; }
          }

          2、animation-duration: 定義動畫的持續時間。

          .animation {
            animation-name: myAnimation;
            animation-duration: 2s;
          }

          3、animation-timing-function: 定義動畫的時間函數(即動畫進度的加速度)。

          .animation {
            animation-name: myAnimation;
            animation-timing-function: ease-in-out;
          }

          4、animation-delay: 定義動畫開始之前的延遲時間。

          .animation {
            animation-name: myAnimation;
            animation-delay: 1s;
          }

          5、animation-iteration-count: 定義動畫的播放次數,infinite為永不停止。

          .animation {
            animation-name: myAnimation;
            animation-iteration-count: 3;
          }

          6、animation-direction`: 定義動畫的播放方向。

          .animation {
            animation-name: myAnimation;
            animation-direction: reverse;
          }

          7、animation-fill-mode: 定義動畫在播放之前和之后如何應用樣式。

          1. none:默認值,動畫不會對元素應用任何樣式。在非活動時間段,元素將恢復到初始樣式。
          2. forwards:在動畫結束后,元素將保持動畫結束狀態。也就是說,元素將保持在最后一幀的狀態。
          3. backwards:在動畫開始前,元素將立即應用動畫的第一幀樣式。這意味著動畫開始前的狀態會提前被應用。
          4. both:結合了 forwards 和 backwards,在動畫開始前和結束后都會應用樣式。
          .animation {
            animation-name: myAnimation;
            animation-fill-mode: forwards;
          }

          8、animation-play-state: 定義動畫的播放狀態。

          .animation {
            animation-name: myAnimation;
            animation-play-state: paused;
          }

          這些是 animation 屬性的一些常用子屬性,它們可以用來控制動畫的各個方面,從而創建出豐富多樣的動畫效果。使用這些屬性可以自定義動畫的外觀、持續時間、延遲等。要實現動畫效果,還需要定義動畫的關鍵幀(@keyframes)規則,包含動畫在不同百分比時的樣式。

          在 CSS 中,可以使用 @keyframes 規則來定義動畫的關鍵幀(即動畫的不同階段)。@keyframes 規則定義了動畫的每個關鍵幀以及相應的樣式。

          下面是一個使用 @keyframes 定義動畫關鍵幀的示例:

          @keyframes slide {
            0% {
              transform: translateX(0);
            }
            50% {
              transform: translateX(100px);
            }
            100% {
              transform: translateX(200px);
            }
          }

          在這個例子中,我們創建了一個名為 slide 的動畫。通過 @keyframes 規則,我們定義了三個關鍵幀:0%、50% 和 100%。

          • 在 0% 關鍵幀,元素的 transform 屬性設置為 translateX(0),即初始狀態。
          • 在 50% 關鍵幀,元素的 transform 屬性設置為 translateX(100px),表示動畫進行到一半時的狀態。
          • 在 100% 關鍵幀,元素的 transform 屬性設置為 translateX(200px),表示動畫結束時的狀態。

          你可以在關鍵幀中定義任意數量的狀態,并根據需要設置不同的樣式屬性。使用百分比來表示關鍵幀的時間點,動畫會根據關鍵幀之間的插值進行平滑過渡。

          定義完關鍵幀后,你可以使用 animation-name 屬性將動畫應用到具體的元素上,如下所示:

          .element {
            animation-name: slide;
            animation-duration: 2s;
          }

          通過將 animation-name 設置為關鍵幀名稱,你可以將定義好的動畫應用于元素,并設置動畫的持續時間(在此示例中為 2 秒)。

          請注意,在實際使用中,除了設置關鍵幀的樣式,你還可以使用其他屬性調整動畫的速度、延遲、重復次數等。根據具體需求,你可以進一步完善動畫效果。

          ?說說transition

          CSS 的 transition 屬性用于在元素發生狀態變化時,平滑地過渡(或動畫)到新的樣式。它允許你控制一個或多個 CSS 屬性的變化過程,使得元素的變化更加柔和和可控。

          transition 屬性由以下幾個子屬性組成:

          1、transition-property:指定要過渡的 CSS 屬性名稱,可以是單個屬性,也可以是多個屬性。 當 transition 屬性只設置了 transition-duration 值時,沒有指定 transition-property 值,默認情況下所有可過渡的 CSS 屬性都會應用過渡效果。

          .element {
            transition-property: width;
          }

          2、transition-duration:指定過渡的持續時間,以秒(s)或毫秒(ms)為單位。

          .element {
            transition-duration: 0.5s;
          }

          3、transition-timing-function:指定過渡的時間函數,用于控制過渡的速度曲線。常見的值包括 ease(默認值)、linear、ease-in、ease-out 和 ease-in-out,也可以使用貝塞爾曲線來定義自定義的速度曲線。

          .element {
            transition-timing-function: ease-in-out;
          }

          4、transition-delay:指定過渡開始之前的延遲時間,以秒(s)或毫秒(ms)為單位。

          .element {
            transition-delay: 0.2s;
          }

          通過使用這些子屬性,你可以控制元素的過渡效果,從而實現例如懸停時顏色漸變、尺寸變化、透明度漸變等效果。

          例如,下面的代碼演示了一個當鼠標懸停在元素上時,背景顏色發生漸變過渡的效果:

          .element {
            background-color: blue;
            transition-property: background-color;
            transition-duration: 0.5s;
            transition-timing-function: ease-in-out;
          }
          ?
          .element:hover for(let [key, value] of map) {
                  if(largeStr.indexOf(key)!==-1) {
                      
                  }
              }
            background-color: red;
          }

          以上代碼將使元素的背景顏色在懸停時從藍色平滑地過渡到紅色,過渡時間為 0.5 秒,速度曲線為先加速后減速。這只是 transition 屬性的一個簡單示例,你可以根據需要調整和組合這些子屬性來實現更復雜的過渡效果。

          ?外邊距塌陷解決方案

          外邊距塌陷是指在垂直方向上,兩個相鄰元素的外邊距(margin)合并成一個外邊距的現象。以下是幾種常見的外邊距塌陷情況及其解決方案:

          1. 父子元素外邊距塌陷:
          2. 情況:父元素的上邊距與第一個子元素的上邊距合并,導致外邊距塌陷。
          3. 解決方案:給父元素添加 overflow: hidden; 或 float: left/right; 屬性,為父元素創建新的塊級格式化上下文(BFC),從而阻止外邊距的合并。
          4. 相鄰兄弟元素外邊距塌陷:
          5. 情況:兩個相鄰的兄弟元素,上一個元素的下邊距與下一個元素的上邊距合并,導致外邊距塌陷。
          6. 解決方案:給其中一個元素添加 padding-top 或 border-top 屬性,或者在兩個元素之間插入空元素(例如 <div></div>)。
          7. 空元素與外邊距塌陷:
          8. 情況:一個沒有內容的空元素或沒有上邊框/上內邊距的元素,上邊距與其下面的元素的上邊距合并,導致外邊距塌陷。
          9. 解決方案:給空元素添加 padding-top 或 border-top 屬性,或者為其添加 display: inline-block; 屬性。
          10. 內部包含塊的外邊距塌陷:
          11. 情況:一個元素的內部包含塊(例如 <div>)中的第一個子元素的上邊距與外部元素的上邊距合并,導致外邊距塌陷。
          12. 解決方案:為外部元素添加 overflow: hidden; 或 float: left/right; 屬性,將其變為 BFC,阻止外邊距合并。

          這些解決方案的原理都是通過改變元素的布局特性來創建新的塊級格式化上下文(BFC),從而阻止外邊距的合并。BFC 可以獨立地控制元素的布局行為,使得外邊距不再發生塌陷。

          ?說一說overflow的各個值

          • visible:正常顯示,多余部分超出盒子顯示
          • scroll:默認顯示滾動條
          • hidden:不提供滾動條,也不支持用戶滾動,多于內容會被裁剪,但可以通過腳本控制滾動
          • clip:和hidden類似,但不允許通過腳本滾動,也不會生成BFC
          • auto:溢出顯示滾動條,不溢出則不顯示,生成BFC
          • overlay:行為與auto相同,但滾動條繪制在內容之上,不占據空間

          ?說說偽類和偽元素

          偽類: 用于已有元素處于某種狀態時為其添加對應的樣式,這個狀態是根據用戶行為而動態變化的

          例如:當用戶懸停在指定元素時,可以通過:hover來描述這個元素的狀態,雖然它和一般css相似,可以為 已有元素添加樣式,但是它只有處于DOM樹無法描述的狀態下才能為元素添加樣式,所以稱為偽類

          偽元素: 用于創建一些不在DOM樹中的元素,并為其添加樣式

          例如,我們可以通過:before來在一個元素之前添加一些文本,并為這些文本添加樣式,雖然用戶可以看見 這些文本,但是它實際上并不在DOM文檔中

          ?引入樣式時,link和@import的區別?

          1. 加載順序: <link> 在頁面加載時同時被加載,而 @import 在頁面加載后才被加載。因此,<link> 可以更快地加載外部資源,并且不會阻塞頁面的加載,而 @import 會延遲頁面的顯示,直到所有的 CSS 文件加載完畢。
          2. 兼容性: <link> 是 HTML 標簽,可以被所有瀏覽器和搜索引擎正確解析。而 @import 是 CSS 的語法規則,只能被符合 CSS3 規范的瀏覽器正確解析,低版本的瀏覽器可能會忽略 @import 聲明。
          3. 使用方式: <link> 可以用于加載任何類型的文件,如 CSS、JavaScript、圖像、音頻等。而 @import 只能用于加載 CSS 文件。
          4. 作用域: <link> 中的樣式表對整個頁面都起作用,而 @import 只對當前樣式表中的規則起作用。

          綜上所述,<link> 更適合引入外部資源,而 @import 更適合在 CSS 文件中嵌入其他 CSS 文件。如果需要同時加載多個 CSS 文件,最好使用 <link>,以提高頁面的性能和可訪問性。

          ?display、visibility、opacity的區別

          • display:none; DOM結構:瀏覽器不會渲染display屬性為none的元素,不占據空間,意思就是頁面上沒有它的一席之地,你在開發者模式中選不中那個元素。 事件監聽:無法進行DOM事件監聽。 性能:動態改變此屬性時會引起回流,性能較差。 繼承:不會被子元素繼承,因為子元素也不被渲染。 transtion過渡不支持display。
          • visibility:hidden; DOM結構:元素被隱藏了,瀏覽器會渲染visibility屬性為hidden的元素,占據空間,意思就是頁面上有它的空間,在開發者模式中能選中那個元素。 事件監聽:無法進行DOM事件監聽。 性能:動態改變此屬性時會引起重繪,性能較高。 繼承:會被子元素繼承,子元素通過設置visibility:visible;來顯示自身,使子元素取消自身隱藏。 transtion:visibility會立即顯示,隱藏時會延時。
          • opacity:0; DOM結構:opacity屬性值為0時透明度為100%,元素隱藏,占據空間,opacity值為0到1,為1時顯示元素。 事件監聽:可以進行DOM事件監聽。 性能:提升為合成層,不會引發其他元素的重繪,性能較高。 繼承:會被子元素繼承,子元素不能通過設置opacity:1;來取消隱藏。 transtion:opacity可以延時顯示與隱藏。

          JS

          ?簡述JavaScript對象、函數、數組的定義。

          對象(Object):JavaScript 的對象是一種復合數據類型,用于存儲鍵值對。對象由一組屬性(properties)組成,每個屬性都有一個鍵(key)和對應的值(value)。對象可以通過字面量表示法或構造函數來創建。

          函數(Function):JavaScript 是一門函數式編程語言,函數在 JavaScript 中是一等公民。函數是可執行的代碼塊,可以接收參數并返回一個值。可以通過函數聲明或函數表達式的方式定義函數。

          數組(Array):JavaScript 數組是一種有序、可變的數據集合,可以存儲多個值。數組可以包含不同類型的數據,并且長度是動態的。可以使用字面量表示法或構造函數來創建數組。

          ?說說JS中的隱式轉換

          隱式類型轉換是指 JavaScript 在比較或計算操作中自動將一個數據類型轉換為另一個數據類型。這種類型轉換是根據 JavaScript 的類型轉換規則進行的,以下是一些常見的隱式類型轉換規則:

          ==

          1. 字符串和數字之間的比較:如果一個操作數是字符串,另一個操作數是數字,JavaScript 會將字符串轉換為數字,然后進行比較。
          2. 布爾值和其他類型之間的比較:布爾值在進行比較時,會被轉換為數字,true 被轉換為 1,false 被轉換為 0。
          3. 對象和原始值之間的比較:對象在進行比較時,JavaScript會先使用 valueOf() 方法獲取對象的原始值,然后再根據前面提到的方法將兩個值進行比較。如果 valueOf() 方法無法返回原始值,則會嘗試調用 toString() 方法來獲取值。
          4. null 和 undefined 的比較:它們在進行相等比較時被認為是相等的。

          運算

          1. string+其他基本數據類型,轉為string
          2. 其他基本數據類型與的number類型操作,均轉為number

          補充問題:

          當a為多少時,if判斷成立

          let a
          if(a == 1&&a == 2&&a == 3) {
              console.log('success!') 
          }

          答案:

          a = {
              a:1,
              valueOf() {
                  return a++
              }
          }

          前端性能優化

          首屏優化

          1. 壓縮、分包(利用瀏覽器并行的能力加載)、刪除無用代碼
          2. 靜態資源分離,如放在CDN上面
          3. JS腳本非阻塞加載(或將其放在最底部,最后加載,以防阻塞頁面渲染)
          4. 合理利用緩存
          5. 服務器端渲染(SSR)
          6. 預置loading、骨架屏

          渲染優化

          1. GPU加速,利用GPU來處理復合圖層(像素密集型)進行“加速”
          2. 減少回流、重繪,例如:
            1. 避免使用CSS表達式,因為當頁面變化時,都會進行重新計算
            2. 不適用table布局,因為該布局中的一個小改動都會引起整個table重新布局,所以現在table布局已經幾乎淘汰
            3. 能使用css就不使用js
          3. 離屏渲染,正常情況下數據經過計算和渲染后,就會直接顯示在屏幕上,而使用離屏渲染,就會在內存將畫面全部渲染好,再放在頁面上,以防畫面過于復雜而使用戶感到掉幀
          4. 懶加載,將需要的資源提前加載到本地,需要時直接從緩存中取出,節約時間。

          JS優化

          1. 防止內存泄露,比如:
            1. 使用全局變量不當產生的內存泄露
            2. DOM引用沒有及時清除,導致DOM刪除后但JS引用依舊存在,占用資源
            3. 定時器沒有及時關閉(所以建議自己封裝可以自動關閉的定時器組件)
          2. 循環語句盡早break
          3. 合理使用閉包
          4. 減少DOM訪問,因為JS引擎和渲染引擎交互較為費時,如果需要常用,要使用一個變量將其緩存起來,不要每次都去查詢獲取
          5. 防抖——多次點擊,只執行最后一次
          6. 節流——一定時間內,多次調用只執行一次
          7. Web Worker(工作線程),可以將一些耗時的數據處理操作從主線程中剝離出來,使主線程更加專注于頁面渲染和交互。

          ?跨瀏覽器兼容問題

          1. CSS盒模型差異,可以使用CSS重置或使用標準化庫來進行統一各瀏覽器的默認樣式
          2. JavaScript API兼容性問題,可以通過特性檢測來判斷當前瀏覽器是否支持某個API,或使用polyfill庫來提供缺失的功能
          3. flex布局兼容性問題,可以使用grid等布局來作為替代方案

          ?如何保證代碼的質量和可維護性

          1. 模塊化,特定的模塊負責特定的功能,提高代碼的可復用性,降低耦合
          2. 通過一些設計模式來管理實例,例如單例模式、觀察者模式等
          3. 進行一些單元測試
          4. 代碼復用,提出可復用的函數及組件
          5. 錯誤處理,合理處理異常和錯誤情況
          6. 使用代碼質量檢查工具來檢查修復代碼規范問題,例如ESLint

          ?關于變量提升和函數提升的問題

          var c = 1;
          function c(c) {
              console.log(c)
          }
          c(2)
          //函數作?域:局部作?域
          var a = 1;
          function b() {
           a = 10;
           return;
           //a函數聲明,提前變量a,將a認為是函數b作?域的變量,具有局部效果
           function a(){}
          }b();
          console.log(a); // 1
          var m= 1, j = k = 0; 
          function add(n) { 
              return n = n+1; 
          } 
          y = add(m); 
          function add(n) { 
              return n = n + 3; 
          } 
          z = add(m);  

          說一下Vue2響應式的實現

          1. 創建 Vue 實例時,會調用 new Vue(),其中會通過 observe 函數對 data 數據進行觀測。
          2. 在 observe 函數中,會使用 Object.defineProperty 遞歸地遍歷所有屬性,并為每個屬性創建對應的 getter 和 setter。
          3. 在屬性的 getter 中,會進行依賴收集。首先,通過閉包引用一個全局變量 Dep.target,該變量保存當前正在計算的 Watcher 實例。然后,在 getter 中調用 dep.depend() 方法,將當前的 Watcher 添加到依賴集合中。
          4. 在屬性的 setter 中,當屬性的值發生改變時,會觸發 setter。在 setter 中,會對新值進行響應式處理(遞歸調用 observe),并通知相關的依賴進行更新。這一過程通過調用 dep.notify() 實現,dep.notify() 會遍歷依賴集合,調用每個依賴的 update 方法,觸發相應的更新操作。
          5. 在模板編譯過程中,解析模板中的指令表達式,對每個指令表達式生成對應的 Watcher 實例。Watcher 實例內部會調用屬性的 getter 方法,在 getter 中觸發依賴收集的過程,將當前 Watcher 添加到依賴集合中。
          6. 當屬性的值發生變化時,會觸發相應的更新操作。依賴收集過程中收集到的 Watcher 實例會在更新階段被遍歷,并調用其 update 方法來更新視圖。

          ?關于跨域

          跨域請求是指在瀏覽器中,當請求的源地址與請求地址的協議、域名、端口號不一致時,會被瀏覽器的同源策略所限制,這是為了保護用戶的信息安全。

          1. JSONP(JSON with Padding):JSONP通過動態創建
          2. CORS(Cross-Origin Resource Sharing):CORS是一種現代的跨域解決方案,通過在服務器端設置響應頭部,允許客戶端跨域訪問資源。在前端開發中,可以通過設置服務器的響應頭部字段Access-Control-Allow-Origin來允許特定的源進行跨域請求。
          3. 代理服務器(Proxy Server):通過在自己的服務器上設置一個代理服務器,將跨域請求轉發到目標服務器,并將目標服務器的響應返回給前端。這種方法需要對服務器進行配置,適用于無法直接修改目標服務器響應頭部的情況。
          4. WebSocket:WebSocket是一種全雙工通信協議,可以在同一域名下使用不同的端口進行跨域通信。通過建立WebSocket連接,可以實現實時通信和跨域數據傳輸。

          ?請解釋一下什么是響應式設計(Responsive Design),以及在開發響應式網站時需要考慮哪些方面,并列舉常用方法

          響應式設計(Responsive Design)是一種網頁設計和開發的方法,旨在使網站能夠適應不同設備、屏幕尺寸和瀏覽器窗口大小,以提供更好的用戶體驗。響應式設計通過使用靈活的布局、彈性的圖像和媒體查詢等技術,讓網頁能夠根據用戶設備的特性進行自適應和優化。

          在開發響應式網站時,需要考慮以下幾個方面:

          1. 彈性布局:使用相對單位(如百分比、em、rem)而不是固定像素來定義元素的尺寸和布局。這樣可以讓網頁的元素根據屏幕尺寸的變化而自動調整大小和位置。
          2. 媒體查詢:使用CSS的媒體查詢功能來檢測設備的特性(如屏幕寬度、觸摸支持等),并根據不同的條件應用不同的樣式規則。這樣可以根據不同設備的屏幕大小和特性來調整網頁的布局和樣式。
          3. 圖片優化:針對不同設備加載適當尺寸和分辨率的圖片,以減少加載時間和帶寬占用。可以使用響應式圖片技術,如<img srcset>和<picture>元素來提供多個不同尺寸的圖片,并根據設備的屏幕密度和大小選擇合適的圖片加載。
          4. 觸摸友好性:優化網頁在觸摸設備上的交互和操作體驗,比如增大可點擊區域、使用合適的手勢和觸摸事件等。
          5. 導航菜單:設計合適的導航菜單,以便在小屏幕設備上能夠輕松導航和訪問各個頁面。
          6. 測試和調試:在不同設備、不同瀏覽器和不同分辨率下進行測試和調試,以確保網頁在各種情況下都能正常顯示和運行。
          7. 性能優化:考慮網頁加載速度和性能,減少不必要的資源請求和加載,使用壓縮和緩存等技術來提高網頁的響應速度。

          以下是一些常用的技術和方法來實現響應式設計:

          1. 媒體查詢(Media Queries):使用CSS的媒體查詢功能,根據設備的特性(如屏幕寬度、設備類型等)應用不同的樣式。通過設置不同的CSS規則,可以根據設備的寬度、高度、方向等特性來改變布局和樣式。
          2. 相對單位(例如em和rem):相對單位可以根據父元素或根元素的大小進行調整。em單位相對于父元素的字體大小,rem單位相對于根元素(通常是html元素)的字體大小。使用這些相對單位可以根據設備的屏幕大小自適應調整元素的大小。
          3. 百分比布局:使用百分比作為元素的寬度、高度等屬性值,以便根據容器的大小來調整元素的尺寸。
          4. 視口單位(例如vw、vh):視口單位是相對于視口寬度和高度的單位。vw表示視口寬度的百分比,vh表示視口高度的百分比。使用視口單位可以根據屏幕的實際尺寸來調整元素的大小。
          5. 彈性盒布局(Flexbox):彈性盒布局是一種靈活的布局方式,可以使容器中的元素在不同尺寸的屏幕上自動調整位置和大小。
          6. 柵格布局(Grid):網格布局是一種二維布局系統,可以將頁面劃分為行和列,并指定元素在網格中的位置。通過設置不同的網格模板和位置屬性,可以實現靈活的響應式布局。
          7. 響應式圖片:使用srcset和sizes屬性來提供不同尺寸的圖片,以適應不同設備的顯示需求。
          8. 斷點(Breakpoints):根據不同設備的屏幕寬度和布局需求,設置斷點來改變頁面的布局和樣式。

          ?什么是單頁面應用(SPA)?它與傳統多頁面應用相比有什么優勢和劣勢?

          單頁面應用(Single Page Application,SPA)是一種Web應用程序的架構模式,它在加載初始HTML頁面后,通過JavaScript動態地更新頁面的內容,而不需要每次頁面切換時重新加載整個頁面。

          與傳統的多頁面應用相比,SPA有以下優勢:

          1. 更好的用戶體驗:由于SPA使用了異步加載和局部更新的方式,用戶在瀏覽網站時可以享受到更流暢、快速的交互體驗,減少了頁面刷新的延遲。
          2. 較少的網絡請求:SPA通常在初始加載時會下載所有所需的JavaScript、CSS和其他靜態資源,之后只需要通過API請求數據。相比多頁面應用,SPA減少了對服務器的頻繁請求,提高了性能。
          3. 良好的代碼組織:SPA使用組件化的方式組織代碼,將頁面拆分為多個可重用的組件。這樣可以提高代碼的復用性、可維護性和可測試性,使開發工作更加高效。

          然而,SPA也存在一些劣勢:

          1. 初始加載較慢:由于SPA需要在初始加載時下載所有所需資源,首次加載時間可能會較長。這對于一些網絡條件較差的用戶來說可能是一個問題。
          2. 對SEO不友好:傳統的搜索引擎爬蟲通常會根據HTML頁面的內容進行索引,而SPA的內容是通過JavaScript動態生成的,對搜索引擎的爬取和索引不太友好。雖然有一些技術可以解決這個問題(如服務器端渲染),但相對復雜。
          3. 依賴于JavaScript:由于SPA大量依賴于JavaScript來處理頁面邏輯和數據交互,因此如果用戶禁用了JavaScript,SPA可能無法正常運行。

          ?JS垃圾回收機制

          1. 項目中,如果存在大量不被釋放的內存(堆/棧/上下文),頁面性能會變得很慢。當某些代碼操作不能被合理釋放,就會造成內存泄漏。我們盡可能減少使用閉包,因為它會消耗內存。
          2. 瀏覽器垃圾回收機制/內存回收機制:
          3. 瀏覽器的Javascript具有自動垃圾回收機制(GC:Garbage Collecation),垃圾收集器會定期(周期性)找出那些不在繼續使用的變量,然后釋放其內存。
          4. 標記清除:在js中,最常用的垃圾回收機制是標記清除:瀏覽器會為內存中所有的變量添加標記,然后再遍歷上下文,為其中所有變量及被變量引用的變量清除標記,這樣剩下被標記的就是待回收對象。 谷歌瀏覽器:“查找引用”,瀏覽器不定時去查找當前內存的引用,如果沒有被占用了,瀏覽器會回收它;如果被占用,就不能回收。 IE瀏覽器:“引用計數法”,當前內存被占用一次,計數累加1次,移除占用就減1,減到0時,瀏覽器就回收它。
          5. 優化手段:內存優化 ; 手動釋放:取消內存的占用即可。
          6. (1)堆內存:fn = null 【null:空指針對象】
          7. (2)棧內存:把上下文中,被外部占用的堆的占用取消即可。
          8. (3)防止出現隱藏類,在一開始調用構造函數生成實例時就傳入需要的變量,防止動態添加和刪除屬性
          9. (4)靜態分配和對象池
          10. 內存泄漏
          11. 在 JS 中,常見的內存泄露主要有 4 種,全局變量、閉包、DOM 元素的引用、定時器

          ?JS 中 this 的五種情況

          1. 作為普通函數執行時,this指向window。
          2. 當函數作為對象的方法被調用時,this就會指向該對象。
          3. 構造器調用,this指向返回的這個對象。
          4. 箭頭函數捕獲的是最近一層非箭頭函數作用域的this值,不會綁定到字面量復制的對象上。
          5. 基于Function.prototype上的 apply 、 call 和 bind調用模式,這三個方法都可以顯示的指定調用函數的 this 指向。apply接收參數的是數組,call接受參數列表,bind方法通過傳入一個對象,返回一個this綁定了傳入對象的新函數。這個函數的 this指向除了使用new時會被改變,其他情況下都不會改變。若為空默認是指向全局對象window。

          ?原型 && 原型鏈

          原型關系:

          • 每個 class都有顯示原型 prototype
          • 每個實例都有隱式原型 __ proto__
          • 實例的_ proto_指向對應 class 的 prototype

          ? 原型: 在 JS 中,每當定義一個對象(函數也是對象)時,對象中都會包含一些預定義的屬性。其中每個函數對象都有一個prototype 屬性,這個屬性指向函數的原型對象。

          原型鏈:函數的原型對象上的constructor默認指向函數本身,原型對象除了有原型屬性外,為了實現繼承,還有一個原型鏈指針_proto_ ,該指針是指向上一層的原型對象,而上一層的原型對象的結構依然類似。因此可以利用_proto_ 一直指向Object的原型對象上,而Object原型對象用Object.prototype.__ proto__ = null表示原型鏈頂端。如此形成了js的原型鏈繼承。同時所有的js對象都有Object的基本方法

          特點: JavaScript對象是通過引用來傳遞的,我們創建的每個新對象實體中并沒有一份屬于自己的原型副本。當我們修改原型時,與之相關的對象也會繼承這一改變。

          ?new運算符的實現機制

          1. 首先創建了一個新的空對象
          2. 設置原型,將對象的原型設置為函數的prototype對象。
          3. 讓函數的this指向這個對象,執行構造函數的代碼(為這個新對象添加屬性)
          4. 判斷函數的返回值類型,如果是值類型,返回創建的對象。如果是引用類型,就返回這個引用類型的對象。

          ?請解釋一下什么是事件委托(或稱事件代理),以及它在前端開發中的作用是什么?

          事件委托(或稱事件代理)是一種在前端開發中常用的技術,它利用了事件冒泡機制,將事件處理程序綁定到一個父元素上,而不是直接綁定到每個子元素上。當事件觸發時,事件會經過冒泡階段依次向上傳播至父元素,父元素可以根據事件的目標元素來判斷應該執行哪個事件處理函數。

          事件委托的作用主要有以下幾點:

          1. 減少事件處理程序的數量:通過將事件處理程序綁定到父元素上,可以避免為每個子元素都綁定事件處理程序,減少內存消耗。
          2. 動態綁定事件:對于通過 JavaScript 動態添加的子元素,使用事件委托可以自動為它們綁定事件處理程序,無需額外的操作。
          3. 簡化代碼結構:使用事件委托可以將事件處理程序集中管理,使代碼更加簡潔、可讀性更高。

          舉個例子,假設有一個列表的父元素,里面包含了多個子元素(項),我們需要為每個子元素綁定點擊事件,實現點擊子元素時改變其樣式。使用事件委托可以這樣處理:

          // 獲取父元素
          const parentElement = document.getElementById('parent');
          ?
          // 綁定點擊事件到父元素
          parentElement.addEventListener('click', function(event) {
            // 判斷事件目標是否是子元素(項)
            if (event.target && event.target.nodeName === 'LI') {
              // 執行事件處理邏輯,例如改變樣式
              event.target.classList.toggle('active');
            }
          });

          通過將點擊事件綁定到父元素上,無論新增或刪除了子元素,甚至是動態生成的子元素,都會自動觸發相應的事件處理邏輯,大大簡化了代碼的管理和維護。

          ?說說你常用的ES6新特性

          • 塊級作用域(Block Scope): 使用 let 和 const 關鍵字聲明的變量具有塊級作用域,即只在當前代碼塊中有效。相比于 var 聲明的變量具有函數作用域而言,這種方式更加靈活和可控。
          • 箭頭函數(Arrow Function): 箭頭函數通過 => 符號定義,可以簡化函數的書寫。它具有以下特點:
            • 自動綁定上下文:箭頭函數不會創建自己的 this,而是繼承外層作用域的 this。
            • 省略 return 關鍵字:當函數體只有一條返回語句時,可以省略 return 關鍵字。
            • 更簡潔的語法:當只有一個參數時,可以省略括號;當函數體為空時,可以使用 () => {} 表示。
          • 解構賦值(Destructuring Assignment): 解構賦值允許從數組或對象中提取值并賦給變量。例如,可以通過以下方式提取數組元素:
           Codeconst [a, b] = [1, 2];

          也可以通過以下方式提取對象屬性:

           Codeconst { name, age } = { name: 'Alice', age: 18 };
          • 模板字符串(Template Strings): 模板字符串使用反引號 `` 包裹,并支持在字符串中插入變量或表達式。例如:
           Codeconst name = 'Alice';
          console.log(`Hello, ${name}!`);
          • 擴展運算符(Spread Operator): 擴展運算符用于展開可迭代對象(如數組和字符串),將其元素逐個展開,例如:
           Codeconst arr = [1, 2, 3];
          console.log(...arr); // 輸出:1 2 3
          • 類(Class): ES6 引入了類語法,可以使用 class 關鍵字定義一個類。類可以包含構造函數、實例方法、靜態方法等。例如:
           Codeclass Person {
            constructor(name) {
              this.name = name;
            }
          ?
            sayHello() {
              console.log(`Hello, my name is ${this.name}!`);
            }
          ?
            static getInfo() {
              console.log('This is a person class.');
            }
          }
          ?
          const person = new Person('Alice');
          person.sayHello();     // 輸出:Hello, my name is Alice!
          Person.getInfo();      // 輸出:This is a person class.
          • 簡化對象字面量(Object Literal Shorthand): 當定義對象字面量時,如果屬性名和變量名相同,可以直接省略寫屬性值。例如:
           Codeconst name = 'Alice';
          const age = 18;
          ?
          const person = { name, age };
          console.log(person);   // 輸出:{ name: 'Alice', age: 18 }
          • 模塊化(Module): ES6 引入了模塊化概念,可以將代碼拆分為多個模塊,每個模塊有自己的作用域,并通過 importexport 關鍵字進行模塊之間的導入和導出。例如:
          // moduleA.js
          export function greet(name) {
            console.log(`Hello, ${name}!`);
          }
          ?
          // moduleB.js
          import { greet } from './moduleA.js';
          greet('Alice');       // 輸出:Hello, Alice!
          • Promise: Promise 是用于處理異步操作的對象,避免了傳統的回調地獄。它表示一個異步操作的最終完成或失敗,并可以鏈式調用 thencatchfinally 方法處理結果。例如:
          function fetchData() {
            return new Promise((resolve, reject) => {
              // 異步操作...
              if (/* 異步操作成功 */) {
                resolve('Data fetched successfully!');
              } else {
                reject('Failed to fetch data!');
              }
            });
          }
          ?
          fetchData()
            .then(data => console.log(data))        // 成功時執行
            .catch(error => console.error(error))   // 失敗時執行
            .finally(() => console.log('Done'));    // 不論成功與否都執行
          • 數組方法(Array Methods): ES6 提供了許多方便的數組方法來處理和遍歷數組,如 forEachmapfilterreduce 等。這些方法提供了更簡潔、可讀性更高的方式來操作數組。例如:
          javascript Codeconst numbers = [1, 2, 3, 4];
          ?
          numbers.forEach(num => console.log(num));                 // 遍歷輸出每個元素
          const doubledNumbers = numbers.map(num => num * 2);       // 對每個元素進行操作并返回新數組
          const evenNumbers = numbers.filter(num => num % 2 === 0); // 過濾出符合條件的元素
          const sum = numbers.reduce((acc, num) => acc + num, 0);    // 對數組進行累加

          說一說apply、call、bind

          apply、call 和 bind 都是 JavaScript 中用于改變函數執行上下文(this)的方法,它們的區別如下:

          1. apply:
          2. 語法:function.apply(thisArg, [argsArray])
          3. 參數:需要指定函數執行時的上下文對象 thisArg 和可選的參數數組 argsArray。
          4. 功能:立即調用函數,并改變函數內部的 this 指向 thisArg,同時可以傳遞一個數組或類數組對象作為參數(通過 arguments 對象傳遞參數也可以)。
          5. 示例:fn.apply(obj, [arg1, arg2])
          6. call:
          7. 語法:function.call(thisArg, arg1, arg2, ...)
          8. 參數:需要指定函數執行時的上下文對象 thisArg 和可選的多個參數 arg1, arg2, ...。
          9. 功能:立即調用函數,并改變函數內部的 this 指向 thisArg,同時可以傳遞多個參數(通過逗號分隔)。
          10. 示例:fn.call(obj, arg1, arg2)
          11. bind:
          12. 語法:function.bind(thisArg, arg1, arg2, ...)
          13. 參數:需要指定函數執行時的上下文對象 thisArg 和可選的多個參數 arg1, arg2, ...。
          14. 功能:創建一個新的函數,函數內部的 this 指向 thisArg,并且綁定了指定的參數。不會立即執行函數,而是返回一個新函數,之后可以再次調用。
          15. 示例:var boundFn = fn.bind(obj, arg1, arg2)

          總結:

          • apply 和 call 可以立即調用函數并改變函數內部的 this 指向,區別在于參數傳遞方式不同,apply 接受參數數組,而 call 接受多個參數。
          • bind 不會立即執行函數,而是返回一個新函數,函數內部的 this 指向綁定的對象,并且可以預先綁定一些參數。
          • 這三種方法都可以實現改變函數執行上下文的目的,根據具體需求選擇合適的方法。

          說一下裝箱和拆箱

          在 JavaScript 中,基本數據類型(Primitive Types)和引用數據類型(Reference Types)在處理和操作時有所不同。當我們對基本數據類型值進行屬性訪問或方法調用時,JavaScript 會將基本數據類型自動轉換為對應的包裝對象,這個過程稱為裝箱(Boxing)。

          下面以數字類型(Number)為例,簡要說明基本數據類型裝箱的過程:

          1. 創建包裝對象:當我們使用屬性或方法來訪問數字類型的值時,JavaScript 在后臺會創建一個臨時的包裝對象(Wrapper Object)。對于數字類型,創建的包裝對象是 Number 對象。
          2. 存儲值:創建的包裝對象將會存儲對應的基本數據類型值。例如,對于數字類型的裝箱過程,包裝對象中會存儲相應的數字值。
          3. 訪問屬性或方法:一旦裝箱完成,我們可以通過包裝對象來訪問屬性和方法。這些屬性和方法是與包裝對象相關聯的。例如,通過.toFixed()方法調用來格式化一個數字。
          4. 自動拆箱:當我們使用包裝對象進行操作后,如果需要將結果賦值給一個變量,JavaScript 會自動進行拆箱(Unboxing)操作,將包裝對象轉換回基本數據類型的值。

          裝箱的過程是自動發生的,JavaScript 引擎會在需要時自動執行裝箱和拆箱操作,使得開發者能夠像操作引用類型一樣操作基本類型。而這種裝箱和拆箱的過程在后臺進行,對于開發者來說是透明的。

          需要注意的是,由于裝箱過程涉及到對象的創建和數據拷貝,相比于直接操作基本類型,使用包裝對象會帶來額外的開銷。因此,在不必要的情況下,最好直接操作基本類型,而不是通過裝箱和拆箱操作。

          ?最大安全整數

          JavaScript中的最大安全整數是 9007199254740991。它可以使用 Number.MAX_SAFE_INTEGER 常量來表示。這個值是由 JavaScript 中的雙精度浮點數表示法決定的,在進行數值運算時不會丟失精度。

          超過最大安全整數的數值會導致精度丟失,可能會引發意外的結果。如果需要處理超過最大安全整數范圍的大整數,可以使用第三方的大數庫或者 BigInt 類型(ES2020 新增)來處理。BigInt 類型可以表示任意精度的整數,但是在進行數值計算時需要特別注意性能和兼容性的問題。

          ?commonjs和es模塊有什么區別?

          CommonJS(簡稱CJS)和ES Modules(簡稱ESM)是兩種不同的模塊化規范,有以下不同:

          1. 語法差異:
          2. CommonJS:使用 require() 導入模塊,使用 module.exports={xxx} 或 exports.xxx=xxx 導出模塊。
          3. ESM:使用 import 導入模塊,使用 export 導出模塊。
          4. 對于基本數據類型,ESM導入的是值的引用,CJS導入的是值的拷貝,故ESM中引入的值是常量,不允許直接修改(對象修改或新增屬性除外)
          5. 補充:如果導入的是對象,那么變量中傳遞來的就是對象的地址值,地址值進行拷貝后通過它訪問的還是同一個對象,所以這里對象導入的可以理解為都是引用
          6. 作為整體導入時(即import * as mod from xxx),這時導入的對象第一級是只讀的,如果嘗試對第一層屬性進行修改,就會報錯
          7. CJS是運行時同步加載(動態),而ESM是編譯時異步加載(靜態)
          8. CJS適用于服務端開發,ESM適用于瀏覽器端

          補充:相同點——CJS和ESM導入時,都會將整個模塊的代碼執行一遍,然后緩存執行的結果

          ?commonJS中module.exports和exports有什么區別

          每個node.js文件在執行時都會隱式的、自動的創造一個module對象,同時,module對象會創建一個名叫exports,初始值為{}的屬性:

          var module = {
              exports:{}
          }

          為了可以更好的導出對應功能模塊里的內容,它會又隱式的創建一個變量exports:

          //隱式的創建了一個變量exports
          var exports = module.exports
          ?
          //此時exports和module.exports 引用的是同一個對象
          console.log(exports === modules.exports) //true  

          所以我們通過exports.xxx = xxx的方式進行導出,它最終也是被加到了modules.exports對象中

          最終導出的是modules.exports對象,這就意味著如果我們將exports的指向改變,那么通過exports.xxx = xxx添加的導出就不會再添加到modules.exports對象中,xxx也就不會被導出

          ?如何理解JS中的異步

          JS是一門單線程語言,因為它運行在瀏覽器的渲染主線程中(當遇到JS代碼時,渲染主線程會將控制權交給js引擎來處理),而渲染主線程只有一個。

          而渲染主線程承擔著諸多工作,渲染頁面,執行js都在其中執行。

          如果用同步的方式,極有可能導致主線程產生阻塞,從而導致消息隊列中很多任務無法及時執行。

          所以瀏覽器就采取了異步措施,當某些異步任務觸發時,如定時器、網絡請求、事件監聽器等,主線程就會將任務交給其他線程去處理,自身立即結束任務執行,轉而執行后續任務,等到異步任務執行完畢,將事先傳遞的回調函數包裝成任務,加入到對應隊列(延時隊列、微任務隊列、交互隊列)的末尾排隊,等待主線程調度執行。

          在這種異步模式下,瀏覽器就不會發生阻塞,保證了單線程的流暢運行。

          ?說一說事件循環

          事件循環又叫消息循環,是瀏覽器渲染主線程的工作方式。

          在Chrome的底層實現中,它開啟了一個for的死循環,每次循環從消息隊列中取出第一個任務執行,而其他線程只需要在合適的時機將任務放到消息隊列中。

          以前我們會將消息隊列簡單分為宏任務隊列和微任務隊列,現在隨著瀏覽器環境愈發復雜,瀏覽器采用了更加靈活多變的處理方式。

          根據W3C官方解釋,每個任務都有不同的類型,同類型的任務須在同一個隊列。不同的隊列有不同的優先級(例如交互隊列優先級大于延時隊列),在一次事件循環中,由瀏覽器自行決定取哪一個隊列的任務,但瀏覽器必須有一個微任務隊列,且其優先級是最高的,必須優先調度執行。

          ?JS中的計時器能做到精確計時嗎?

          不可以

          1. 計算機中采用晶體振蕩器來計時,雖然比較準確,但對比原子鐘,精確度還是不足,且會受溫度電壓等因素影響,在計算機中通常會使用網絡時間協議來進行校準。而js計時是調用操作系統中的計時函數,也就攜帶了些許偏差。
          2. 按照W3C標準,當瀏覽器中使用計時器,其嵌套層級超過五層時,之后的計時器就默認會有一個4ms的延遲,這4ms也會引起時間的偏差
          3. 而最主要的因素還是事件循環中,如果渲染主線程上有任務正在執行,就會推遲計時器的執行

          ?如何判斷一個對象是否為空

          如果使用常規的Object.getOwnPropertyNames()來判斷,雖然可以將一般的不可枚舉類型屬性也判斷出來,但無法判斷繼承的屬性以及Symbol類型值定義的屬性。所以我們需要使用Reflect.ownKeys()來進行轉換,這樣通過它返回的數組長度就能精準判斷出對象是否為空。

          ?重寫一下String.prototype.trim

          1、正則

          String.prototype.trim = function() {
              return this.replace(/(^\s*)|(\s*$)/g, "")
          }

          2、雙指針法

          .精靈圖(CSS Sprites)的優點和缺點

          精靈圖是一種網頁圖片應用處理方式。就是把網頁中很多小背景圖片整合到一張圖片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的組合進行背景圖顯示及定位,達到顯示某一部分背景圖的效果。

          精靈圖的優點:

          1、減少圖片的體積,因為每個圖片都有一個頭部信息,把多個圖片放到一個圖片里,就會共用同一個頭部信息,從而減少了字節數。

          2、減少了網頁的http請求次數,從而加快了網頁加載速度,提高用戶體驗。

          3、解決了網頁設計師在圖片命名上的困擾,只需對一張集合的圖片上命名就可以了,不需要對每一個小元素進行命名,從而提高了網頁的制作效率。

          4、更換風格方便,只需要在一張或少張圖片上修改圖片的顏色或樣式,整個網頁的風格就可以改變。維護起來更加方便。

          精靈圖的缺點:

          1.在圖片合并的時候,你要把多張圖片有序的合理的合并成一張圖片,還要留好足夠的空間,防止板塊內出現不必要的背景;這些還好,最痛苦的是在寬屏,高分辨率的屏幕下的自適應頁面,你的圖片如果不夠寬,很容易出現背景斷裂;

            2.在開發的時候比較麻煩,你要通過photoshop或其他工具測量計算每一個背景單元的精確位置,這是針線活,沒什么難度,但是很繁瑣;

          3.在維護的時候比較麻煩,如果頁面背景有少許改動,一般就要改這張合并的圖片,無需改的地方最好不要動,這樣避免改動更多的css,如果在原來的地方放不下,又只能(最好)往下加圖片,這樣圖片的字節就增加了,還要改動css。

          4.精靈圖不能隨意改變大小和顏色。精靈圖改變大小會失真模糊,降低用戶體驗,css3新屬性可以改變精靈圖顏色,但是比較麻煩,并且新屬性有兼容問題。現在一般都是用web字體(圖標字體)來代替精靈圖。

          2.什么是vue全家桶

          Vue + vue-router + vuex + axios + es6 + sass

          3.doctype是什么,網頁常見doctype及特點

           DOCTYPE是document type(文檔類型)的簡寫,在web設計中用來說明你用的XHTML或者HTML是什么版本。
           常見類型:
          1.過渡型(Transitional):要求非常寬松,它允許你繼續使用HTML4.01的標識(但是要符合xhtml的寫法),完整代碼如下:
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
           
          2.嚴格型(Strict):要求非常嚴格,你不能使用任何表現層的標識和屬性,例如<br>,完整代碼如下:
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
           
          3.框架型(Frameset):專門針對框架頁面設計使用,如果你的頁面中包含有框架(frameset),完整代碼如下:
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
           

          3.什么是web語義化,有什么好處

          Web語義化簡單來說就是為了讓頁面對人和機器更友好,讓人和機器更容易理解頁面內容。

          1.對機器來說,語義化能讓機器更精確的知道頁面中的重點和關鍵點。讓機器更容易為人篩選出想要的部分。

          2.對開發人員來說,更容開發和易維護頁面。根據頁面中的標簽名和類名就能知道哪個部分放置了哪些內容,從而提高了開發和維護的效率。

          4.你知道的HTTP 請求方式有幾種

          HTTPRequestMethod共計17種

          1.GET 請求指定的頁面信息,并返回實體主體。

          2.HEAD 類似于get請求,只不過返回的響應中沒有具體的內容,用于獲取報頭

          3.POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。

          4.PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。

          5.DELETE 請求服務器刪除指定的頁面。

          6.CONNECT HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。

          7.OPTIONS 允許客戶端查看服務器的性能。

          8.TRACE 回顯服務器收到的請求,主要用于測試或診斷。

          9.PATCH 實體中包含一個表,表中說明與該URI所表示的原內容的區別。

          10.MOVE 請求服務器將指定的頁面移至另一個網絡地址。

          11.COPY 請求服務器將指定的頁面拷貝至另一個網絡地址。

          12.LINK 請求服務器建立鏈接關系。

          13.UNLINK 斷開鏈接關系。

          14.WRAPPED 允許客戶端發送經過封裝的請求。

          15.LOCK 允許用戶鎖定資源,比如可以再編輯某個資源時將其鎖定,以防別人同時對其進行編輯。

          16.MKCOL 允許用戶創建資源

          17.Extension-mothed 在不改動協議的前提下,可增加另外的方法。

          5.css選擇器有哪些

          1.簡單選擇器

          通配符選擇器 *

          id選擇器 #id

          class選擇器 .class

          標簽選擇器 element

          2.復合選擇器

          后代選擇器 element element

          子代選擇器 element>element

          兄弟選擇器 element+element

          并列選擇器 element,element

          偽類選擇器 :link

          屬性選擇器 [attribute]

          6.css hack原理及常見hack

          原理:CSS hack是一種類似作弊的手段,以欺騙瀏覽器的方式達到兼容的目的,是用瀏覽器的兼容性差異來解決瀏覽器的兼容性問題。

          常見hack:

          1.利用瀏覽器對相同代碼的解析和支持的不同實現的hack

          比如div{ _width:80px },在ie6中能識別并解析帶下劃線的屬性,但是ie7及以上版本中識別不了。

          2.以Firefox或Webkit特有的擴展樣式實現的hack

          Firefox支持以-moz-開頭的屬性

          Webkit內核支持以-webkit-開頭的屬性

          3.以IE特有的條件注釋為基礎的hack

          <!--[ifIE8]> <style type="text/css"> #test{ color:red; } </style><![endif]-->

          比如這個樣式,可以在ie8中生效,但是其他瀏覽器則不會生效

          7.css中有哪些常見的繼承屬性

          • 文本

          1. color(顏色,a元素除外)

          2. direction(方向)

          3. font(字體)

          4. font-family(字體系列)

          5. font-size(字體大小)

          6. font-style(用于設置斜體)

          7. font-variant(用于設置小型大寫字母)

          8. font-weight(用于設置粗體)

          9. letter-spacing(字母間距)

          10. line-height(行高)

          11. text-align(用于設置對齊方式)

          12. text-indent(用于設置首航縮進)

          13. text-transform(用于修改大小寫)

          14. visibility(可見性)

          15. white-space(用于指定如何處理空格)

          16. word-spacing(字間距)

          • 列表

          1. list-style(列表樣式)

          2. list-style-image(用于為列表指定定制的標記)

          3. list-style-position(用于確定列表標記的位置)

          4. list-style-type(用于設置列表的標記)

          • 表格

          1. border-collapse(用于控制表格相鄰單元格的邊框是否合并為單一邊框)

          2. border-spacing(用于指定表格邊框之間的空隙大小)

          3. caption-side(用于設置表格標題的位置)

          4. empty-cells(用于設置是否顯示表格中的空單元格)

          • 頁面設置(對于印刷物)

          1. orphans(用于設置當元素內部發生分頁時在頁面底部需要保留的最少行數)

          2. page-break-inside(用于設置元素內部的分頁方式)

          3. widows(用于設置當元素內部發生分也是在頁面頂部需要保留的最少行數)

          • 其他

          1. cursor(鼠標指針)

          2. quotes(用于指定引號樣式)

          8.sessionStorage,localStorage,cookie區別

          ·共同點:都是保存在瀏覽器端,且同源的。

          ·區別:cookie數據始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和服務器間來回傳遞;cookie數據還有路徑(path)的概念,可以限制cookie只屬于某個路徑下。存儲大小限制也不同,cookie數據不能超過4k,同時因為每次http請求都會攜帶cookie,所以cookie只適合保存很小的數據,如會話標識。

          ·而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。sessionStorage和localStorage 雖然也有存儲大小的限制,但比cookie大得多,可以達到5M或更大。

          ·數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效,自然也就不可能持久保持;localStorage:始終有效,窗口或瀏覽器關閉也一直保存,因此用作持久數據;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。

          ·作用域不同,sessionStorage不在不同的瀏覽器窗口中共享,即使是同一個頁面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。WebStorage 支持事件通知機制,可以將數據更新的通知發送給監聽者。WebStorage的 api 接口使用更方便。

          9.JavaScript有哪些數據類型

          原始類型有6種 object,number,string,boolean,null,undefined

          10.輸出今天是星期幾

          var str = "今天是星期" + "日一二三四五六".charAt(new Date().getDay());alert(str);

          11.如何判斷一個變量是否為數組

          arr.constructor === Array 為true說明是數組類型

          arr instanceof Array 為true則是數組類型

          Object.prototype.toString.call(arr) === '[object Array]'; 為true為數組類型

          Array.isArray(arr) 為true則為數組類型

          12.實現一個js深度克隆函數

           //深度克隆
          function deepClone(obj){
          var result={},oClass=isClass(obj);
          for(key in obj){
           var copy=obj[key];
           if(isClass(copy)=="Object"){
           result[key]=arguments.callee(copy);
           }else if(isClass(copy)=="Array"){
           result[key]=arguments.callee(copy);
           }else{
           result[key]=obj[key];
           }
           }
           return result;
          }
          function isClass(o){
           if(o===null) return "Null";
           if(o===undefined) return "Undefined";
           return Object.prototype.toString.call(o).slice(8,-1);
          }
          //克隆一個數組
          var arr=["a","b","c"];
          var oNew=deepClone(arr);
          console.log(oNew);//Object {0: "a", 1: "b", 2: "c"}

          13.給定一個日期,頁面打印倒計時

          <!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>倒計時</title>

          </head>

          <body>

          <input type="text" name="time" id="time" value="2017-09-22" />

          <input type="button" name="okbtn" id="okbtn" value="確認" />

          <br />

          <p id="textp">這里顯示倒計時</p>

          </body>

          <script type="text/javascript">

          var okbtn=document.getElementById("okbtn");

          textp=document.getElementById("textp");

          okbtn.onclick=function(){

          var time=document.getElementById("time");

          var timevalue=time.value;

          //通過正則表達式確認輸入格式是否正確

          var patt=/^(\d{1,4})(-)(\d{1,2})(\d{1,2})$/;

          if(patt.test(timevalue)==false){

          //如果不正確

          textp.innerHTML="輸入格式不滿足YYYY-MM-DD";

          return false;

          }else{

          textp.innerHTML="這里顯示倒計時";

          }

          //獲取輸入的年月日

          var timearray=timevalue.split("-");

          //ShowLeftTime(timearray[0],timearray[1],timearray[2]);

          setInterval(function(){ShowLeftTime(timearray[0],timearray[1],timearray[2]);},1000);

          }

          function ShowLeftTime(year,month,date){

          //得出剩余時間

          var now=new Date();

          var endDate=new Date(year,month-1,date);

          var leftTime=endDate.getTime()-now.getTime();

          var leftsecond=parseInt(leftTime/1000);

          var day=Math.floor(leftsecond/(60*60*24));

          var hour=Math.floor((leftsecond-day*24*60*60)/3600);

          var minute=Math.floor((leftsecond-day*24*60*60-hour*3600)/60);

          var second=Math.floor(leftsecond-day*60*60*24-hour*60*60-minute*60);

          //顯示剩余時間

          textp.innerHTML="距離"+year+"年"+month+"月"+date+"日"

          +"還有"+day+"天"+hour+"小時"+minute+"分"+second+"秒";

          }

          </script>

          </html>

          14.數組去重

          //利用indexOf

          var aa=[1,3,5,4,3,3,1,4]

          function arr(arr) {

          var result=[]

          for(var i=0; i<arr.length; i++){

          if(result.indexOf(arr[i])==-1){

          result.push(arr[i])

          }

          }

          console.log(result)

          }

          arr(aa)

          //循環嵌套

          function fn(arr) {

          var result = [];

          var flag;

          for (var i = 0, len = arr.length; i < len; i++) {

          flag = false;

          for (var j = 0, len = result.length; j < len; j++) {

          if (arr[i] == result[j]) {

          flag = true;

          break;

          }

          }

          if (!flag) {

          result.push(arr[i]);

          }

          }

          return result;

          }

          15.求數組中最大值,最小值和重復次數最多的數值

          var arr = [1,2,2,3,5,5,5,6];

          var max = arr[0]; // 數組中的最大值

          var min = arr[0]; // 數組中的最小值

          var mostCount; // 數組中出現次數最多的元素

          var temp = {};

          var num = 0;

          for(var i=arr.length-1; i>=0; i--){

          if(max<arr[i]){ // 得到最大值

          max = arr[i]

          }

          if(min>arr[i]){ // 得到最小值

          min = arr[i]

          }

          if(temp[arr[i]]){ // 得到元素出現的次數,并組成obj

          temp[arr[i]] = tempObj[arr[i]]+1;

          }else{

          temp[arr[i]] = 1;

          }

          }

          for(var key in temp){ // 從對象中得到數組中出現最多的元素

          if(!mostCount){

          mostCount = key;

          }else if(temp[mostCount]<temp[key]){

          mostCount = key;

          }

          }

          console.log("最大值為"+max+"; 最小值為"+minVal+"; 次數最多的為"+mostCount);

          17.請概括什么情況下打印控制臺會提示undefined

          1.當打印的變量聲明未賦值時

          2.當打印的執行函數沒有返回值時

          18.原生實現數組快速排序

          var times=0;

          var quickSort=function(arr){

          //如果數組長度小于等于1無需判斷直接返回即可

          if(arr.length<=1){

          return arr;

          }

          var midIndex=Math.floor(arr.length/2);//取基準點

          var midIndexVal=arr.splice(midIndex,1);//取基準點的值,splice(index,1)函數可以返回數組中被刪除的那個數arr[index+1]

          var left=[];//存放比基準點小的數組

          var right=[];//存放比基準點大的數組

          //遍歷數組,進行判斷分配

          for(var i=0;i<arr.length;i++){

          if(arr[i]<midIndexVal){

          left.push(arr[i]);//比基準點小的放在左邊數組

          }

          else{

          right.push(arr[i]);//比基準點大的放在右邊數組

          }

          console.log("第"+(++times)+"次排序后:"+arr);

          }

          //遞歸執行以上操作,對左右兩個數組進行操作,直到數組長度為<=1;

          return quickSort(left).concat(midIndexVal,quickSort(right));

          };

          console.log(quickSort(arr));

          19.原生實現二分查找法

          var arr = [5,0,-56,90,12];

          var flag = false;//標志位進行優化,數組本來就是有序序列的話,無需再排序

          //先進行大的排序

          for(var i=0;i<arr.length-1;i++){

          //小的排序

          for(var j=0;j<arr.length-1-i;j++){

          //比較

          if(arr[j]>arr[j+1]){

          //交換

          var temp = arr[j];

          arr[j] = arr[j+1];

          arr[j+1] = temp;

          flag = true;

          }

          }

          //此部分為優化,已排序的話,無需再次排序

          if(flag){

          flag=false;

          }else{

          break;//已排序,無需交換

          }

          }

          //輸出新數組

          for(var i=0;i<arr.length;i++){

          document.write(arr[i]+' ');

          }

          20.正則表達式,清楚字符串前后空格

          var str=" hello ";

          str=str.replace(/^s*|s*$/g,'');

          alert(str);

          21.簡述http協議中get和post方法的區別

          1、 GET主要用于從服務器查詢數據,POST用于向服務器提交數據

          2、 GET通過URL傳遞數據,POST通過http請求體傳遞數據

          3、 GET傳輸數據量有限制,不能大于2kb,POST傳遞的數據量較大,一般大量的數據提交都是通過POST方式

          4、 GET安全性較低,容易在URL中暴漏數據,POST安全性較高

          22.什么是csrf攻擊,如何阻止

          CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。

          從上圖可以看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:

            1.登錄受信任網站A,并在本地生成Cookie。

            2.在不登出A的情況下,訪問危險網站B。

          防止方式

          (1).Cookie Hashing(所有表單都包含同一個偽隨機值)

          (2).驗證碼

          (3).One-Time Tokens(不同的表單包含一個不同的偽隨機值)

          23.服務器推送數據到前端有哪些解決方案

          一、Ajax輪詢

          用定時器不斷發送請求

          優點:實現簡單。

          缺點:這是通過模擬服務器發起的通信,不是實時通信,不顧及應用的狀態改變而盲目檢查更新,導致服務器資源的浪費,且會加重網絡負載,拖累服務器。

          二、comet

          基于 HTTP 長連接的 "服務器推" 技術,能使服務器端主動以異步的方式向客戶端程序推送數據,而不需要客戶端顯式的發出請求,目前有兩種實現方式:

          1. 基于 AJAX 的長輪詢(long-polling)方式

          優點

          客戶端很容易實現良好的錯誤處理系統和超時管理,實現成本與Ajax輪詢的方式類似。

          缺點

          需要服務器端有特殊的功能來臨時掛起連接。當客戶端發起的連接較多時,服務器端會長期保持多個連接,具有一定的風險。

          2. 基于 Iframe 及 htmlfile 的流(streaming)方式

          Comet的優缺點

          優點: 實時性好(消息延時小);性能好(能支持大量用戶)

          缺點: 長期占用連接,喪失了無狀態高并發的特點。

          三、websocket

          WebSocket是HTML5開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。WebSocket通訊協議于2011年被IETF定為標準RFC 6455,WebSocketAPI被W3C定為標準。在WebSocket API中,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。

          24.h5c3有哪些新增特性

          h5新增的標簽

          新增元素

          說明

          video

          表示一段視頻并提供播放的用戶界面

          audio

          表示音頻

          canvas

          表示位圖區域

          source

          為video和audio提供數據源

          track

          為video和audio指定字母

          svg

          定義矢量圖

          code

          代碼段

          figure

          和文檔有關的圖例

          figcaption

          圖例的說明

          main

          time

          日期和時間值

          mark

          高亮的引用文字

          datalist

          提供給其他控件的預定義選項

          keygen

          秘鑰對生成器控件

          output

          計算值

          progress

          進度條

          menu

          菜單

          embed

          嵌入的外部資源

          menuitem

          用戶可點擊的菜單項

          menu

          菜單

          template

          模板

          section

          區塊

          nav

          導航

          aside

          側邊欄

          article

          文章

          footer

          底部

          header

          頭部

          - css3

          css3被劃分為模塊,最重要的幾個模塊包括:選擇器、框模型、背景和邊框、文本效果、2D/3D 轉換、動畫、多列布局、用戶界面

          • 選擇器

          • 框模型

          • 背景和邊框

            border-radius、box-shadow、border-image、

            background-size:規定背景圖片的尺寸

            background-origin:規定背景圖片的定位區域

            background-clip:規定背景的繪制區域

          • 文本效果(常用)

            text-shadow:設置文字陰影

            word-wrap:強制換行

            word-break

            css3提出@font-face規則,規則中定義了font-family、font-weight、font-style、font-stretch、src、unicode-range

          • 2/3D轉換

            transform:向元素應用2/3D轉換

            transition:過渡

          • 動畫

          • @keyframes規則:

            animation、animation-name、animation-duration等

          • 用戶界面(常用)

            box-sizing、resize

            css3新增偽類

            :nth-child()

            :nth-last-child()

            :only-child

            :last-child

            :nth-of-type()

            :only-of-type()

            :empty

            :target 這個偽類允許我們選擇基于URL的元素,如果這個元素有一個識別器(比如跟著一個#),那么:target會對使用這個ID識別器的元素增加樣式。

            :enabled

            :disabled

            :checked

            :not

          25.正則驗證郵箱

          由于郵箱的基本格式為“名稱@域名”,需要使用“^”匹配郵箱的開始部分,用“$”匹配郵箱結束部分以保證郵箱前后不能有其他字符,所以最終郵箱的正則表達式為

          ^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$

          26.標準模式與怪異模式下盒子模型的計算方式

          兩種模式的區別:

            標準模式會被設置的padding撐開,而怪異模式則相當于將盒子的大小固定好,再將內容裝入盒子。盒子的大小并不會被padding所撐開。

          標準模式:盒子總寬度/高度 = 設置寬度/高度+padding+border

          怪異模式:盒子總寬度/高度= 內容寬度/高度 + padding + border + margin;

          27.你用到了es6中哪些新特性

          1. 默認參數

          2. 模版表達式

          3. 箭頭函數

          4. Promise

          5. 塊級作用域的let和const

          6. 模塊化

          28.描述一個閉包

          function A(){

          var x = 1;

          return function(){

          return ++x;

          }

          }

          1.存在一個函數A

          2.在函數A內部返回一個函數

          3.返回的函數引用A函數的私有變量

          4.這個返回的函數是A函數的閉包函數

          29.一個箭頭函數,如何獲取傳入的所有實參

          用無限參數

          var fn = (…args)=>{

          console.log(args);

          }

          這樣就可以打印傳入的所有參數

          注意:在箭頭函數中不能使用arguments

          30.通訊協議知道哪些?講講websocket協議。

          http、https、websocket、tcp/ip

          webSocket是H5的新協議,它先通過http請求的tcp層3次握手建立連接,然后通過請求帶的update:webSocket信息將http協議轉換成webSocket協議,再然后就可以服務端向客戶端推送信息了。Websocket建立的是長連接,它是雙工通信,允許服務器端主動推送信息到客戶端。http建立的是短連接,無狀態單工通信。


          主站蜘蛛池模板: 国产精品久久亚洲一区二区| 国产一区二区三区美女| 无码人妻一区二区三区兔费| 日本v片免费一区二区三区| 亚洲午夜精品一区二区公牛电影院| 亚洲综合在线成人一区| 麻豆AV无码精品一区二区| 亚洲一区二区三区在线网站| 亚洲乱码av中文一区二区| 日韩三级一区二区三区| 四虎精品亚洲一区二区三区| 日本一区二区三区中文字幕| 亚洲色欲一区二区三区在线观看| 精品亚洲一区二区三区在线播放| 国产一区二区精品尤物| 一区二区三区在线免费看| 国产精品电影一区二区三区| 一区二区三区四区视频在线| 美女福利视频一区| 无码中文人妻在线一区二区三区| 色综合视频一区二区三区| 无码乱人伦一区二区亚洲| 3d动漫精品啪啪一区二区中文| 亚洲日韩一区二区一无码| 无码欧精品亚洲日韩一区夜夜嗨| 国产麻豆媒一区一区二区三区| 国产AV国片精品一区二区| 97se色综合一区二区二区| 三上悠亚国产精品一区| 无码人妻av一区二区三区蜜臀| 精品黑人一区二区三区| 91福利一区二区| 日本精品视频一区二区三区| 污污内射在线观看一区二区少妇| 无码一区二区三区亚洲人妻| 国产美女一区二区三区| 亚洲综合一区二区国产精品| 国产裸体歌舞一区二区| 国产日韩AV免费无码一区二区三区| 手机福利视频一区二区| 精品国产一区二区三区香蕉|