在输入中将字符在整个宽度上等分

时间:2019-02-27 14:09:07

标签: javascript css reactjs html5 css3

我有一个输入字段和maxLength值,我想将输入字段分成相等的maxLength虚拟框,以便每个框包含一个字母。

例如,如果我的maxLength值为10且输入宽度为100px,我想将这10个字符分布在输入的整个宽度上,则所需结果如下所示


| H | e | l | l | o | w | o | r | l | d |

我决定使用下面的代码并添加css letterSpacing属性,基于字符W(因为它是最宽的字符)来计算字母间距,但这并不能提供准确的结果

enter code here

function calculateLetterSpacing(fontInfo, width, maxLength) {
  const inputWidth = width;
  const span = document.createElement('span');
  span.innerText = "W";
  span.style.fontSize = fontInfo.fontSize;
  span.style.fontFamily = fontInfo.fontName;
  document.body.appendChild(span);
  const charMaxWidth = span.offsetWidth;
  return (inputWidth - charMaxWidth*maxLength)/maxLength;
}

是否有任何直接的CSS属性可以使我做到这一点。

P.S字体可以是任何字符,不是等宽字体。

2 个答案:

答案 0 :(得分:0)

没有直接的CSS属性可以做到这一点,但是我让您的函数正常工作。点击底部的“运行代码段”,然后查看代码中的注释以获取解释。

var inputfield = document.getElementById("inputfield"); // the input field
var temp = document.getElementById("temphidden"); // the hidden span
var fontsizeOption = document.getElementById("fontsize"); // dropdown for font-size
var fontnameOption = document.getElementById("fontname"); // dropdown for font-name
var widthOption = document.getElementById("inputwidth"); // dropdown for input field's width
var lengthOption = document.getElementById("maxlength"); // dropdown for maxLength

// for demo purposes get the initial values from the dropdowns
var w = parseInt(widthOption.options[widthOption.selectedIndex].value); // initialize width
var m = parseInt(lengthOption.options[lengthOption.selectedIndex].value); // initialize maxLength
var f = { // initialize the fontInfo object
	fontSize : fontsizeOption.options[fontsizeOption.selectedIndex].value,
	fontName : fontnameOption.options[fontnameOption.selectedIndex].value
}; 

calculateLetterSpacing(f, w, m); // initialize the attributes

function calculateLetterSpacing(fontInfo, width, maxLength) {
	var inputWidth = width;
	
	// set the width of the input field
	inputfield.style.width = inputWidth + "px";
	
	// set the font-size of the input field and in the hidden span
	inputfield.style.fontSize = temp.style.fontSize = fontInfo.fontSize;
	
	// set the font name - both locations
	inputfield.style.fontFamily = temp.style.fontFamily = fontInfo.fontName;
	
	// set the max number of chars allowed in the input field
	inputfield.maxLength = maxLength;
	
	// copy the content of input field into the hidden span
	temp.innerHTML = inputfield.value;
	
	// the hidden span's size grows as each character is typed in,
	// therefore the width in pixels of the span == width in pixels
	// of the input string; calculate whiteSpace
	var whiteSpace = parseInt(inputfield.style.width) - temp.clientWidth;
	
	// before text is typed in the length is 0, so check for this
	if (temp.innerHTML.length == 0) { return; }
	
	// divide whiteSpace by numChars to get the amount of letter-spacing
	inputfield.style.letterSpacing = (whiteSpace / temp.innerHTML.length) + "px";
	
	// focus back to the input field
	inputfield.focus();
}
body {font:14px arial;text-align:center;}

#inputfield {
	padding-left:1px;
	text-align:center;
	display:block;
	margin:0 auto 20px auto;
	line-height:30px;
}

.selectwrapper { /* select boxes are for example purposes */
	display:block;
	margin:10px auto;
	width:110px;
}

.selectwrapper select {
	width:100%;
	font:18px arial;
	height:30px;
}
<!-- The input field -->
<p>Type something in ...</p>
<input id="inputfield" type="text" onkeyup="calculateLetterSpacing(f, w, m)">

<!-- The span below is hidden. When a character is entered, it is also copied to this 
	hidden span ("temphidden"). The span's growing width provides the width in 
	pixels of the character string regardless of the font type or size. Access the 
	width of the hidden span using [element].clientWidth -->
	
<span id="temphidden" style="position:absolute;visibility:hidden;white-space:nowrap;padding:1px;"></span> 

<!-- The dropdowns are for demonstration purposes, see "Run code snippet" -->

<div class="selectwrapper">font-size
<select id="fontsize" onchange="{f.fontSize=this.value; calculateLetterSpacing(f, w, m)}">
	<option value="8px">8px</option>
	<option value="12px" selected="selected">12px</option>
	<option value="18px">18px</option>
	<option value="24px">24px</option>
</select>
</div>

<div class="selectwrapper">font name
<select id="fontname" onchange="{f.fontName=this.value; calculateLetterSpacing(f, w, m)}">
	<option value="times">Times</option>
	<option value="arial" selected="selected">Arial</option>
	<option value="Verdana">Verdana</option>
	<option value="Courier">Courier</option>
</select>
</div>

<div class="selectwrapper">width
<select id="inputwidth" onchange="{w=this.value; calculateLetterSpacing(f, w, m)}">
	<option value="80">80px</option>
	<option value="100" selected="selected">100px</option>
	<option value="150">150px</option>
	<option value="220">220px</option>
</select>
</div>

<div class="selectwrapper">max length
<select id="maxlength" onchange="{m=this.value; calculateLetterSpacing(f, w, m)}">
	<option value="7">7</option>
	<option value="10" selected="selected">10</option>
	<option value="15">15</option>
	<option value="24">24</option>
</select>
</div>

答案 1 :(得分:0)

这是一个比较简单的解决方案,可以很好地工作,只需对其进行测试。让flexbox为您完成工作,这是您要求的CSS工具。

将此内容粘贴到HTML文件中,然后保存并在浏览器中打开,它将在屏幕上等距放置到word变量中的许多字母

<!DOCTYPE html>
<html>
<style>
    #container {
        margin: 0;
        padding: 0;
        width: 100%;
        display: flex;
        flex-direction: row;
        justify-content: space-around;
    }
</style>
<div id="container">
</div>
<script>
    let lettersHTML = "";
    //define the word
    let word = "thing";
    //split it
    let split = word.split('');
    //this splits your word into ["t","h","i","n","g"]
    //iterate with for loop - over each letter
    for (let i=0; i<split.length; i++) {
        let para = document.createElement("P");
        para.innerHTML = `${split[i]}`;
        document.getElementById("container").appendChild(para);
    }
    </script>
</html>