替代不剪切中间字符的“溢出:隐藏”

Posted

技术标签:

【中文标题】替代不剪切中间字符的“溢出:隐藏”【英文标题】:Alternative to `overflow: hidden` which does not clip mid-character 【发布时间】:2019-01-21 14:02:30 【问题描述】:

我正在使用overflow: hidden 属性来限制计算器显示屏中显示的数字。但是,overflow: hidden 会在字符中间剪辑字符,这是我想避免的。

Mozilla 建议使用text-overflow: '';,它与浏览器不太兼容。关于如何限制字符数和剪辑 between 字符而不是中间字符,您还有其他建议吗? (我不想在我的显示器上看到半个数字)

鼓励使用 javascript 解决方案。

这是我目前的解决方案。 在我输入数字时有效,在我输入运算符时无效

  let digitsArray = [];
  let digitsString = "";
  let displayOutput = "";
  let pressedButtonsArray = [];
  let pressedButtonsString = "";
  let visibleArray = [];
  let visibleText = "";
  let result = "";
  let displayTextWidth;
  let numberOfCharacters;
  let pixelsPerCharacter;
  let numberOfVisibleCharacters;
  let outerDivWidth;

  window.onload = function() 
    outerDivWidth = document.getElementById("outerDiv").offsetWidth;
  ;

  window.onresize = function() 
    outerDivWidth = document.getElementById("outerDiv").offsetWidth;
  ;


    document.onkeypress = function(event) 
    let buttonValue = event.which || event.keyCode;
    let buttonCharacter = String.fromCharCode(buttonValue);
    if (/[0123456789]/.test(buttonCharacter)) 
      clickNumberButton(buttonCharacter)
    
    if (buttonCharacter == "+") 
      clickOperationButton('+','+');
    
    if (buttonCharacter == "-") 
      clickOperationButton('-','-');
    
    if (buttonCharacter == "*") 
      clickOperationButton('*','×')
    
    if (buttonCharacter == "/") 
      clickOperationButton('/','÷');
    ;
    if (buttonCharacter == "=") 
      equate();
    
  ;

  function show() 

  


  function scaleFont() 

    // Put in here, so that it's executed everytime a button is pressed //
    console.log("offsetwidth: " + document.getElementById("displayText").offsetWidth)
    displayTextWidth = document.getElementById("displayText").offsetWidth;
    console.log("displayTextWidth: " + displayTextWidth);
    numberOfCharacters = visibleText.length;
    console.log("numberOfCharacters: " + numberOfCharacters);
    pixelsPerCharacter = displayTextWidth/numberOfCharacters;
    console.log("pixelsPerCharacter: " + pixelsPerCharacter);
    numberOfVisibleCharacters = Math.floor(outerDivWidth / pixelsPerCharacter);
    console.log("numberOfVisibleCharacters: " + numberOfVisibleCharacters);
    displayText = visibleText.slice(-numberOfVisibleCharacters)
    document.getElementById("displayText").innerhtml = displayText;
    console.log("offsetwidth: " + document.getElementById("displayText").offsetWidth)
  


  function clickNumberButton(button) 
    //Equation has happened//
    if (pressedButtonsArray[pressedButtonsArray.length-1] == "=") 
      pressedButtonsArray = [];
      pressedButtonsArray.push(button);
      pressedButtonsString = pressedButtonsArray.join("");

      visibleArray = [];
      visibleArray.push(button);
      visibleText = visibleArray.join("");
      document.getElementById("displayText").innerHTML = visibleText;
    
    //Equation hasn't happened//
    else 
      pressedButtonsArray.push(button);
      pressedButtonsString = pressedButtonsArray.join("");

      visibleArray.push(button);
      visibleText = visibleArray.join("");
      document.getElementById("displayText").innerHTML = visibleText;
    
    scaleFont();
    console.log("PBA: " + pressedButtonsArray);
    console.log("VA: " + visibleArray);
    console.log("PBS: " + pressedButtonsString);
    console.log("VT: " + visibleText);
  

  function clickOperationButton(button, symbol) 
    if (pressedButtonsArray.length > 0 && (/[0123456789=]/.test(pressedButtonsArray[pressedButtonsArray.length-1])) || (button == "-" && pressedButtonsArray[pressedButtonsArray.length-1] !== "-")) 
      if (pressedButtonsArray[pressedButtonsArray.length-1] == "=") 
        pressedButtonsArray = [];
        pressedButtonsArray.push(result, button);
        pressedButtonsString = pressedButtonsArray.join("");

        visibleArray = [];
        visibleArray.push(result, symbol);
        visibleText = visibleArray.join("");
        document.getElementById("displayText").innerHTML = visibleText;
      
      else 
        pressedButtonsArray.push(button);
        pressedButtonsString = pressedButtonsArray.join("");

        visibleArray.push(symbol);
        visibleText = visibleArray.join("");
        document.getElementById("displayText").innerHTML = visibleText;
      
    
    scaleFont();
    console.log("PBA: " + pressedButtonsArray);
    console.log("VA: " + visibleArray);
    console.log("PBS: " + pressedButtonsString);
    console.log("VT: " + visibleText);
  

  function equate() 
    if (pressedButtonsArray.length > 0 && (/[0123456789]/.test(pressedButtonsArray[pressedButtonsArray.length-1]))) 
      pressedButtonsArray.push("=");
      result = eval(pressedButtonsString);
      pressedButtonsString = result.toString();

      visibleArray.push("=");
      visibleText = result.toString();
      document.getElementById("displayText").innerHTML = visibleText;
    
    scaleFont();
    console.log("PBA: " + pressedButtonsArray);
    console.log("VA: " + visibleArray);
    console.log("PBS: " + pressedButtonsString);
    console.log("VT: " + visibleText);
  

  function del() 
    if (pressedButtonsArray[pressedButtonsArray.length-1] == "=") 
      pressedButtonsArray = [];
      pressedButtonsString = "";

      visibleArray = [];
      visibleText = "";
      result = "";
      document.getElementById("displayText").innerHTML = "";
    
    else 
      pressedButtonsArray.splice(-1,1);
      pressedButtonsString = pressedButtonsArray.join("");

      visibleArray.splice(-1,1)
      visibleText = visibleArray.join("");
      document.getElementById("displayText").innerHTML = visibleText;
    
    scaleFont();
    console.log("PBA: " + pressedButtonsArray);
    console.log("VA: " + visibleArray);
    console.log("PBS: " + pressedButtonsString);
    console.log("VT: " + visibleText);
  

  function cancel() 
    pressedButtonsArray = [];
    pressedButtonsString = "";
    visibleArray = [];
    visibleText = "";
    result = "";
    scaleFont();
    document.getElementById("displayText").innerHTML = "";
    console.log("PBA: " + pressedButtonsArray);
    console.log("VA: " + visibleArray);
    console.log("PBS: " + pressedButtonsString);
    console.log("VT: " + visibleText);
  
