整合營銷服務商

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

          免費咨詢熱線:

          Web開發學習筆記(27)-CSS3(1)選擇器

          Web開發學習筆記(27)-CSS3(1)選擇器

          1)CSS3 中提供的新選擇器 —— 屬性選擇器:

          • 屬性選擇器

          屬性選擇器就是通過正則的方式去匹配指定屬性的元素,為其設置樣式。

          在 CSS3 中新增了三種屬性選擇器,如下所示:

          選擇器

          描述

          E[attr^=“xx”]

          選擇元素 E,其中 E 元素的 attr 屬性是以 xx 開頭的任何字符。

          E[attr$=“xx”]

          選擇元素 E,其中 E 元素的 attr 屬性是以 xx 結尾的任何字符。

          E[attr*=“xx”]

          選擇元素 E,其中 E 元素的 attr 屬性是包含 xx 的任何字符。

          例子,

          <!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>
                a[href^="#"] {
                  color: rgb(179, 255, 0);
                }
                a[href$="org"] {
                  color: rgb(195, 0, 255);
                }
                a[href*="le"] {
                  background-color: rgb(0, 255, 149);
                  color: white;
                }
              </style>
            </head>
            <body>
              <ul>
                <li><a href="#">本地鏈接</a></li>
                <li><a href="https://www.wangyelang.cn">王耶浪</a></li>
                <li><a href="https://developer.mozilla.org">Web開發</a></li>
                <li><a href="https://learningnotes.com">學習筆記</a></li>
              </ul>
            </body>
          </html>

          顯示為,

          • 在上面代碼中,我們使用 a[href^="#"] 去匹配 a 標簽中 href 屬性值以 # 開頭的元素。
          • 使用 a[href$="org"] 去匹配 a 標簽中 href 屬性值以 org 結尾的元素。
          • 使用 a[href*="le"] 去匹配 a 標簽中 href 屬性值包含 un 的元素。

          (2)子元素偽類選擇器就是選擇某元素的子元素的一種選擇器。

          在 CSS3 中,有以下幾種子元素偽類選擇器:

          選擇器

          描述

          E:first-child

          選擇元素 E 的第一個子元素。

          E:last-child

          選擇元素 E 的最后一個子元素。

          E:nth-child(n)

          選擇元素 E 的第 n 個子元素,n 有三種取值,數字、odd 和 even。注意第一個子元素的下標是 1。

          E:only-child

          選擇元素 E 下唯一的子元素。

          E:first-of-type

          選擇父元素下第一個 E 類型的子元素。

          E:last-of-type

          選擇父元素下最后一個 E 類型的子元素。

          E:nth-of-type(n)

          選擇父元素下第 n 個 E 類型的子元素,n 有三種取值,數字、odd 和 even。

          E:only-of-type

          選擇父元素唯一的 E 類型的子元素。

          E:nth-last-child(n)

          選擇所有 E 元素倒數的第 n 個子元素。

          E:nth-last-of-type(n)

          選擇所有 E 元素倒數的第 n 個為 E 的子元素。

          例子,

          <!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>
                div {
                  width: 100px;
                  height: 100px;
                  margin-top: 10px;
                  background-color: rgb(0, 255, 242);
                }
                div:nth-child(2) {
                  background-color: rgb(0, 255, 128);
                }
                div:nth-of-type(4) {
                  background-color: rgb(111, 0, 255);
                }
              </style>
            </head>
            <body>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
            </body>
          </html>
          

          顯示效果,

          • div:nth-child(2)div 的第 2 個子元素添加綠色背景顏色。
          • div:nth-of-type(4) 給父元素下第 4 個 div 子元素添加紫色背景顏色。

          (3)UI 偽類選擇器是通過元素的狀態來選擇的一種選擇器。

          在 CSS3 中有以下幾種 UI 偽類選擇器。

          選擇器

          描述

          :focus

          給獲取焦點的元素設置樣式。

          ::selection

          給頁面中被選中的文本內容設置樣式。

          :checked

          給被選中的單選框或者復選框設置樣式。

          :enabled

          給可用的表單設置樣式。

          :disabled

          給不可用的表單設置樣式。

          :read-only

          給只讀表單設置樣式。

          :read-write

          給可讀寫的表單元素設置樣式。

          :valid

          驗證有效。

          :invalid

          驗證無效。

          練習一:屬性有效性驗證

          頁面上有一個郵箱輸入框,當你的輸入滿足郵箱格式時,輸入框的背景顏色為綠色;當你的輸入不滿足要求,背景顏色為紅色。

          <!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>
                /*格式錯誤*/
                input:invalid {
                  background-color: red;
                }
                /*格式正確*/
                input:valid {
                  background-color: green;
                }
              </style>
            </head>
            <body>
              電子郵箱:<input type="email" />
            </body>
          </html>

          練習二:獲得焦點驗證

          頁面上有一個姓名輸入框和一個密碼輸入框,當聚焦輸入框時,輸入框的背景顏色會發生改變,

          <!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>
                input:focus {
                  background-color: rgb(255, 153, 0);
                }
              </style>
            </head>
            <body>
              姓名:<input type="text" /><br />
              密碼:<input type="password" />
            </body>
          </html>

          練習:

          實現一個五彩導航

          在前面的內容中,我們已經學習了 CSS3 的選擇器應用。我們在之前的章節中也做過橫向導航,這里我們結合所學的 CSS3 選擇器來實現一個升級版的導航。

          知識點

          • hover 偽類選擇器

          要求

          1. 新建一個 html 文件。
          2. <a> 標簽轉換成行內塊,寬 120px 高 58px、設置背景顏色 #FFFAE8;
          3. 當鼠標移動到鏈接上時達到以下要求:
          • 背景顏色分別變為 #E1D15E、#F9D6D1、#5BDE66、#EBAA8D、#BED780;
          • 設置圓角效果(border-radius);
          • 字體:顏色為 #fff,去掉鏈接下劃線。

          驗證測試

          按以上要求用 HTML 完成以下效果:

          解題:

          S 鼠標框選(頁面選擇)時返回對應的 HTML 或文案內容

          一、需求背景

          1、項目需求

          當用戶進行鼠標框選選擇了頁面上的內容時,把選擇的內容進行上報。

          2、需求解析

          雖然這需求就一句話的事,但是很顯然,沒那么簡單...

          因為鼠標框選說起來簡單,就是選擇的內容,但是這包含很多中情況,比如:只選擇文案、選擇圖片、選擇輸入框、輸入框中的內容選擇、iframe、等。

          簡單總結,分為以下幾點:

          1. 選擇文案時
          2. 選擇圖片、svg、iframe、video、audio 等標簽時
          3. 選擇 input、select、textarea 等標簽時
          4. 選擇 input、textarea 標簽內容時
          5. 選擇類似 字符時
          6. 鍵盤全選時
          7. 鼠標右鍵選擇
          8. 以上各模塊結合時
          9. 當包含標簽的時候,返回 html 結構,只有文本時返回文本內容

          二、技術要點

          鼠標框選包含以下幾點:

          1. debounce 防抖
          2. addEventListener 事件監聽
          3. Range 對象
          4. Selection 對象

          1、debounce

          老生常談的技術點了,這里不能用節流,因為肯定不能你鼠標選擇的時候,隔一段時間返回一段內容,肯定是選擇之后一起返回。

          這里用 debounce 主要也是用在事件監聽和事件處理上。

          • 【debounce 掘金】
          • 【debounce CSDN】

          2、addEventListener

          事件監聽,因為鼠標選擇,不僅僅是鼠標按下到鼠標抬起,還包括雙擊、右鍵、全選。

          需要使用事件監聽對事件作處理。

          • 【addEventListener MDN】

          3、Range

          Range 接口表示一個包含節點與文本節點的一部分的文檔片段。

          Range 是瀏覽器原生的對象。

          3.1. 創建 Range 實例,并設置起始位置

          <body>
            <ul>
              <li>Vite</li>
              <li>Vue</li>
              <li>React</li>
              <li>VitePress</li>
              <li>NaiveUI</li>
            </ul>
          </body>
          <script>
            // 創建 Range 對象
            const range=new Range()
            const liDoms=document.querySelectorAll("li");
            // Range 起始位置在 li 2
            range.setStartBefore(liDoms[1]);
            // Range 結束位置在 li 3
            range.setEndAfter(liDoms[2]);
            // 獲取 selection 對象
            const selection=window.getSelection();
            // 添加光標選擇的范圍
            selection.addRange(range);
          </script>


          可以看到,選擇內容為第二行和第三行

          3.1.1 瀏覽器兼容情況


          3.2. Range 屬性

          1. startContainer:起始節點。
          2. startOffset:起始節點偏移量。
          3. endContainer:結束節點。
          4. endOffset:結束節點偏移量。
          5. collapsed:范圍的開始和結束是否為同一點。
          6. commonAncestorContainer:返回完整包含 startContainer 和 endContainer 的最深一級的節點。

          3.2.1. 用我們上面創建的實例來看下 range 屬性的值


          3.2.2. 如果我們只選擇文本內容時

          只選擇 li 中的 itePres


          可以看出 range 屬性對應的值


          3.3. Range 方法

          1. cloneContents():復制范圍內容,并將復制的內容作為 DocumentFragment 返回。
          2. cloneRange():創建一個具有相同起點/終點的新范圍, 非引用,可以隨意改變,不會影響另一方。
          3. collapse(toStart):如果 toStart=true 則設置 end=start,否則設置 start=end,從而折疊范圍。
          4. compareBoundaryPoints(how, sourceRange):兩個范圍邊界點進行比較,返回一個數字 -1、0、1。
          5. comparePoint(referenceNode, offset):返回-1、0、1具體取決于 是 referenceNode 在 之前、相同還是之后。
          6. createContextualFragment(tagString):返回一個 DocumentFragment。
          7. deleteContents():刪除框選的內容。
          8. extractContents():從文檔中刪除范圍內容,并將刪除的內容作為 DocumentFragment 返回。
          9. getBoundingClientRect():和 dom 一樣,返回 DOMRect 對象。
          10. getClientRects():返回可迭代的對象序列 DOMRect。
          11. insertNode(node):在范圍的起始處將 node 插入文檔。
          12. intersectsNode(referenceNode):判斷與給定的 node 是否相交。
          13. selectNode(node):設置范圍以選擇整個 node。
          14. selectNodeContents(node):設置范圍以選擇整個 node 的內容。
          15. setStart(startNode, startOffset):設置起點。
          16. setEnd(endNode, endOffset):設置終點。
          17. setStartBefore(node):將起點設置在 node 前面。
          18. setStartAfter(node):將起點設置在 node 后面。
          19. setEndBefore(node):將終點設置為 node 前面。
          20. setEndAfter(node):將終點設置為 node 后面。
          21. surroundContents(node):使用 node 將所選范圍內容包裹起來。

          3.4. 創建 Range 的方法

          3.4.1. Document.createRange

          const range=document.createRange();

          3.4.2. Selection 的 getRangeAt() 方法

          const range=window.getSelection().getRangeAt(0)

          3.4.3. caretRangeFromPoint() 方法

          if (document.caretRangeFromPoint) {
              range=document.caretRangeFromPoint(e.clientX, e.clientY);
          }

          3.4.4. Range() 構造函數

          const range=new Range()

          3.5. Range 兼容性


          4、Selection

          Selection 對象表示用戶選擇的文本范圍或插入符號的當前位置。它代表頁面中的文本選區,可能橫跨多個元素。

          4.1. 獲取文本對象

          window.getSelection()



          4.2. Selection 術語

          4.2.1. 錨點 (anchor)

          錨指的是一個選區的起始點(不同于 HTML 中的錨點鏈接)。當我們使用鼠標框選一個區域的時候,錨點就是我們鼠標按下瞬間的那個點。在用戶拖動鼠標時,錨點是不會變的。

          4.2.2. 焦點 (focus)

          選區的焦點是該選區的終點,當你用鼠標框選一個選區的時候,焦點是你的鼠標松開瞬間所記錄的那個點。隨著用戶拖動鼠標,焦點的位置會隨著改變。

          4.2.3. 范圍 (range)

          范圍指的是文檔中連續的一部分。一個范圍包括整個節點,也可以包含節點的一部分,例如文本節點的一部分。用戶通常下只能選擇一個范圍,但是有的時候用戶也有可能選擇多個范圍。

          4.2.4. 可編輯元素 (editing host)

          一個用戶可編輯的元素(例如一個使用 contenteditable 的 HTML 元素,或是在啟用了 designMode 的 Document 的子元素)。

          4.3. Selection 的屬性

          首先要清楚,選擇的起點稱為錨點(anchor),終點稱為焦點(focus)。

          1. anchorNode:選擇的起始節點。
          2. anchorOffset:選擇開始的 anchorNode 中的偏移量。
          3. focusNode:選擇的結束節點。
          4. focusOffset:選擇開始處 focusNode 的偏移量。
          5. isCollapsed:如果未選擇任何內容(空范圍)或不存在,則為 true。
          6. rangeCount:選擇中的范圍數,之前說過,除 Firefox 外,其他瀏覽器最多為1。
          7. type:類型:None、Caret、Range

          4.4. Selection 方法

          1. addRange(range): 將一個 Range 對象添加到當前選區。
          2. collapse(node, offset): 將選區折疊到指定的節點和偏移位置。
          3. collapseToEnd(): 將選區折疊到當前選區的末尾。
          4. collapseToStart(): 將選區折疊到當前選區的起始位置。
          5. containsNode(node, partlyContained): 判斷選區是否包含指定的節點,可以選擇是否部分包含。
          6. deleteFromDocument(): 從文檔中刪除選區內容。
          7. empty(): 從選區中移除所有范圍(同 `removeAllRanges()``,已廢棄)。
          8. extend(node, offset): 將選區的焦點節點擴展到指定的節點和偏移位置。
          9. getRangeAt(index): 返回選區中指定索引處的 Range 對象。
          10. removeAllRanges(): 移除所有選區中的范圍。
          11. removeRange(range): 從選區中移除指定的 Range 對象。
          12. selectAllChildren(node): 選中指定節點的所有子節點。
          13. setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset): 設置選區的起始和結束節點及偏移位置。
          14. setPosition(node, offset):collapse 的別名

          4.5. Selection 兼容性


          三、項目實現

          1、實現思路

          1. 先獲取選擇的內容,開發 getSelectContent 函數
          2. 對獲取的內容進行判斷,是否存在 selection 實例,沒有直接返回 null
          3. 判斷 selection 實例的 isCollapsed 屬性 沒有選中,對 selection 進行 toString().trim() 操作,判斷內容 有內容,直接返回 text 類型 無內容,返回 null 有選中,則判斷內容
          4. 判斷選中的內容有沒有節點 沒有節點,則和沒有選中一樣處理,進行 toString().trim() 操作,判斷內容 有內容,直接返回 text 類型 無內容,返回 null 有節點,進行 toString().trim() 操作,判斷內容 沒有內容,判斷是否有特殊節點 有 'iframe', 'svg', 'img', 'audio', 'video' 節點,返回 html 類型 有 'input', 'textarea', 'select',判斷 value 值,是否存在 存在:返回 html 類型 不存在:返回 null 沒有特殊節點,返回 null 有內容,返回 html 類型
          5. 對鼠標 mousedown、mouseup 事件和 selectionchange、contextmenu、dblclick 事件進行監聽,觸發 getSelectContent 函數
          6. 在需要的地方進行 debounce 防抖處理

          2、簡易流程圖


          2、Debounce 方法實現

          2.1. JS

          function debounce (fn, time=500) {
            let timeout=null; // 創建一個標記用來存放定時器的返回值
            return function () {
              clearTimeout(timeout) // 每當觸發時,把前一個 定時器 clear 掉
              timeout=setTimeout(()=> { // 創建一個新的 定時器,并賦值給 timeout
                fn.apply(this, arguments)
              }, time)
            }
          }

          2.2. TS

          /**
           * debounce 函數類型
           */
          type DebouncedFunction<F extends (...args: any[])=> any>=(...args: Parameters<F>)=> void
          /**
           * debounce 防抖函數
           * @param {Function} func 函數
           * @param {number} wait 等待時間
           * @param {false} immediate 是否立即執行
           * @returns {DebouncedFunction}
           */
          function debounce<F extends (...args: any[])=> any>(
            func: F,
            wait=500,
            immediate=false
          ): DebouncedFunction<F> {
            let timeout: ReturnType<typeof setTimeout> | null
            return function (this: ThisParameterType<F>, ...args: Parameters<F>) {
              // eslint-disable-next-line @typescript-eslint/no-this-alias
              const context=this
              const later=function () {
                timeout=null
                if (!immediate) {
                  func.apply(context, args)
                }
              }
              const callNow=immediate && !timeout
              if (timeout) {
                clearTimeout(timeout)
              }
              timeout=setTimeout(later, wait)
              if (callNow) {
                func.apply(context, args)
              }
            }
          }

          3、獲取選擇的文本/html 元素

          3.1. 獲取文本/html 元素

          nterface IGetSelectContentProps {
            type: 'html' | 'text'
            content: string
          }
          /**
           * 獲取選擇的內容
           * @returns {null | IGetSelectContentProps} 返回選擇的內容
           */
          const getSelectContent=(): null | IGetSelectContentProps=> {
            const selection=window.getSelection()
            if (selection) {
              // 1. 是焦點在 input 輸入框
              // 2. 沒有選中
              // 3. 選擇的是輸入框
              if (selection.isCollapsed) {
                return selection.toString().trim().length
                  ? {
                      type: 'text',
                      content: selection.toString().trim()
                    }
                  : null
              }
              // 獲取選擇范圍
              const range=selection.getRangeAt(0)
              // 獲取選擇內容
              const rangeClone=range.cloneContents()
              // 判斷選擇內容里面有沒有節點
              if (rangeClone.childElementCount > 0) {
                // 創建 div 標簽
                const container=document.createElement('div')
                // div 標簽 append 復制節點
                container.appendChild(rangeClone)
                // 如果復制的內容長度為 0
                if (!selection.toString().trim().length) {
                  // 判斷是否有選擇特殊節點
                  const isSpNode=hasSpNode(container)
                  return isSpNode
                    ? {
                        type: 'html',
                        content: container.innerHTML
                      }
                    : null
                }
                return {
                  type: 'html',
                  content: container.innerHTML
                }
              } else {
                return selection.toString().trim().length
                  ? {
                      type: 'text',
                      content: selection.toString().trim()
                    }
                  : null
              }
            } else {
              return null
            }
          }
          /**
           * 判斷是否包含特殊元素
           * @param {Element} parent 父元素
           * @returns {boolean} 是否包含特殊元素
           */
          const hasSpNode=(parent: Element): boolean=> {
            const nodeNameList=['iframe', 'svg', 'img', 'audio', 'video']
            const inpList=['input', 'textarea', 'select']
            return Array.from(parent.children).some((node)=> {
              if (nodeNameList.includes(node.nodeName.toLocaleLowerCase())) return true
              if (
                inpList.includes(node.nodeName.toLocaleLowerCase()) &&
                (node as HTMLInputElement).value.trim().length
              )
                return true
              if (node.children) {
                return hasSpNode(node)
              }
              return false
            })
          }

          3.2. 只需要文本

          /**
           * 獲取框選的文案內容
           * @returns {string} 返回框選的內容
           */
          const getSelectTextContent=(): string=> {
            const selection=window.getSelection()
            return selection?.toString().trim() || ''
          }

          4、添加事件監聽

          // 是否時鼠標點擊動作
          let selectionchangeMouseTrack: boolean=false
          const selectionChangeFun=debounce(()=> {
            const selectContent=getSelectContent()
            console.log('selectContent', selectContent)
            // todo... 處理上報
            selectionchangeMouseTrack=false
          })
          // 添加 mousedown 監聽事件
          document.addEventListener('mousedown', ()=> {
            selectionchangeMouseTrack=true
          })
          // 添加 mouseup 監聽事件
          document.addEventListener(
            'mouseup',
            debounce(()=> {
              selectionChangeFun()
            }, 100)
          )
          // 添加 selectionchange 監聽事件
          document.addEventListener(
            'selectionchange',
            debounce(()=> {
              if (selectionchangeMouseTrack) return
              selectionChangeFun()
            })
          )
          // 添加 dblclick 監聽事件
          document.addEventListener('dblclick', ()=> {
            selectionChangeFun()
          })
          // 添加 contextmenu 監聽事件
          document.addEventListener(
            'contextmenu',
            debounce(()=> {
              selectionChangeFun()
            })
          )

          也可以進行封裝

          /**
           * addEventlistener function 類型
           */
          export interface IEventHandlerProps {
            [eventName: string]: EventListenerOrEventListenerObject
          }
          
          let selectionchangeMouseTrack: boolean=false
          const eventHandlers: IEventHandlerProps={
            // 鼠標 down 事件
            mousedown: ()=> {
              selectionchangeMouseTrack=true
            },
            // 鼠標 up 事件
            mouseup: debounce(()=> selectionChangeFun(), 100),
            // 選擇事件
            selectionchange:  debounce(()=> {
              if (selectionchangeMouseTrack) return
              selectionChangeFun()
            }),
            // 雙擊事件
            dblclick: ()=> selectionChangeFun(),
            // 右鍵事件
            contextmenu: debounce(()=> selectionChangeFun())
          }
          Object.keys(eventHandlers).forEach((event)=> {
            document.addEventListener(event, eventHandlers[event])
          })

          5、返回內容

          5.1. 純文本內容


          5.2. html 格式


          6. 完整 JS 代碼

          function debounce (fn, time=500) {
            let timeout=null; // 創建一個標記用來存放定時器的返回值
            return function () {
              clearTimeout(timeout) // 每當觸發時,把前一個 定時器 clear 掉
              timeout=setTimeout(()=> { // 創建一個新的 定時器,并賦值給 timeout
                fn.apply(this, arguments)
              }, time)
            }
          }
          
          let selectionchangeMouseTrack=false
          document.addEventListener('mousedown', (e)=> {
            selectionchangeMouseTrack=true
            console.log('mousedown', e)
          })
          document.addEventListener('mouseup', debounce((e)=> {
            console.log('mouseup', e)
            selectionChangeFun()
          }, 100))
          document.addEventListener('selectionchange', debounce((e)=> {
            console.log('selectionchange', e)
            if (selectionchangeMouseTrack) return
            selectionChangeFun()
          }))
          document.addEventListener('dblclick', (e)=> {
            console.log('dblclick', e)
            selectionChangeFun()
          })
          document.addEventListener('contextmenu',debounce(()=> {
            selectionChangeFun()
          }))
          
          const selectionChangeFun=debounce(()=> {
            const selectContent=getSelectContent()
            selectionchangeMouseTrack=false
            console.log('selectContent', selectContent)
          })
          
          const getSelectContent=()=> {
            const selection=window.getSelection();
            if (selection) {
              // 1. 是焦點在 input 輸入框
              // 2. 沒有選中
              // 3. 選擇的是輸入框
              if (selection.isCollapsed) {
                return selection.toString().trim().length ? {
                  type: 'text',
                  content: selection.toString().trim()
                } : null
              }
              // 獲取選擇范圍
              const range=selection.getRangeAt(0);
              // 獲取選擇內容
              const rangeClone=range.cloneContents()
              // 判斷選擇內容里面有沒有節點
              if (rangeClone.childElementCount > 0) {
                const container=document.createElement('div');
                container.appendChild(rangeClone);
                if (!selection.toString().trim().length) {
                  const hasSpNode=getSpNode(container)
                  return hasSpNode ? {
                    type: 'html',
                    content: container.innerHTML
                  } : null
                }
                return {
                  type: 'html',
                  content: container.innerHTML
                }
              } else {
                return selection.toString().trim().length ? {
                  type: 'text',
                  content: selection.toString().trim()
                } : null
              }
            } else {
              return null
            }
          }
          
          const getSpNode=(parent)=> {
            const nodeNameList=['iframe', 'svg', 'img', 'audio', 'video']
            const inpList=['input', 'textarea', 'select']
            return Array.from(parent.children).some((node)=> {
              if (nodeNameList.includes(node.nodeName.toLocaleLowerCase())) return true
              if (inpList.includes(node.nodeName.toLocaleLowerCase()) && node.value.trim().length) return true
              if (node.children) {
                return getSpNode(node)
              }
              return false
            })
          }

          四、總結

          1. 鼠標框選上報能監控用戶在頁面的行為,能為后續的數據分析等提供便利
          2. 基于 JS 中的 Selection 和 Range 實現的,使用原生 JS
          3. 涉及到的操作比較多,包含鍵盤、鼠標右鍵、全選等
          4. 能對框選的內容進行分類,區別 html 和 text,更方便的看出用戶選擇了哪些內容

          面是承接上文的知識點簡介:

          6.表單

          對于功能性的表單,HTML僅僅是產生表單的表面樣子,為后臺提供數據。

          創建所有表單 <form></form>

          創建一個滾動菜單,size設置在需要滾動前可以看到的表單項數目 <select multiple name=”NAME” size=</select>

          設置每個表單項的內容 <option>

          創建一個下拉菜單 <select name=”NAME”></select>

          文本框區域,列的數目設置寬度,行的數目設置高度 <textarea name=”NAME” cols=40 rows=8></textarea>

          復選框,文字在標簽后面 <input type=”checkbox” name=”NAME”>

          單選框,文字在標簽后面 <input type=”radio” name=”NAME” value=”x”>

          單行文本輸入區域,size設置以字符計的寬度 <input type=text name=”foo” size=20>

          submit(提交)按鈕 <input type=”submit” value=”NAME”>

          使用圖象的submit(提交)按鈕 <input type=”image” border=0 name=”NAME” src=”name.gif”>

          reset(重置)按鈕 <input type=”reset”>

          本來以為后面還會有更多知識點可以分享給大家,誰知都是一下雜亂無章的筆記而已

          下面我想和大家分享一下,CSS的選擇器吧

          文章如下

          在CSS中,選擇器用于選擇需要添加樣式的元素,簡單的講,就是確定你要把樣式給那個元素。在我們寫web前端的時候,選擇器的使用是非常頻繁的,合理的使用選擇器會精簡大量的代碼。小松果總結了下,CSS選擇器大致的歸類為基礎選擇器和符合選擇器兩類。

          1、基礎選擇器

          a、html標簽選擇器:

          標簽{屬性:屬性值}

          div、p、h1、span……

          b、class 類選擇器,可以共用重復:

          .name {屬性:屬性值}

          標簽中有class=”name”的元素

          c、id選擇器: 唯一性

          #name{屬性:屬性值}

          標簽中有id=”name”的元素

          d、屬性選擇器

          *[title] {屬性:屬性值}

          所有包含標題(title)的元素

          e、通配符選擇器,所有的元素:

          * {屬性:屬性值}

          例:* {margin:0; padding:0}

          2、復合選擇器

          a、 后代選擇器:

          A B { 屬性:屬性值}

          注:A指父級選擇器 B指子級選擇器

          b、偽類選擇器:

          a:link {屬性:屬性值} 默認

          a:visited {屬性:屬性值} 訪問過的鏈接

          a:hover {屬性:屬性值} 鼠標經過

          a:active {屬性:屬性值} 激活狀態(選中時的狀態)

          注:順序不能錯 l v h a,還有一個a {屬性:屬性值} ,這個也要寫,里面放超鏈接中相同屬性,不同屬性分別寫在不同的偽類選擇器中。


          主站蜘蛛池模板: 精品国产一区二区麻豆| 韩国精品一区二区三区无码视频 | 3d动漫精品成人一区二区三| 中文字幕精品亚洲无线码一区| 2022年亚洲午夜一区二区福利 | 亚洲国产美女福利直播秀一区二区| 天堂国产一区二区三区| AV无码精品一区二区三区| 久久婷婷色综合一区二区| 三级韩国一区久久二区综合| 亚洲AV无码一区二区三区久久精品| 中日韩一区二区三区| 秋霞日韩一区二区三区在线观看 | 一区二区视频在线免费观看| 亚洲av无码一区二区三区人妖| 亚洲视频一区网站| 精品国产乱子伦一区二区三区 | 久久国产精品亚洲一区二区| 国产精品乱码一区二区三区| 国产拳头交一区二区| 日韩免费无码一区二区视频| 亚洲一区免费视频| 亚洲国产精品一区第二页| 人妻少妇AV无码一区二区| 制服丝袜一区二区三区| 国产精品 一区 在线| 欧洲精品无码一区二区三区在线播放 | 亚洲国产系列一区二区三区| 亚洲AV综合色一区二区三区 | 亚洲性色精品一区二区在线| 亚洲高清美女一区二区三区| 精品永久久福利一区二区| 亚洲视频一区在线观看| 亚洲熟女综合一区二区三区| 色国产在线视频一区| 日韩精品久久一区二区三区| 日韩高清一区二区| 一区二区三区免费视频观看| 国产成人一区二区动漫精品| 国产在线观看一区二区三区四区| 鲁丝丝国产一区二区|