如何扩展表格单元格的可编辑区域?

How to expand a table cell's editable area?

提问人:ttoshiro 提问时间:6/11/2020 最后编辑:ttoshiro 更新时间:7/12/2020 访问量:607

问:

我之前问过这个问题两次([1],[2]),并得到了一些很好的答案,但没有一个是我想要的。

情况:我有一个表,一列中的单元格是 .问题:可编辑区域未到达单元格的所有边缘。取而代之的是,在可编辑部分下方有一个薄的填充 (5px) 的不可编辑区域。我希望保留 5px 的空间,但也希望它是可编辑的(即我喜欢尺寸,但不喜欢它的不可编辑方面)。contentEditable

我已经知道 JavaScript 允许 document.getElementById(“id”).contentEditable = true; 属性来做到这一点。事实上,我更愿意使用这种方法(如果有办法,请告诉我)!但是,我故意尝试在单元格的一端设置一个不可编辑的单元,当我需要单元格执行函数时,它最终会被脚本用作输入(例如,当添加数字总和时,该单元与整数一起解析,输出变为)。<span>NaN

从视觉上看,我正在寻找的是这个模型所示:

Mock-up

下面是不必要的填充的视觉表示(右侧除外),以红色显示(我更改了 CSS 中的颜色只是为了让它在这里可见)。需要明确的是,我仍然喜欢单元格的尺寸,但我想使单元格的整个区域都可编辑,除了文本“kg”所在的位置。此外,“kg”右侧的红色区域不是不必要的填充,它应该保持不可编辑。

Unnecessary padding

此外,这是我到目前为止拥有的代码:

function myFunction() {
  var jack = document.getElementById("jack").innerText;
  var john = document.getElementById("john").innerText;
  var joe = document.getElementById("joe").innerText;

  var total = parseInt(jack) + parseInt(john) + parseInt(joe);

  document.getElementById("total").innerHTML = total;
}

myFunction();
* {
  box-sizing: border-box;
}

table {
  width: 100%;
}

table,
tr,
th,
td {
  background-color: #fff;
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial, sans-serif;
}

td:last-child {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: none;
}

td:last-child,
span:first-child {
  flex-grow: 1;
  margin-right: 10px;
  outline: none;
  text-align: right;
}

.cell {
  height: 30px;
}

#total {
  display: flex;
  justify-content: flex-end;
}
<table>
  <thead>
    <tr class="cell">
      <th>Person</th>
      <th>Weight</th>
    </tr>
  </thead>
  <tbody>
    <tr class="cell">
      <td>Jack</td>
      <td id="jack" oninput="myFunction()">
        <span contentEditable="true">4000</span>
        <span>kg</span>
      </td>
    </tr>
    <tr class="cell">
      <td>John</td>
      <td id="john" oninput="myFunction()">
        <span contentEditable="true">200</span>
        <span>kg</span>
      </td>
    </tr>
    <tr class="cell">
      <td>Joe</td>
      <td id="joe" oninput="myFunction()">
        <span contentEditable="true">3</span>
        <span>kg</span>
      </td>
    </tr>
    <tr class="cell">
      <td>Total</td>
      <td>
        <span id="total"></span>
        <span>kg</span>
      </td>
    </tr>
  </tbody>
</table>

如您所见,在右列单元格的角落/边缘,顶部、底部和左侧大约有 5px 的不可编辑空间。有没有办法使这个特定部分可编辑,而无需函数在单元格的右侧(单元所在的位置)接收单位?

任何帮助都非常感谢!

JavaScript HTML CSS

评论

1赞 StackSlave 6/12/2020
为什么我在 CSS 中看不到?也使用 ,也使用 。padding:0;*{ box-sizing:border-box; }
0赞 ttoshiro 6/12/2020
啊,我忘了我把它留在那里了。我最终从您的评论中得到了这个问题的答案,我只需要删除填充并将单元格的属性设置为 .如果你想回答这个问题,我很乐意把你的答案标记为答案。但是,该怎么办?height:30pxbox-sizing: border-box
1赞 StackSlave 6/12/2020
box-sizing:border-box;使边框和填充成为元素宽度和高度的一部分,因此在更改边框或填充时不必重构。

答:

1赞 Mohammed Khaled 6/11/2020 #1

你在右边看到的这个边距是由 flex-box 引起的,你可以去掉

display: flex;

之后,您可能会注意到总单元格损坏以修复它,如下所示编辑您的函数:

function myFunction() {
   var jack = document.getElementById("jack").innerText;
   var john = document.getElementById("john").innerText;
   var joe = document.getElementById("joe").innerText;

   var total = parseInt(jack) + parseInt(john) + parseInt(joe);

   document.getElementById("total").innerText = total + " kg";
}

myFunction();

和你的 HTML :

<td id="total">
   <span>0</span>
   <span>kg</span>
</td>

评论

0赞 ttoshiro 6/11/2020
感谢您的回复,但这仍然不会改变填充问题,并且还会破坏总单元格。这是代码的输出:jsfiddle.net/dyjuo4fk
0赞 Mohammed Khaled 6/12/2020
您忘记删除代码中的 display:flex 属性
0赞 ttoshiro 6/18/2020
我把它拿走了,但底部的单元格仍然坏了。同样,实际的可编辑区域仍然非常薄
2赞 StackSlave 6/12/2020 #2

只需在 CSS 中使用 ,您不需要填充。您可能还希望使用 ,作为最佳实践,这样填充和边框将成为所有元素的宽度和高度的一部分。padding:0;*{ box-sizing:border-box; }

评论

0赞 ttoshiro 6/17/2020
感谢您的回复。这将删除填充,但是当设置高度以满足先前的尺寸时,单元格下方及其右侧仍存在不可编辑的区域。我想删除下面不可编辑的部分。
1赞 StackSlave 6/18/2020
去掉第一个和 .此外,您需要了解一个或多个空格或换行符会在 HTML 中创建单个空格。一些浏览器省略了开头和结尾的空格,但不要指望它。td:last-child{ /*everything */ }#total{ /* everything */ }
0赞 ttoshiro 6/18/2020
这更接近我正在寻找的内容,但在数字/单位下方仍然有一个无法编辑的薄层
2赞 Kalimah 6/12/2020 #3

您发布的关于计算的标题与您的问题(关于演示)不同。

如果您想保留可以使用的当前代码,请申请。填充的问题在于您在表格单元格上使用 flexbox。要解决这两个问题,您可以使用伪元素并删除内部跨度和 .document.querySelector("#jack span:first-child")parseInt():afterdisplay: flex

此外,您需要按照其他答案中的建议使用运算符添加默认值。parseInt||

下面是一个示例:

function myFunction() {
  var jack = document.getElementById("jack").innerText;
  var john = document.getElementById("john").innerText;
  var joe = document.getElementById("joe").innerText;

  var total = (parseInt(jack) || 0) + (parseInt(john) || 0) + (parseInt(joe) || 0);

  document.getElementById("total").innerHTML = total;
}

myFunction();
table {
  width: 100%;
}

table,
tr,
th,
td {
  background-color: #fff;
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial, sans-serif;
}

td:last-child {
  border: none;
  text-align: right;
  outline: 0;
}

td:last-child::after {
  content: " kg";
}

.cell {
  height: 30px;
}
<table>
  <thead>
    <tr class="cell">
      <th>Person</th>
      <th>Weight</th>
    </tr>
  </thead>
  <tbody>
    <tr class="cell">
      <td>Jack</td>
      <td id="jack" oninput="myFunction()" contentEditable="true">
        3000
      </td>
    </tr>
    <tr class="cell">
      <td>John</td>
      <td id="john" oninput="myFunction()" contentEditable="true">
        200
      </td>
    </tr>
    <tr class="cell">
      <td>Joe</td>
      <td id="joe" oninput="myFunction()" contentEditable="true">3
      </td>
    </tr>
    <tr class="cell">
      <td>Total</td>
      <td id="total">
      </td>
    </tr>
  </tbody>
</table>

评论

0赞 ttoshiro 6/12/2020
哎呀!很抱歉,我不小心将标题编辑为我在其中一个旧问题中提出的问题。它现在修好了。谢谢!
1赞 Prabesh Gouli 7/11/2020 #4

这在未来也可能有所帮助:

在做css时,我也遇到很多这样的问题,到目前为止,我发现最好的解决方案是:

如果您有任何额外的样式:

-> Ctrl+Shift+I,您将获得开发人员页面。page you get when you Ctrl+Shift+I

-> 转到“样式”选项卡旁边的“计算”选项卡 Computed Tab

--> 然后比较样式的值和你分配的值,你会自己找到解决方案。

这就是我如何为自己找到造型问题的解决方案。希望它也能帮助你。

1赞 Sudip Shrestha 7/12/2020 #5

我用而不是用于编辑(个人喜好)。<input /><span />