.container 
    width: 100%;
    height: 100%;
    margin: auto;
  

  .wrapper 
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-auto-rows: 16vh;
    font-family: sans-serif;
  

  .outerDiv 
    font-size: 80px;
    grid-column-start: 1;
    grid-column-end: 13;
    grid-row-start: 1;
    grid-row-end: 2;
    background-color: #DABE4A;
    text-align:right;
    white-space: nowrap;
  

  .innerDiv 
    float:right;
  

  .displayText 
    

  .cancel 
    grid-column-start: 1;
    grid-column-end: 7;
    grid-row-start: 2;
    grid-row-end: 3;
    display: flex;
    justify-content: center;
    align-items: center;
  

  .del 
    grid-column-start: 7;
    grid-column-end: 10;
    grid-row-start: 2;
    grid-row-end: 3;
  

  .divide 
    grid-column-start: 10;
    grid-column-end: 13;
    grid-row-start: 2;
    grid-row-end: 3;
  

  .multiply 
    grid-column-start: 10;
    grid-column-end: 13;
    grid-row-start: 3;
    grid-row-end: 4;
  

  .minus 
    grid-column-start: 10;
    grid-column-end: 13;
    grid-row-start: 4;
    grid-row-end: 5;
  

  .plus 
    grid-column-start: 10;
    grid-column-end: 13;
    grid-row-start: 5;
    grid-row-end: 7;
  

  .seven 
    grid-column-start: 1;
    grid-column-end: 4;
    grid-row-start: 3;
    grid-row-end: 4;
  

  .eight 
    grid-column-start: 4;
    grid-column-end: 7;
    grid-row-start: 3;
    grid-row-end: 4;
  

  .nine 
    grid-column-start: 7;
    grid-column-end: 10;
    grid-row-start: 3;
    grid-row-end: 4;
  

  .four 
    grid-column-start: 1;
    grid-column-end: 4;
    grid-row-start: 4;
    grid-row-end: 5;
  

  .five 
    grid-column-start: 4;
    grid-column-end: 7;
    grid-row-start: 4;
    grid-row-end: 5;
  

  .six 
    grid-column-start: 7;
    grid-column-end: 10;
    grid-row-start: 4;
    grid-row-end: 5;
  

  .one 
    grid-column-start: 1;
    grid-column-end: 4;
    grid-row-start: 5;
    grid-row-end: 6;
  

  .two 
    grid-column-start: 4;
    grid-column-end: 7;
    grid-row-start: 5;
    grid-row-end: 6;
  

  .three 
    grid-column-start: 7;
    grid-column-end: 10;
    grid-row-start: 5;
    grid-row-end: 6;
  

  .decimal 
    grid-column-start: 1;
    grid-column-end: 4;
    grid-row-start: 6;
    grid-row-end: 7;
  

  .zero 
    grid-column-start: 4;
    grid-column-end: 7;
    grid-row-start: 6;
    grid-row-end: 7;
  

  .equal 
    grid-column-start: 7;
    grid-column-end: 10;
    grid-row-start: 6;
    grid-row-end: 7;
  

  .button 
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 35px;
    border: thin black solid;
  

  .special 
    background-color: #C6CE71;
  

  .operation 
    background-color: #8CD4B9;
  

  .number 
    background-color: #153058;
  

  .module-button 
    background-color: inherit;
    font: inherit;
    border: none;
    width: 100%;
    height: 100%;
  

  .module-button:focus outline:0;

  .module-button:hover 
    filter:brightness(1.5);
  

  .module-button:active 
    filter:brightness(1);
  

  @media only screen and (min-width: 768px) 
    .container 
      width: 752px;
      max-height: 100%;
    
    .wrapper 
      grid-auto-rows: minmax(103px);
    
  
