如何改变JS中的字体大小以适应其容器?

问题描述 投票:0回答:1

我正在做一个简单的计算器应用程序,使用vanilla JS 而我有 div 元素来显示数字。但当 textContent 的宽度,它开始看起来很丑陋。我想让 font-size 使其始终在宽度范围内。

我是这样给我的显示添加数字的 div

for(let i=0; i<numbers.length; i++){
    numbers[i].addEventListener("click", function(){
        display.textContent += this.textContent;
    })
}

textContent 是少它看起来不错

enter image description here

但当 textContent 超出了宽度就不好看了

enter image description here

原代码在这里。

//Selectors
let numbers = document.querySelectorAll(".numbers")
let operators = document.querySelectorAll(".operators")

let equalto = document.querySelector(".equalto")
let clear = document.querySelector(".clear")
let backspace = document.querySelector(".backspace")
let plusMinus = document.querySelector(".plus-minus")
let dot = document.querySelector(".dot")

let display = document.querySelector(".display")
let output = document.querySelector(".output")

let equaltoPressed = false;

//Event Listeners
for(let i=0; i<numbers.length; i++){
	numbers[i].addEventListener("click", function(){
		if (equaltoPressed){
			display.textContent = "";
			equaltoPressed = false;
		}
		//if condition so that if the display has "Infinity" on it, we don't append digits
		if ("0123456789.+-×÷".includes(display.textContent[display.textContent.length-1]) || display.textContent == "")
			display.textContent += this.textContent;
		evaluate();
	})
}

for(let i=0; i<operators.length; i++){
	operators[i].addEventListener("click", function(){
		equaltoPressed = false;
		if ("+-×÷".includes(display.textContent[display.textContent.length-1]))
			display.textContent = display.textContent.substring(0,display.textContent.length-1) + this.textContent;
		else
			display.textContent += this.textContent;
	})
}

equalto.addEventListener("click", function(){	
	if (output.textContent !== ""){
		display.textContent = output.textContent;
		output.textContent = "";
		equaltoPressed = true;
	}	
});

clear.addEventListener("click", function(){
	equaltoPressed = false;
	display.textContent = "";
	output.textContent = "";
})


backspace.addEventListener("click", function(){
	equaltoPressed = false;
	display.textContent = display.textContent.substr(0,display.textContent.length-1);
	evaluate();
})


plusMinus.addEventListener("click", function(){
	equaltoPressed = false;
	let expression = display.textContent;
	let flag = true;

	for (let i=expression.length-1; i>=0; i--){
		if ("+-×÷".includes(expression[i])){
			if (expression[i] !== "-")
				expression = expression.substring(0,i+1) + "-" + expression.substring(i+1,expression.length);
			flag = false;
			break;
		}
	}

	if (flag)
		expression = "-"+expression;
	display.textContent = expression;

	evaluate();
})


dot.addEventListener("click", function(){
	if (equaltoPressed)
		display.textContent = "";
	let start = 0;
	for (let i=display.textContent.length-1; i>=0; i--){
		if("+-×÷".includes(display.textContent[i])){
			start = i+1;
			break;
		}
	}
	if (!display.textContent.substring(start,display.textContent.length).includes("."))
		display.textContent += ".";
})

//Functions
function evaluate(){
	let expression = display.textContent;

	for (let i=0; i<expression.length; i++){
		if (expression[i] === "×")
			expression = expression.substring(0,i) + "*" + expression.substring(i+1,expression.length);
		if (expression[i] === "÷")
			expression = expression.substring(0,i) + "/" + expression.substring(i+1,expression.length);
	}

	if("0123456789.".includes(expression[expression.length-1]) && eval(expression) != expression)
		output.textContent = eval(expression);
	else
		output.textContent = "";
}
*{
	border:0;
	margin:0;

}

body{
	min-height: 100vh;
	background: black;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	font-family: arial;
	font-size: 1.5rem;
	color: #f8f8f8;
}

.row{
	display: flex;
}