单位是浮动在单元格右侧 5px 上的跨度(td 内相对 div 中的绝对跨度)。

对于输入:隐藏边框,占据 100% 的宽度和高度,填充约 25px(因此该单元将保留在文本框内容的右侧)。

还增加了列宽。

function myFunction() {
  var jack = document.getElementById("inpJack").value;
  var john = document.getElementById("inpJohn").value;
  var joe = document.getElementById("inpJoe").value;

  var total = parseInt(jack) + parseInt(john) + parseInt(joe);

  document.getElementById("total").innerHTML = total;
}

myFunction();
* {
  box-sizing: border-box;
}

table {
  width: 100%;
}

table,
tr,
th,
td {
  background-color: #fff;
  border: 1px solid black;
  border-collapse: collapse;
  font-family: Arial, sans-serif;
}

.cell {
  vertical-align: middle;
}

.tdPersonName, .tdHeader {
  height: 30px;
  padding-left: 5px;
}

.divInputContainer {
 position:relative;
}

.withUnit, .inpWithUnit {
  text-align: right;
  padding-right: 25px;
}

.inpWithUnit {
  font-family: Arial, sans-serif;
  font-size: 16px;
  height: 30px;
  width: 100%;
  height: 100%;
  margin:0;
  border: none;
}

.inpWithUnit:focus {
    outline-width: 0;
}

.spUnit {
 position:absolute; right:5px;
}

#total {
  display: flex;
  justify-content: flex-end;
}
<table>
  <colgroup>
    <col style="width: 40%;">
    <col style="width: 60%;">
  </colgroup>
  <thead>
    <tr class="cell">
      <th class="tdHeader">Person</th>
      <th class="tdHeader">Weight</th>
    </tr>
  </thead>
  <tbody>
    <tr class="cell">
      <td class="tdPersonName">Jack</td>
      <td id="jack" oninput="myFunction()">
        <div class="divInputContainer">
          <span class="spUnit">kg</span>
          <input id="inpJack" class="inpWithUnit" value="4000" />
        </div>
      </td>
    </tr>
    <tr class="cell">
      <td class="tdPersonName">John</td>
      <td id="john" oninput="myFunction()">
        <div class="divInputContainer">
          <span class="spUnit">kg</span>
          <input id="inpJohn" class="inpWithUnit" value="200" />
        </div>
      </td>
    </tr>
    <tr class="cell">
      <td class="tdPersonName">Joe</td>
      <td id="joe" oninput="myFunction()">
        <div class="divInputContainer">
          <span class="spUnit">kg</span>
          <input id="inpJoe" class="inpWithUnit" value="3" />
        </div>
      </td>
    </tr>
    <tr class="cell">
      <td class="tdPersonName">Total</td>
      <td>
        <div class="divInputContainer">
          <span class="spUnit">kg</span>
          <span id="total" class="withUnit" />
        </div>
      </td>
    </tr>
  </tbody>
</table>

编辑:

我们可以通过删除单元格和文本框上的填充来减少空间,但是,文本上方和下方仍将保留一点空间。这是因为字体就是这样。这些数字不会占据从上到下的完整空间。例如,1234 的底部高于“g”或“q”的底部。

enter image description here 值得一读

评论

0赞 ttoshiro 7/12/2020
这很好,但同样,可编辑区域在到达单元格边缘之前被切断,并且上方和下方有一条细线(水平),这是不可编辑的空间。我正在尝试使可编辑区域到达单元格的边界
0赞 Sudip Shrestha 7/12/2020
你的意思是你不想要填充物?就像你想让文本接触单元格边框一样?将 margin-top、margin-bottom、padding-top 和 padding-bottom 设置为零。使字体变大...
0赞 ttoshiro 7/12/2020
是的,但问题是我确实喜欢单元格的实际尺寸和字体大小。当填充设置为零时,默认情况下单元格会变细
0赞 Sudip Shrestha 7/12/2020
我们可以通过删除单元格和文本框上的填充来减少空间,但是,文本上方和下方仍将保留一点空间。这是因为字体就是这样。这些数字不会占据从上到下的完整空间。例如,1234 的底部高于“g”或“q”的底部。请参阅编辑后的答案中的图像。
0赞 ttoshiro 7/13/2020
但是,这总是正确的吗?例如,当我在脚本标签内设置时,整个单元格将变为可编辑。似乎只有当我在内联 HTML 中设置属性时才会出现这个空间。document.getElementById("jack").contentEditable = truecontentEditable = "true"