久久久久在线观看_又色又爽又黄的免费视频播放_一区中文字幕_日韩电影在线播放

今日焦點(diǎn) 焦點(diǎn)資訊 營銷之道 企業(yè)報(bào)道 淘寶運(yùn)營 網(wǎng)站建設(shè) 軟件開發(fā) 400電話
  當(dāng)前位置: 首頁 » 資訊 » 軟件開發(fā) » 正文

如何實(shí)現(xiàn)可拖動(dòng)table表頭

放大字體  縮小字體 發(fā)布日期:2018-02-10  來源:企業(yè)800網(wǎng)  作者:新格網(wǎng)  瀏覽次數(shù):679  【去百度看看】
核心提示:首先要說明的是,我們的項(xiàng)目使用的表格大概只分為兩類,一類是表頭不固定,就是普通的表格,另一類是表頭固定,tbody部分是可以滾動(dòng)的。需要說明的是,表頭固定的那種是需要用兩個(gè)table去實(shí)現(xiàn),做過的人應(yīng)該也都明白。前者看起來比較簡單,因?yàn)閷挾仁鞘躷head里的th影響的,后者看起來就不好處理,因?yàn)槟阌脙蓚(gè)table就會(huì)出現(xiàn)下面的情況:
首先要說明的是,我們的項(xiàng)目使用的表格大概只分為兩類,一類是表頭不固定,就是普通的表格,另一類是表頭固定,tbody部分是可以滾動(dòng)的。需要說明的是,表頭固定的那種是需要用兩個(gè)table去實(shí)現(xiàn),做過的人應(yīng)該也都明白。前者看起來比較簡單,因?yàn)閷挾仁鞘?code>thead里的th影響的,后者看起來就不好處理,因?yàn)槟阌脙蓚(gè)table就會(huì)出現(xiàn)下面的情況:

emmm,這和我們想象的應(yīng)該不一樣,這可咋整,感覺處理起來很麻煩啊。想起看過element-ui中的表格,似乎有拖動(dòng)表頭的實(shí)現(xiàn),先打開控制臺(tái)看下結(jié)構(gòu)吧:

呃,話說長這么大我都沒用過<colgroup><col>這兩個(gè)標(biāo)簽,但仔細(xì)觀察上面有個(gè)width,看到這大概也知道是怎么回事了,打開MDN看下相關(guān)屬性的描述,和想的一樣,width能控制當(dāng)前列的寬度。
寬度的控制我們是解決了,還有一個(gè)問題,就是拖動(dòng)后,其他列的寬度改怎么改變,如下:

abcd

如果我拖動(dòng)a列,改變的寬度應(yīng)該怎樣分配到b,c,d上,我這里是這樣處理的,b、c、d有個(gè)屬性去表示該列是否已經(jīng)被拖動(dòng)過了,如果b、c、d都沒拖動(dòng)過,那么把a(bǔ)改變的寬度平分到b、c、d三列的寬度上,如果b、c、d都改變了話,那么只改變最后一列d的寬度。好了,思路已經(jīng)有了,我們可以去實(shí)現(xiàn)了。
事實(shí)證明,如果按照上面的設(shè)計(jì)就太蠢了,已經(jīng)改成只改變拖動(dòng)列后面的列且這些列沒有改變過寬度。

實(shí)現(xiàn)

首先html結(jié)構(gòu)大概是這樣的:

<table>
  <thead>
    <tr>
      <th>a<th>
      <th>b<th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>1<th>
      <th>2<th>
    </tr>
  </tbody>
</table>

js方面

  constructor (id, options) {
    this._el = document.querySelector(`#${id}`);
    // 實(shí)際使用中需要對(duì)dom結(jié)構(gòu)進(jìn)行判斷,這里就不做了
    this._tables = Array.from(this._el.querySelectorAll('table'));
    setTimeout(() => this._resolveDom());

    this.store = {
      dragging: false,                 //是否拖動(dòng)
      draggingColumn: null,            //拖動(dòng)的對(duì)象
      miniWidth: 30,                   //拖動(dòng)的最小寬度
      startMouseLeft: undefined,       //鼠標(biāo)點(diǎn)擊時(shí)的clientX
      startLeft: undefined,            //th右離table的距離
      startColumnLeft: undefined,      //th左離table的距離
      tableLeft: undefined,            //table離頁面左邊的距離,
      HColumns: [],
      BColumns: [],
    };
  };

添加dom:

const [ THeader ] = this._tables;
let TBody;
const Tr = THeader.tHead.rows[0];
const columns = Array.from(Tr.cells);
const Bcolgroup = document.createElement('colgroup');
const cols = columns.map((item, index) => {
  const col = document.createElement('col');
  item.dataset.index = index;
  col.width = +item.offsetWidth;
  return col;
});
cols.reduce((newDom, item) => {
  newDom.appendChild(item);
  return newDom;
}, Bcolgroup);
const HColgroup = Bcolgroup.cloneNode(true);
THeader.appendChild(HColgroup);

//不管是一個(gè)table還是兩個(gè),都把header和body提出來
if (this._tables.length === 1) {
  const [ , tbody ] = Array.from(THeader.children);
  tbody.remove();
  TBody = THeader.cloneNode();
  TBody.appendChild(Bcolgroup);
  TBody.appendChild(tbody);
  this._el.appendChild(TBody);
} else {
  [ , TBody ] = this._tables;
  TBody.appendChild(Bcolgroup);
}

