用户如何在会话

时间:2018-03-12 17:50:17

标签: javascript html html-table

用户如何在html会话期间调整html表格列宽?

td 元素主要包含通过css类合理调整大小的文本输入字段,表格默认为容纳它们。这可能会导致一些水平滚动,但这没关系。

但是在编辑会话期间,用户可能需要增加某些列的宽度以帮助他们进行编辑,如何在下次加载页面时丢失这些设置并不重要。

我假设我使用Javascript来更新字段宽度但是如何触发它,视觉提示是什么?



<table>
    <tr>
        <th class="tableheading ui-corner-all">
            <label>
                #
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="largeinputfield">
                Album
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Genre
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Album Artist
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Sort Album Artist
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Album Artists
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Sort Album Artists
            </label>
        </th>
    </tr>
    <tr>
        <td class="tableheading ui-corner-all">
            1
        </td>
        <td>
            <input name="13ALBUM" value="The Orchestral Suites" class="largeinputfield" type="text">
        </td>
        <td>
            <input name="13GENRE" value="" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTIST" value="Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTIST_SORT" value="Bach, Johann Sebastian; Academy of Ancient Music; Hogwood, Christopher" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTISTS" value="Johann Sebastian Bach;;;Academy of Ancient Music;;;Christopher Hogwood" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTISTS_SORT" value="Bach, Johann Sebastian;;;Academy of Ancient Music;;;Hogwood, Christopher" class="mediuminputfield" type="text">
        </td>
    </tr>
<tr>
<td class="tableheading ui-corner-all">
    1
</td>
<td>
    <input name="14ALBUM" value="The Orchestral Suites" class="largeinputfield" type="text">
</td>
<td>
    <input name="14GENRE" value="" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTIST" value="Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTIST_SORT" value="Bach, Johann Sebastian; Academy of Ancient Music; Hogwood, Christopher" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTISTS" value="Johann Sebastian Bach;;;Academy of Ancient Music;;;Christopher Hogwood" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTISTS_SORT" value="Bach, Johann Sebastian;;;Academy of Ancient Music;;;Hogwood, Christopher" class="mediuminputfield" type="text">
</td>
</tr>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:2)

将所有输入转换为textareas,因为不需要编写JavaScript解决方案。应用正确的CSS。 Textareas有一个调整大小选项。您可能希望使用JavaScript自定义它。

对于可调整大小的列,有很多方法。我花时间做了一个伪劣的解决方案,宁愿完全不同,但这里有一些东西让你开始......

它使用textareas而不是输入。对于列中的每个textarea,调整其大小会将该列中的所有textareas调整为相同的宽度。显然css需要调整,因为它们没有完美对齐,所以它不是一个很好的解决方案。

更好的解决方案是获取每个列分隔符的x位置,并能够根据需要设置这些x位置。但我会再看一次。

&#13;
&#13;
let allInputs = document.querySelectorAll('input');
let cols = document.querySelectorAll('table tr th').length-1;
let isDown = false;
let elSelected = null;
let allTextareas = Array.from(allInputs).map((el, i)=>{
  let newEl = document.createElement("textarea");
  newEl.innerHTML = el.value;
  newEl.addEventListener('mousedown', function(){
    isDown = true;
    elSelected = {el: this, i: i, colID: i%cols};
  });
  el.parentNode.appendChild(newEl);
  el.parentNode.removeChild(el);
  return {el: newEl, colID: i%cols};
});

document.addEventListener('mouseup', function(){
  isDown = false;
  elSelected = null;
});

let colWidth = 0;
document.addEventListener('mousemove', function(){
  if(isDown && elSelected){
    if(elSelected.el.clientWidth != colWidth){
      colWidth = elSelected.el.clientWidth;
      allTextareas.forEach((o, j)=>{
        if(elSelected.i !== j && elSelected.colID === o.colID){
          o.el.style.width = colWidth+'px';
        }
      });
    }
  }
});
&#13;
textarea {
  resize: horizontal;
}
&#13;
<table>
    <tr>
        <th class="tableheading ui-corner-all">
            <label>
                #
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="largeinputfield">
                Album
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Genre
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Album Artist
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Sort Album Artist
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Album Artists
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Sort Album Artists
            </label>
        </th>
    </tr>
    <tr>
        <td class="tableheading ui-corner-all">
            1
        </td>
        <td>
            <input name="13ALBUM" value="The Orchestral Suites" class="largeinputfield" type="text">
        </td>
        <td>
            <input name="13GENRE" value="" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTIST" value="Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTIST_SORT" value="Bach, Johann Sebastian; Academy of Ancient Music; Hogwood, Christopher" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTISTS" value="Johann Sebastian Bach;;;Academy of Ancient Music;;;Christopher Hogwood" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTISTS_SORT" value="Bach, Johann Sebastian;;;Academy of Ancient Music;;;Hogwood, Christopher" class="mediuminputfield" type="text">
        </td>
    </tr>