.light-grey{
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: #a6a6a6;
	height: 4.2rem;
	width: 4.2rem;
	border-radius: 	50%;
	margin: .4rem;
	cursor: pointer;
	color: black;
}

.dark-grey{
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: #333333;
	height: 4.2rem;
	width: 4.2rem;
	border-radius: 	50%;
	margin: .4rem;
	cursor: pointer;
}

.yellow{
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: #ff9501;
	height: 4.2rem;
	width: 4.2rem;
	border-radius: 	50%;
	margin: .4rem;
	cursor: pointer;
}

#zero{
	width: 9.2rem;
	border-radius:0 50px 50px 0;
	border-top-right-radius: 50px;
	border-bottom-left-radius: 50px;
	border-bottom-right-radius: 50px;
	border-top-left-radius: 50px;
}

.display{
	width: 19.2rem;
	height: 3rem;
	margin: 0 .4rem 2rem .4rem;
	text-align: right;
	font-size: 3rem;
}

.output{
	width: 19.2rem;
	height: 2rem;
	margin: 0 .4rem 2rem .4rem;
	text-align: right;
	font-size: 2rem;
}

i{
	font-size: 1.3rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css" integrity="sha256-46r060N2LrChLLb5zowXQ72/iKKNiw/lAmygmHExk/o=" crossorigin="anonymous" />
<div class="display"></div>
<div class="output"></div>
<div class="row">
  <div class="light-grey clear">AC</div>
  <div class="light-grey plus-minus">+/-</div>
  <div class="light-grey operators">÷</div>
  <div class="yellow backspace"><i class="fas fa-backspace"></i></div>
</div>
<div class="row">
  <div class="dark-grey numbers">7</div>
  <div class="dark-grey numbers">8</div>
  <div class="dark-grey numbers">9</div>
  <div class="yellow operators">×</div>
</div>
<div class="row">
  <div class="dark-grey numbers">4</div>
  <div class="dark-grey numbers">5</div>
  <div class="dark-grey numbers">6</div>
  <div class="yellow operators">-</div>
</div>
<div class="row">
  <div class="dark-grey numbers">1</div>
  <div class="dark-grey numbers">2</div>
  <div class="dark-grey numbers">3</div>
  <div class="yellow operators">+</div>
</div>
<div class="row">
  <div class="dark-grey numbers" id="zero">0</div>
  <div class="dark-grey dot">.</div>
  <div class="yellow equalto">=</div>
</div>
javascript html css dom
1个回答
4
投票

在这里,更好地查看它在一个 全页. 增加了一个封面元素 .display-font.display-cover 左右 .display,把它们的样式固定了一下。

然后添加了一个带有 observer 在你的JS的末端,它正在寻找改变在 .display,然后改变 font-size: n%.display-cover 取决于 .display-font. 这里我们需要 .display-font 以固定值 font-size. 虽然我们无法改变 font-size.display因为我们正在观察它的变化,而且... ... font-size 变化导致圆圈错误。

但用2个盖板块一切正常。请看。

更新了

将以上所有内容添加到 .output 块,第一次尝试就错过了。

更新2

新增 white-space: nowrap;.display-cover.output-cover 以防止文本跳转到下一行。

在代码的部分加入大量的注释和解释,其中在 .display.output 正在观察。

更多关于 突变观察者. 它不是量子力学,也不是高深的编程。昨天第一次使用它,说实话。

更多关于 语句. 用它来检查是否有 .display.output 宽度。

关于你的注释中的四舍五入错误(当你使用一个ling数字,超过17个符号)。

  1. 这个错误可以在你的原始代码中重复出现。

  2. 这个错误可以在我发现的所有在线计算器中重复出现。如果你设置100000000000000000+68 - 你会得到100000000000000060。这是一些Javascript的四舍五入功能。你可以在这里测试它 https:/www.jqueryscript.netdemoCalculator-App-jQuery-Bootstrap.

//Selectors
let numbers = document.querySelectorAll(".numbers")
let operators = document.querySelectorAll(".operators")

let equalto = document.querySelector(".equalto")
let clear = document.querySelector(".clear")
let backspace = document.querySelector(".backspace")
let plusMinus = document.querySelector(".plus-minus")
let dot = document.querySelector(".dot")

let display = document.querySelector(".display")
let output = document.querySelector(".output")

let equaltoPressed = false;

//Event Listeners
for (let i = 0; i < numbers.length; i++) {
  numbers[i].addEventListener("click", function() {
    if (equaltoPressed) {
      display.textContent = "";
      equaltoPressed = false;
    }
    //if condition so that if the display has "Infinity" on it, we don't append digits
    if ("0123456789.+-×÷".includes(display.textContent[display.textContent.length - 1]) || display.textContent == "")
      display.textContent += this.textContent;
    evaluate();
  })
}

for (let i = 0; i < operators.length; i++) {
  operators[i].addEventListener("click", function() {
    equaltoPressed = false;
    if ("+-×÷".includes(display.textContent[display.textContent.length - 1]))
      display.textContent = display.textContent.substring(0, display.textContent.length - 1) + this.textContent;
    else
      display.textContent += this.textContent;
  })
}

equalto.addEventListener("click", function() {
  if (output.textContent !== "") {
    display.textContent = output.textContent;
    output.textContent = "";
    equaltoPressed = true;
  }
});

clear.addEventListener("click", function() {
  equaltoPressed = false;
  display.textContent = "";
  output.textContent = "";
})


backspace.addEventListener("click", function() {
  equaltoPressed = false;
  display.textContent = display.textContent.substr(0, display.textContent.length - 1);
  evaluate();
})


plusMinus.addEventListener("click", function() {
  equaltoPressed = false;
  let expression = display.textContent;
  let flag = true;

  for (let i = expression.length - 1; i >= 0; i--) {
    if ("+-×÷".includes(expression[i])) {
      if (expression[i] !== "-")
        expression = expression.substring(0, i + 1) + "-" + expression.substring(i + 1, expression.length);
      flag = false;
      break;
    }
  }

  if (flag)
    expression = "-" + expression;
  display.textContent = expression;

  evaluate();
})


dot.addEventListener("click", function() {
  if (equaltoPressed)
    display.textContent = "";
  let start = 0;
  for (let i = display.textContent.length - 1; i >= 0; i--) {
    if ("+-×÷".includes(display.textContent[i])) {
      start = i + 1;
      break;
    }
  }
  if (!display.textContent.substring(start, display.textContent.length).includes("."))
    display.textContent += ".";
})

//Functions
function evaluate() {
  let expression = display.textContent;

  for (let i = 0; i < expression.length; i++) {
    if (expression[i] === "×")
      expression = expression.substring(0, i) + "*" + expression.substring(i + 1, expression.length);
    if (expression[i] === "÷")
      expression = expression.substring(0, i) + "/" + expression.substring(i + 1, expression.length);
  }

  if ("0123456789.".includes(expression[expression.length - 1]) && eval(expression) != expression)
    output.textContent = eval(expression);
  else
    output.textContent = "";
}


// .display and .output font resizing changing addon
let displayCover = document.querySelector(".display-cover");
let outputCover = document.querySelector(".output-cover");
let displaySize;
let outputSize;
// This part is a config of MutationObserver, options for the observer (which mutations to observe) 
let config = {
  attributes: true,
  childList: true,
  characterData: true
};

// Defining new class of the object MutationObserver, which provides the ability to watch for changes being made to the DOM tree. Basically - this class will be executed on every observing changes in '.display'.
let displayObserver = new MutationObserver(function(mutations) {

  displaySize = 100; // we will use it like a base 100% font-size later
  // set font size to '.display-cover'
  displayCover.style.cssText = 'font-size:' + displaySize + '%';
  
  // 'while' statement creates a loop that executes a specified statement as long as the test condition evaluates to true. The condition is evaluated before executing the statement. Each time we set font size -1 - the width of '.display' changes, and we keeping this loop until the width of '.display' will be not more then it's parent '.display-cover' 
  while(display.offsetWidth > displayCover.offsetWidth) {
    displaySize = displaySize - 1; //decrements font size by 1% each loop
    displayCover.style.cssText = 'font-size:' + displaySize + '%';
    // basically in DOM you see only result of the very last loop of this 'while' statment    
  } 
  
});

// Start observing the target node (your '.display') for configured mutations (using config)
displayObserver.observe(display, config);

//----------

// everything the same as above, but for '.output'
let outputObserver = new MutationObserver(function(mutations) {
  outputSize = 100; 
  outputCover.style.cssText = 'font-size:' + outputSize + '%';
  while(output.offsetWidth > outputCover.offsetWidth) {
    outputSize = outputSize - 1;
    outputCover.style.cssText = 'font-size:' + outputSize + '%';
  } 
});

// as you can see, 'config' is the same
outputObserver.observe(output, config);
* {
  border: 0;
  margin: 0;
}

body {
  min-height: 100vh;
  background: black;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-family: arial;
  font-size: 1.5rem;
  color: #f8f8f8;
}

.row {
  display: flex;
}

.light-grey {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #a6a6a6;
  height: 4.2rem;
  width: 4.2rem;
  border-radius: 50%;
  margin: .4rem;
  cursor: pointer;
  color: black;
}

.dark-grey {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #333333;
  height: 4.2rem;
  width: 4.2rem;
  border-radius: 50%;
  margin: .4rem;
  cursor: pointer;
}

.yellow {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ff9501;
  height: 4.2rem;
  width: 4.2rem;
  border-radius: 50%;
  margin: .4rem;
  cursor: pointer;
}

#zero {
  width: 9.2rem;
  border-radius: 0 50px 50px 0;
  border-top-right-radius: 50px;
  border-bottom-left-radius: 50px;
  border-bottom-right-radius: 50px;
  border-top-left-radius: 50px;
}
.display-font {
  font-size: 3rem;
}
.display-cover {
  width: 19.2rem;
  height: 3rem;
  margin: 0 .4rem 2rem .4rem;
  text-align: right;  
  font-size: 100%;  
  white-space: nowrap;
}