<div class="container">
  <div class="wrapper">
    <div class="outerDiv" id="outerDiv">
      <div class="innerDiv" id="innerDiv">
        <span class="displayText" id="displayText">
        </span>
      </div>
    </div>
    <div class="cancel button special"><button class="module-button" onclick="cancel()">CANCEL</button></div>
    <div class="del button special"><button class="module-button" onclick="del()">DEL</button></div>

    <div class="plus button operation"><button class="module-button" onclick="clickOperationButton('+','+')">+</button></div>
    <div class="minus button operation"><button class="module-button" onclick="clickOperationButton('-','-')">-</button></div>
    <div class="multiply button operation"><button class="module-button" onclick="clickOperationButton('*','×')">×</button></div>
    <div class="divide button operation"><button class="module-button" onclick="clickOperationButton('/','÷')">÷</button></div>


    <div class="seven button number"><button class="module-button" onclick="clickNumberButton(7)">7</button></div>
    <div class="eight button number"><button class="module-button" onclick="clickNumberButton(8)">8</button></div>
    <div class="nine button number"><button class="module-button" onclick="clickNumberButton(9)">9</button></div>

    <div class="four button number"><button class="module-button" onclick="clickNumberButton(4)">4</button></div>
    <div class="five button number"><button class="module-button" onclick="clickNumberButton(5)">5</button></div>
    <div class="six button number"><button class="module-button" onclick="clickNumberButton(6)">6</button></div>

    <div class="one button number"><button class="module-button" onclick="clickNumberButton(1)">1</button></div>
    <div class="two button number"><button class="module-button" onclick="clickNumberButton(2)">2</button></div>
    <div class="three button number"><button class="module-button" onclick="clickNumberButton(3)">3</button></div>

    <div class="decimal button number"><button class="module-button" onclick="clickNumberButton('.')">.</button></div>
    <div class="zero button number"><button class="module-button" onclick="clickNumberButton(0)">0</button></div>
    <div class="equal button number"><button class="module-button" onclick="equate()">=</button></div>

  </div>
</div>

【问题讨论】:

我是overflow: hidden 你有代码sn-p要分享吗? @KenoClayton 刚刚添加。感谢您的建议。 【参考方案1】:

您可以使用舍入算法和指数符号来显示非常大的数字:

显示结果的函数:

/**
 * Use the rounding algorithm to prevent overflow from float numbers.
 * If the number is too big (>= 1e+8), return a string representing  
 * the Number object in exponential notation.
 */
function resultDisplay(number) 
  number = roundNumber(number, 3);
  return (number >= 1e+8) ? number.toExponential(3) : number;

使用的舍入算法: [1]

/**
 * A rounding algorithm to handle JavaScript's rounding errors.
 * @param  Number  num    the number to round
 * @param  Number  scale  how many decimal places to keep
 */
function roundNumber(num, scale) 
  var number = Math.round(num * Math.pow(10, scale)) / Math.pow(10, scale);
  if(num - number > 0) 
    return (number + Math.floor(
      2 * Math.round(
        (num - number) * Math.pow(10, (scale + 1))
      ) / 10
    ) / Math.pow(10, scale));
   else 
    return number;
  


[1] 基于我对库宁回答的理解的算法:Round at most 2 decimal places.

【讨论】:

另请阅读:Is floating point math broken? 在我构建类似项目时发现它很有帮助。 我很欣赏这个解决方案。但是,我并不是要四舍五入,而只是为了显示在显示器中可见的字符。【参考方案2】:

我知道您更喜欢 JavaScript 解决方案,但有一种更好的方法可以使用 CSS 执行此操作,该方法还可以保留实际数字以供进一步计算。由于您没有提供代码 sn-p,我只能假设您的计算器读取一行。

这里是修复,假设显示数字的类是.number

.number 
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

这会在末尾用... 截断数字,所以如果数字太大,它会看起来像这样:

123.486593845674...

这与所有现代浏览器(IE11 及更高版本)兼容。

【讨论】:

谢谢。有没有办法在不使用省略号的情况下完成以下操作? 我不知道。只有 IIRC Firefox 支持 text-overflow 属性的字符串,所以我不建议使用它。 @DavyH Yes that's correct

以上是关于替代不剪切中间字符的“溢出:隐藏”的主要内容,如果未能解决你的问题,请参考以下文章

jQuery Nice Select 不使用溢出隐藏

Bootstrap 的下拉菜单被数据表隐藏

解决一行文本溢出隐藏点击展开之后全部显示并自动换行每行长度一致问题

elementui表格文字不换行,溢出隐藏

位置绝对和溢出隐藏

如果 div 宽度变小,则隐藏框