<tr>
<td class="tableheading ui-corner-all">
    1
</td>
<td>
    <input name="14ALBUM" value="The Orchestral Suites" class="largeinputfield" type="text">
</td>
<td>
    <input name="14GENRE" value="" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTIST" value="Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTIST_SORT" value="Bach, Johann Sebastian; Academy of Ancient Music; Hogwood, Christopher" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTISTS" value="Johann Sebastian Bach;;;Academy of Ancient Music;;;Christopher Hogwood" class="mediuminputfield" type="text">
</td>
<td>
    <input name="14ALBUM_ARTISTS_SORT" value="Bach, Johann Sebastian;;;Academy of Ancient Music;;;Hogwood, Christopher" class="mediuminputfield" type="text">
</td>
</tr>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以执行以下操作,您可以使用javascript添加可拖动区域(设置为蓝色以查看可见性)。如果你搞砸了这个,你应该找到你正在寻找的解决方案。

桌子上的设定宽度很重要,因为没有它,它将无法正常工作。

这会通过并自动为每个TH元素附加一个调整大小的触发器。该元素上的Mousedown将其父TH设置为活动元素,这允许全局mousemove事件更改其大小。

function each(arr, fn){
  let i = arr.length
  while(--i > -1){ fn(arr[i]) }
}

function px(val){ return [val, 'px'].join("") }

var resizeElement, startSize, startX

function beginResize(e){
  killResize()
  let th = e.target.parentElement
  resizeElement = th
  startSize = th.clientWidth
  startX = e.pageX
}

function killResize(){
  resizeElement = null
  startSize = null
  startX = null
}

each(document.querySelectorAll('th'), elem => {
  let trigger = document.createElement('span')
  trigger.className = 'resizeTrigger'
  
  trigger.addEventListener('mousedown', beginResize)
  
  elem.appendChild(trigger)
})

document.addEventListener('mousemove', e => {
  if(resizeElement){
    let diff = e.pageX - startX
    resizeElement.style.width = px(startSize + diff)
  }
})

document.addEventListener('mouseup', killResize)
table {
  table-layout: fixed;
  width: 100%;
}
th {
  position: relative;
}

th > .resizeTrigger {
  content: '';
  position: absolute;
  display: block;
  width: 8px;
  right: -4px;
  top: 0;
  height: 100%;
  background: blue;
  cursor: ew-resize;
}
input {
width: 100%;
}
<table>
    <tr>
        <th class="tableheading ui-corner-all">
            <label>
                #
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="largeinputfield">
                Album
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Genre
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Album Artist
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Sort Album Artist
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Album Artists
            </label>
        </th>
        <th class="tableheading ui-corner-all">
            <label class="mediuminputfield">
                Sort Album Artists
            </label>
        </th>
    </tr>
    <tr>
        <td class="tableheading ui-corner-all">
            1
        </td>
        <td>
            <input name="13ALBUM" value="The Orchestral Suites" class="largeinputfield" type="text">
        </td>
        <td>
            <input name="13GENRE" value="" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTIST" value="Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTIST_SORT" value="Bach, Johann Sebastian; Academy of Ancient Music; Hogwood, Christopher" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTISTS" value="Johann Sebastian Bach;;;Academy of Ancient Music;;;Christopher Hogwood" class="mediuminputfield" type="text">
        </td>
        <td>
            <input name="13ALBUM_ARTISTS_SORT" value="Bach, Johann Sebastian;;;Academy of Ancient Music;;;Hogwood, Christopher" class="mediuminputfield" type="text">
        </td>
    </tr>

答案 2 :(得分:0)

