【问题标题】:How to expand a table cell's editable area?如何扩大表格单元格的可编辑区域?
【发布时间】:2020-09-30 07:43:23
【问题描述】:

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

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

我已经知道 JavaScript 允许 document.getElementById("id").contentEditable = true; 属性执行此操作。事实上,我更喜欢使用这种方法(如果有方法,请告诉我)! 但是,我故意尝试在单元格的一端设置一个不可编辑的单元,使用<span>,当我需要单元格执行功能时(例如,当添加数字总和时,单元被解析为整数,输出变为 NaN) .

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

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

另外,这是我目前的代码:

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>

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

非常感谢任何帮助!

【问题讨论】:

  • 为什么我在 CSS 中看不到 padding:0;?也可以使用*{ box-sizing:border-box; }
  • 啊,我忘了我把那个放在那里了。我最终从您的评论中得到了这个问题的答案,我只需要删除填充并将单元格的height: 属性设置为30px。如果您想回答这个问题,我很乐意将您的问题标记为答案。但是,box-sizing: border-box 做了什么?
  • box-sizing:border-box; 使边框和内边距成为元素宽度和高度的一部分,因此如果您更改边框或内边距,则无需重构。

标签: javascript html css


【解决方案1】:

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

【讨论】:

  • 感谢您的回复。这将删除填充,但是当设置高度以满足先前的尺寸时,单元格下方和其右侧仍然存在不可编辑的区域。我想删除下面不可编辑的部分。
  • 去掉第一个td:last-child{ /*everything */ }#total{ /* everything */ }。此外,您需要了解一个或多个空格或换行符会在 HTML 中创建一个空格。一些浏览器会忽略标签开头和结尾的空格,但不要指望它。
  • 这个比较接近我要找的,但是数字/单位下面还有一层不能编辑的薄层
【解决方案2】:

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

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

【讨论】:

  • 糟糕!对此感到抱歉,我不小心将标题编辑为我在一个较旧的问题中提出的问题。它现在固定了。谢谢!
【解决方案3】:

右边这个margin是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>

【讨论】:

  • 感谢您的回复,但这仍然不会改变填充问题并且还会破坏整个单元格。这是您的代码的输出:jsfiddle.net/dyjuo4fk
  • 您忘记删除代码中的 display:flex 属性
  • 我删除了它,但底部的单元格仍然坏了。同样,实际的可编辑区域仍然很薄
【解决方案4】:

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

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

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

-> Ctrl+Shift+I 你会得到开发者页面。

-> 转到样式选项卡旁边的计算选项卡

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

这就是我如何为自己找到关于样式问题的解决方案。希望对你也有帮助。

【讨论】:

    【解决方案5】:

    我使用&lt;input /&gt; 而不是&lt;span /&gt; 进行编辑(个人喜好)。

    单位是从单元格右侧浮动 5px 的跨度 (Absolute span in a relative div inside a td)。

    对于输入:隐藏边框,占据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' 的底部。

    Worth reading

    【讨论】:

    • 这很好,但同样,可编辑区域在到达单元格边缘之前被切断,并且在其上方和下方有一条细线(水平)是不可编辑的空间。我正在尝试让可编辑区域到达单元格的边界
    • 你的意思是你不想要填充?就像您希望文本触摸单元格边框一样?您将 margin-top、margin-bottom、padding-top 和 padding-bottom 设置为零。让字体变大...
    • 对,但问题是我确实喜欢单元格的实际尺寸和字体大小。当填充设置为零时,默认情况下单元格会变薄
    • 我们可以通过删除单元格和文本框上的填充来减少空间,但是,仍然会在文本上方和下方保留一点空间。这是因为字体就是这样。这些数字不占用从上到下的全部空间。例如,1234 的底部高于“g”或“q”的底部。请在编辑后的答案中查看图片。
    • 这是真的吗?例如,当我在脚本标签内设置document.getElementById("jack").contentEditable = true 时,整个单元格都变为可编辑的。似乎只有当我在内联 HTML 中设置 contentEditable = "true" 属性时才会出现这个空间。
    猜你喜欢
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多