//拖動(dòng)時(shí)的占位線
const hold = document.createElement('p');
hold.classList.add('resizable-hold');
this._el.appendChild(hold);

上面這塊就是添加節(jié)點(diǎn)的,對(duì)dom進(jìn)行處理,為了復(fù)用,這里我們不管你是表頭固定還是表頭不固定,我們都拆分為兩個(gè)table,這樣處理起來也方便的多。
然后就是處理手指移到列右側(cè)cursor的值設(shè)為col-resize:

handleMouseMove(evt) {
  //...
  if (!this.store.dragging) {
    const rect = target.getBoundingClientRect();
    const bodyStyle = document.body.style;
    if (rect.width > 12 && rect.right - event.pageX < 8) {
      bodyStyle.cursor = 'col-resize';
      target.style.cursor = 'col-resize';
      this.store.draggingColumn = target;
    } else {
      bodyStyle.cursor = '';
      target.style.cursor = 'pointer';
      this.store.draggingColumn = null;
    }
  }
};

需要注意的是,getBoundingClientRect()獲取的rigth是元素右側(cè)距離頁面左邊緣的距離,不是離頁面右邊緣的距離。這里就是給theadtr添加mousemove事件,當(dāng)鼠標(biāo)指針距離右邊緣小于8的時(shí)候,改變指針形狀,然后改變store里的狀態(tài),表示此時(shí)點(diǎn)擊是可以拖動(dòng)的了。
然后就是mousedown+mousemove+mouseup來處理拖動(dòng)了:

const handleMouseDown = (evt) => {
  if (this.store.draggingColumn) {
    this.store.dragging = true;

    let { target } = evt;
    if (!target) return;

    const tableEle = THeader;
    const tableLeft = tableEle.getBoundingClientRect().left;
    const columnRect = target.getBoundingClientRect();
    const minLeft = columnRect.left - tableLeft + 30;
    target.classList.add('noclick');

    this.store.startMouseLeft = evt.clientX;
    this.store.startLeft = columnRect.right - tableLeft;
    this.store.startColumnLeft = columnRect.left - tableLeft;
    this.store.tableLeft = tableLeft;

    document.onselectstart = () => false;
    document.ondragstart = () => false;

    hold.style.display = 'block';
    hold.style.left = this.store.startLeft + 'px';

    const handleonMouseMove = (event) => {
      const deltaLeft = event.clientX - this.store.startMouseLeft;
      const proxyLeft = this.store.startLeft + deltaLeft;

      hold.style.left = Math.max(minLeft, proxyLeft) + 'px';
    };

    // 寬度是這樣分配的,舉個(gè)

以上就是如何實(shí)現(xiàn)可拖動(dòng)table表頭的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

 
關(guān)鍵詞: table,表頭,拖動(dòng)
長春  短信群發(fā)  吉林省  紅視窗  中國  長春市  玉米  長春網(wǎng)站建設(shè)  網(wǎng)站  振華  設(shè)備  設(shè)計(jì)  吉林  廣州  撲克  長春上門維修電腦  敘利亞  內(nèi)蒙古  聯(lián)合聲明  消費(fèi)者權(quán)益  突擊步槍  新聞中心  化學(xué)武器  中非合作論壇  中國政府  滿洲里  美國白宮  記者會(huì)  塞內(nèi)加爾  中消協(xié)  強(qiáng)臺(tái)風(fēng)  中國電影  消費(fèi)者  海外網(wǎng)  長春北大青鳥  中國智能建筑節(jié)  敘政府  重慶市  網(wǎng)站建設(shè)  北京市  國家元首  長春上門修電腦  產(chǎn)業(yè)園  北斗導(dǎo)航  中國芯  龍頭企業(yè)  黨委書記  長春上門做系統(tǒng)  長春電腦上門維修  塞申斯  侯建國,質(zhì)量,中國特色社會(huì)主義  售前咨詢技巧  俄羅斯  發(fā)言人  特朗普,貿(mào)易戰(zhàn),美國  運(yùn)載火箭  中國軍網(wǎng)  今日頭條  美國人  特朗普  長春國貿(mào)  位置服務(wù)  英國皇家海軍  一帶一路  中國移動(dòng)  人民政府  檢察官  中國市場(chǎng)  發(fā)布會(huì)  美國海軍陸戰(zhàn)隊(duì)  小學(xué)生  撫養(yǎng)費(fèi)  指示  圓桌  觀察者網(wǎng)  白宮  彈道導(dǎo)彈  小雨  郭曉東  美國  亞馬遜  臺(tái)風(fēng)  參議院  尼克松  日本  國家安全  化武  步槍  大阪  毒品  動(dòng)物世界  廣東省  劉強(qiáng)東  美國陸軍  中國空軍  非洲  劉雨欣  美國總統(tǒng)  結(jié)婚紀(jì)念日  越野車 
 
[ 資訊搜索 ]  [ 加入收藏 ]  [ 告訴好友 ]  [ 打印本文 ]  [ 違規(guī)舉報(bào) ]  [ 關(guān)閉窗口 ]

 
0條 [查看全部]  相關(guān)評(píng)論

 
網(wǎng)站首頁 | 關(guān)于我們 | 聯(lián)系方式 | 使用協(xié)議 | 版權(quán)隱私 | 網(wǎng)站地圖 | 排名推廣 | 廣告服務(wù) | 積分換禮 | 網(wǎng)站留言 | RSS訂閱 | 皖I(lǐng)CP備2021004516號(hào)-14
企業(yè)800網(wǎng) · 提供技術(shù)支持