整合營銷服務商

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

          免費咨詢熱線:

          CSS3 columns 屬性

          CSS3 columns 屬性

          指定列的寬度和數量:

          div{columns:100px3; -webkit-columns:100px3; /* Safari and Chrome */ -moz-columns:100px3; /* Firefox */}


          瀏覽器支持

          表格中的數字表示支持該屬性的第一個瀏覽器版本號。

          緊跟在 -webkit-, -ms- 或 -moz- 前的數字為支持該前綴屬性的第一個瀏覽器版本號。

          屬性




          columns50.04.0 -webkit-10.09.0 -moz-9.03.1 -webkit-37.015.0 -webkit-11.1

          屬性定義及使用說明

          Columns屬性是一個速記屬性設置列寬和列數。

          默認值:auto auto
          繼承:no
          版本:CSS3
          JavaScript 語法:object.style.columns="100px 3"

          語法

          columns: column-width column-count;

          描述
          column-width列的寬度
          column-count列數

          Column-count

          div元素的文本分成三列。

          Column-gap

          在div元素的文本分成三列,并指定一個30像素的列之間的差距。

          Column-rule

          指定列之間的規則:寬度,樣式和顏色。

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          家好,我是前端西瓜哥。

          之前因為工作上的一些原因,使用的 wangEditor 富文本編輯器的表格(table)功能并不能滿足需求,創建的表格只是設置了 width: 100%,列的寬度的自適應的效果非常不美觀。于是決定修改源碼,對表格功能做了加強,使其支持調整列寬。

          為了方便讀者理解,最近把這部分邏輯單獨抽離出來并做了優化,寫了個能獨立運行的 demo,配合這篇文章簡單說一說實現思路。

          實現思路

          1. 創建空表格

          第一步是創建空表格。要想支持表格可以設置寬度,需要在 table 元素下使用 colgroup 元素。我們根據表格列的數量,在 colgroup 下創建同等數量的 col 元素并設置寬度,就能給對應順序的列賦予寬度。效果可以查看這個 在線demo 。

          此外,表格的單元格如果沒有內容,是會發生高度塌陷的,且無法通過 min-heightheight 設置高度 。為解決這個問題,我們通常會在創建空表格時,給單元格添加 <br /> 內容。

          2. 高亮線的顯現

          第二步是實現光標劃到列之間的分割線上方時,將高亮線顯現出來。實現方式是:

          • 初始化時,在編輯器容器元素下創建一個絕對定位的 div 元素作為高亮線,并隱藏。
          • 給編輯器容器元素綁定鼠標移動事件。當光標移動到表格元素內部時,遍歷 col 元素得到所有列分隔線的位置(最左邊的不需要)。若光標位于這些分隔線附近,拿到左位移量,然后修改高亮線的位置并將其顯現出來;否則隱藏高亮線。

          3. 拖拽高亮線實現設置列寬

          前面提到,當光標懸浮在列分割線上方附近,會出現高亮線。其實為實現修改列寬,我們還要記錄一些數據:(1)對應的表格元素;(2)第幾列 rowIdx。當然光標移開時,要把這些數據清空。

          下面是拖拽這一動作的實現,涉及到鼠標按下、鼠標移動、鼠標釋放三個事件:

          • 當鼠標在高亮線上 按下 時,我們要將上面的數據拷貝一份,然后再記錄好要修改的(3)列的寬度;(4)光標左偏移量 left(后面要用來計算相對移動位置)(5)對應的 col 元素。
          • 在鼠標按下不釋放的情況下,移動鼠標,就代表著 拖拽 這一動作的發生。此時,我們計算光標的相對左移動,給對應的 col 元素設置寬度,就能實現動圖上的效果。
          • 鼠標釋放,將這些數據重置為空。

          因為只需要得到拖拽的相對位置,所以我們不是必須要將事件綁定到編輯器容器上。另外為了確保鼠標釋放事件正在發生,最終我選擇在 document 元素上綁定事件。document 元素上綁定的鼠標釋放事件,按下鼠標后,即便在瀏覽器外面釋放鼠標,也能觸發。

          另外,為處理列寬過小,甚至計算出負值的情況,我們需要設置一個最小列寬。

          代碼實現

          那么這里就簡單講解一下核心代碼。

          首先是創建空表格:

          const DEFAULT_COL_WIDTH = 80
          const DEFAULT_COL_SIZE = 5
          const DEFAULT_ROW_SIZE = 5
          // 生成空 table
          function createTable(row = DEFAULT_ROW_SIZE, col = DEFAULT_COL_SIZE, hasTh = false, colWidth = DEFAULT_COL_WIDTH) {
            const tbody = document.createElement('tbody')
            let tr, td
            for (let i = 0; i < row; i++) {
              tr = document.createElement('tr')
              tbody.appendChild(tr)
              for (let j = 0; j < col; j++) {
                td = document.createElement((i === 0 && hasTh) ? 'th' : 'td')
                td.innerHTML = '<br />' // 填充點東西,處理單元格高度塌陷問題
                tr.appendChild(td)
              }
            }
            const colgroup = document.createElement('colgroup')
            let colElm
            for (let i = 0; i < col; i++) {
              colElm = document.createElement('col')
              colElm.style.width = colWidth + 'px'
              colgroup.appendChild(colElm)
            }
            const table = document.createElement('table')
            table.appendChild(colgroup)
            table.appendChild(tbody)
            return table
          }
          

          顯現高亮線的核心實現邏輯如下。計算左偏移量使用了 getBoundingClientRect() 方法和鼠標事件中得到的 clientX 坐標。其中還需要注意坐標系有 “相對表格” 和 “相對編輯器容器” 兩種。

          const hl = new HL(editorEl) // 高亮線對象
          // ...
          let lastState = {} // 高亮線出現時,記錄對應的 tableEl 和 rowIdx
          function handleMovemove(event) {
            // 找到最近的table父元素
            const nearestTable = getNearestTable(event.target, editorEl)
            if (!nearestTable) {
              hl.hideHL()
              lastState = {}
              return
            }
            const tableLeftByViewport = nearestTable.getBoundingClientRect().left
            const cursorLeftByTable = event.clientX - tableLeftByViewport
            const tableLeftByEditor = tableLeftByViewport - editorEl.getBoundingClientRect().left
            //accurateLeft 為精準的列分割線上的左偏移量
            const { idx: rowIdx, left: accurateLeft } = getNearestRowBorder(nearestTable, cursorLeftByTable)
            if (rowIdx !== -1) {
              hl.drawHL(nearestTable, tableLeftByEditor + accurateLeft) // 轉換為相對 editor 容器的左偏移量
              lastState = { tableEl: nearestTable, rowIdx } // 保存 table 元素和 列索引,鼠標按下時要用到。
              editorEl.style.cursor = 'col-resize'
            } else {
              hl.hideHL()
              lastState = {}
            }
          }
          

          然后是拖拽的邏輯。dragState.tableEl 除了記錄保存當前表格元素,還在 moveover 事件中做是否觸發拖拽的標識。

          // 拖拽過程中保存的變量
          const emptyDragState = {
            tableEl: undefined,
            rowIdx: undefined,
            col: null,
            width: undefined,
            left: undefined,
          }
          let dragState = {...emptyDragState}
          function dragMouseDown(event) {
            // TODO: 需要點左鍵才執行
            const { tableEl, rowIdx } = lastState
            if (!tableEl) return
            const col = getCol(tableEl, rowIdx)
            const width = parseFloat(col.style.width)
            const left = event.clientX
            dragState = { ...dragState, ...lastState, col, width, left }
          }
          function dragMouseover(event) {
            const { left, tableEl, width, rowIdx } = dragState
            if (!tableEl) return
            const offset = event.clientX - left
            setColWidth(tableEl, rowIdx, width + offset)
          }
          function dragMouseup() {
            dragState = {...emptyDragState}
          }
          

          結尾

          俗話說的好,“Talk is cheap, show me your code!”。如果你對里面的實現細節感興趣的話,請去我的在線 demo 閱讀源碼和測試:

          https://codepen.io/F-star/pen/eYWjKBg?editors=1010

          篇系統介紹了flex的語法及基本知識,如果您還不熟悉flex知識,點擊這里先看看《 前端入門——彈性布局(Flex)》。本篇將結合flex基本知識去實現常見的網頁布局效果,常見的經典網頁布局有:

          上下結構,頭部高度固定,下部區域高度自適應。

          上下結構

          html:

          <main>
            <header>header</header>
            <section>content</section>
          </main>

          css:

          main{
            width:100%;
            height:100vh;
            display:flex;
            flex-direction: column;
          }
          main > header{
            height: 100px;
            background: #cdf0fd;
          }
          main > section{
            flex-grow:1;
          }

          左右結構,左邊寬度固定,右邊區域寬度自適應。

          左右結構

          html:

          <main>
            <nav>left nav</nav>
            <section>content</section>
          </main>

          css:

          main{
            width:100%;
            height:100vh;
            display:flex;
          }
          main > nav{
            width:150px;
            background: #cdf0fd;
          }
          main > section{
            flex-grow:1;
          }

          上中下結構,頭部和底部高度固定,中間區域高度自適應。

          上中下結構

          html:

          <main>
          <header>header</header>
          <section>content</section>
          <footer>footer</footer>
          </main>

          css:

          main{
            width:100%;
            height:100vh;
            display:flex;
            flex-direction: column;
          }
          main > header,
          main > footer{
              height: 100px;
              background: #cdf0fd;
            }
          main > section{
            flex-grow:1;
          }

          左中右結構,左邊和右邊寬度固定,中間區域寬度自適應。

          左中右結構

          html:

          <main>
          <nav>left nav</nav>
          <section>content</section>
          <aside>right aside</aside>
          </main>

          css:

          main{
            width:100%;
            height:100vh;
            display:flex;
          }
          main > nav,
          main > aside{
              width:150px;
              background: #cdf0fd;
            }
          main > section{
            flex-grow:1;
          }

          圣杯布局,就是中間區域再嵌套其它結構。

          1、上中下結構里,中間區域嵌套左中右結構

          圣杯布局1

          html:

          <main>
           <header>header</header>
          <section>
             <!--嵌套左中右結構-->
              <nav>left nav</nav>
              <section>content</section>
              <aside>right aside</aside>
          </section>
          <footer>footer</footer>
          </main>

          css:

          main{
            width:100%;
            height:100vh;
            display:flex;
            flex-direction: column;
          }
          main > header,
            main > footer{
              height: 100px;
              background: #cdf0fd;
            }
          main > section{
            flex-grow:1;
            display:flex;
          }
          /*嵌套的左中右結構*/
          main > section > nav,
          main > section > aside{
              width:150px;
              background: #fdcdcd;
           }
          main > section > section{
            width:100%;
            flex-grow:1;
          }

          2、左中右結構里,中間區域嵌套上中下結構

          圣杯布局2

          html:

          <main>
            <nav>left nav</nav>
            <section>
              <!--嵌套上中下結構-->
                <header>header</header>
                <section>content</section>
                <footer>footer</footer>
            </section>
          	<aside>right aside</aside>
          </main>

          css:

           main{
             width:100%;
             height:100vh;
             display:flex;
           }
          main > nav,
          main > aside{
              width:150px;
              background: #cdf0fd;
            }
          main > section{
            flex-grow:1;
            width:100%;
            display:flex;
            flex-direction: column;
          }
          /*嵌套的上中下結構*/
          main > section > header,
          main > section > footer{
              height: 100px;
              background: #fdcdcd;
            }
          main > section > section{
            flex-grow:1;
          }

          9宮格布局

          9宮格

          html:

          <main>
                  <section>content 1 </section>
                  <section>content 2 </section>
                  <section>content 3 </section>
                  <section>content 4 </section>
                  <section>content 5 </section>
                  <section>content 6 </section>
                  <section>content 7 </section>
                  <section>content 8 </section>
                  <section>content 9 </section>
              </main>

          css:

           main{
             width:100%;
             height:100vh;
             display:flex;
             flex-wrap: wrap;
           }
          main > section{
            width: 30%;
            background:#55ff00;
            margin: 1.5%;
          }

          總結

          以上是常見的經典布局,在這些布局的基礎上可以組合、拆分制作各種各樣的布局,如果結合position:fixed定位還可以實現頭部或側邊欄固定的布局效果。

          以上布局使用傳統的float、position也可以實現,只是相對來說比較麻煩一些,已不建議使用,所以了解下就可以了。

          雖然flex可以滿足大部分布局,但是flex并不擅長柵格布局,后面會介紹display:grid(網格布局),網格是一組相交的水平線和垂直線,它定義了網格的列和行。所以使用網格布局能夠構建更加復雜的網頁設計。

          感謝關注,希望能夠給你有所幫助,歡迎提出錯誤,補充。


          上篇:前端入門——彈性布局(Flex)

          下篇:前端入門 —— 網格布局(Grid)


          源碼鏈接: https://pan.baidu.com/s/1bdZM8ZcdU3FdSCp2u0sx8A?pwd=9ub2
          提取碼: 9ub2


          主站蜘蛛池模板: 色狠狠色狠狠综合一区| 夜色福利一区二区三区| 国产日韩视频一区| 国产精品一区12p| 日本在线视频一区| 国产精品成人一区无码| 国产激情无码一区二区app| 一区二区三区日本视频| 无码一区二区三区视频| 国产亚洲一区区二区在线| 国产精品一区二区久久国产| 国产在线观看一区精品 | 亚洲国产精品一区二区第四页| 国产精品一区二区无线| 国产另类TS人妖一区二区| 日韩人妻无码免费视频一区二区三区| 国产精品一区二区香蕉| 一区二区三区精品| 视频在线一区二区| 国产成人精品一区二三区熟女| 波多野结衣在线观看一区二区三区| 嫩B人妻精品一区二区三区| 日本一区二区三区精品视频| 亚洲国产一区二区三区| 国产精品无码一区二区三区免费 | 无码少妇一区二区三区浪潮AV| 中文字幕一区二区三区有限公司 | 中文字幕精品无码一区二区三区| 一区二区三区高清| 一区二区三区无码被窝影院| 中文字幕精品一区二区2021年 | 国产精品日本一区二区在线播放| 中文字幕一区一区三区| 国产在线aaa片一区二区99| 久久久精品人妻一区二区三区蜜桃 | 国产午夜精品免费一区二区三区| 国产伦精品一区二区三区四区| 无码一区二区三区在线观看| 亚洲日韩激情无码一区| 久久一区二区三区99| 四虎一区二区成人免费影院网址|