.display {
  font-size: 100%;
  display: inline-block;
}

.output-font {
  font-size: 2rem;
}
.output-cover {
  width: 19.2rem;
  height: 2rem;
  margin: 0 .4rem 2rem .4rem;
  text-align: right;  
  font-size: 100%;
  white-space: nowrap;
}

.output {
  font-size: 100%;
  display: inline-block;
}

i {
  font-size: 1.3rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css" integrity="sha256-46r060N2LrChLLb5zowXQ72/iKKNiw/lAmygmHExk/o=" crossorigin="anonymous" />
<div class="display-font">
  <div class="display-cover">
    <div class="display"></div>
  </div>
</div>
<div class="output-font">
  <div class="output-cover">
    <div class="output"></div>
  </div>
</div>
<div class="row">
  <div class="light-grey clear">AC</div>
  <div class="light-grey plus-minus">+/-</div>
  <div class="light-grey operators">÷</div>
  <div class="yellow backspace"><i class="fas fa-backspace"></i></div>
</div>
<div class="row">
  <div class="dark-grey numbers">7</div>
  <div class="dark-grey numbers">8</div>
  <div class="dark-grey numbers">9</div>
  <div class="yellow operators">×</div>
</div>
<div class="row">
  <div class="dark-grey numbers">4</div>
  <div class="dark-grey numbers">5</div>
  <div class="dark-grey numbers">6</div>
  <div class="yellow operators">-</div>
</div>
<div class="row">
  <div class="dark-grey numbers">1</div>
  <div class="dark-grey numbers">2</div>
  <div class="dark-grey numbers">3</div>
  <div class="yellow operators">+</div>
</div>
<div class="row">
  <div class="dark-grey numbers" id="zero">0</div>
  <div class="dark-grey dot">.</div>
  <div class="yellow equalto">=</div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.