这是另一种解决方案。要允许表格扩展到屏幕宽度以外,请将其放在div中并设置overflow:auto css for the div。

在标题内定义表格内容&#39;和&#39;行&#39;。

&#13;
&#13;
//define table
const headers = [{name:'#', type:'label'}, {name:'Album', type:'input'}, {name:'Genre', type:'input'}, {name:'...', type:'input'}];
const cols = headers.length;
const rows = [
  ['1', 'The Orchestral Suites', 'Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood', '...'],
  ['2', 'The Orchestral Suites', 'Johann Sebastian Bach; Academy of Ancient Music, Christopher Hogwood', '...']
];
//create table
const elHeaderRow = document.getElementById('headers');
const elTable = document.getElementById('table');
const allElements = document.getElementsByTagName("*");//for cursor
//create headers
headers.forEach(({name, type})=>{
  const el = document.createElement('th');
  el.textContent = name;
  elHeaderRow.appendChild(el);
});
let cells = [];
//create rows
rows.forEach((row, rowID)=>{
  const elRow = document.createElement('tr');
  elRow.id = 'row-'+(rowID+1);
  cells.push(...row.map((name, colID)=>{
    const elCell = document.createElement('td');
    const type = headers[colID].type;
    const elRowContents = document.createElement(type);
    if(type === 'input'){
      elRowContents.value = name;
      elRowContents.type = 'text';
    } else {
      elRowContents.textContent = name;
    }
    elCell.appendChild(elRowContents);
    elRow.appendChild(elCell);
    return {rowID:rowID, colID:colID, element: elCell};
  }));
  elTable.appendChild(elRow);
});
const container = document.getElementById('table-container');
//get positions of cells (x etc.)
function getColumnPositions(cells){
  const positions = cells.map(cell=>{
    const rect = cell.element.getBoundingClientRect();
    return {x:rect.x, width:rect.width, right: rect.right, element: cell.element};
  });
  return positions;
}
let cellPositions = getColumnPositions(cells);
const dividerWidth = 4;
let cellHit = null;
let isDown = false;
let isResizing = false;
// on mouse move
document.addEventListener('mousemove', function(e){
  const x = e.pageX;
  const y = e.pageY;
  let tag = document.elementFromPoint(x, y);
  let bStickRight = false;
  if(tag){
    tag = tag.tagName;
  }
  const insideTable = (tag === "DIV" || tag === "BODY" || tag === "TABLE" || tag === "TD" || tag === "TH" || tag === "INPUT");
  if(insideTable){
    if(!cellHit){
       isResizing = false;
    }
    if(cellHit && isResizing){
      if(container.scrollLeft === container.scrollWidth-container.clientWidth){
      bStickRight = true;
        
        container.scrollLeft = container.scrollWidth;
      }
      cellHit.element.style.width = (x-cellHit.x)+'px';
      cellHit.element.style.minWidth = (x-cellHit.x)+'px';
      if(bStickRight){
        container.scrollLeft = container.scrollWidth;
      }
    } else {
      cellHit = null;
      cellPositions.forEach(cell=>{
        if(Math.abs(x-cell.right) < dividerWidth){
          cellHit = cell;
        }
      });
    }
  } else {
    cellHit = null;
  }
  if(cellHit){
    Array.from(allElements).forEach((el)=>{
      el.style.cursor = 'ew-resize';
      el.style.userSelect = 'none';
    });
  } else {
    Array.from(allElements).forEach((el)=>{
      el.style.cursor = '';
      el.style.userSelect = '';
    });
  }
}, false);
//on mouse down
document.addEventListener('mousedown', function(e){
  isDown = true;
  if(cellHit){
    isResizing = true;
  }
}, false);
//on mouse up
document.addEventListener('mouseup', function(e){
  isDown = false;
  isResizing = false;
  cellPositions = getColumnPositions(cells);
  Array.from(allElements).forEach((el)=>{
    el.style.cursor = '';
    el.style.userSelect = '';
  });
}, false);
&#13;
input[type="text"] {
  min-width: 100%;
}
#table-container {
  overflow: auto;
  max-width: 85%;
}
td {
  padding: 0 2px;
}
&#13;
<div id="table-container">
  <table id="table">
    <tr id="headers">
    </tr>
  </table>
</div>
&#13;
&#13;
&#13;