iCMS

小实例---关于input宽度自适应以及多个input框合并拆分

好喜欢专业转载优质博客文章的地方哦~

前两个月,公司内部需要开发关于大数据方面的辅助工具语料分词系统,在这个项目中遇到以下几个主要问题,在此分享~

一、input宽度根据内定文本宽度自适应

背景:项目需求中,前台展示,需要从后台获取的.txt文件解析成很多字符串,然后分别放在前台input框中,贴图:

小实例---关于input宽度自适应以及多个input框合并拆分

其中,每一个字符串,长度不一,所以,input框要根据字符串的长度,发生变化,这里就要解决input自适应的问题了。

方法一:网上搜索的,误差很大,仅供参考~

小实例---关于input宽度自适应以及多个input框合并拆分

然后,我又改善了一下,减小误差。

//字符串文本

var a1 = "人民网/nz 莫斯科/nsf 31日/t 电/n (/w 记者/nnt 屈海齐/nr )/w 据/p 俄新社/nt 报道/v ,/w 《/w [今日/t 俄罗斯/nsf]/nz 》/w (/w RussiaToday/x )/w [总裁/nnt德米特里·基谢廖夫/nrf决定]/v 任命/vn 玛格丽特·西莫尼/nrf 杨/ng 为/p 《/w [今日/t 俄罗斯/nsf]/nz 》/w 通讯社/nis 主编/v ,/w 同时/c 兼任/v 《/w [今日/t俄罗斯/nsf]/nz 》/w [电视/n 频道/n]/nz 主编/v 。/w 玛格丽特·西蒙尼扬/nrf 1980年/t 生于/v [克拉斯/nrf 诺达尔/nrf]/ns 。/w 毕业/v 于/p [库班/nrf 国立/b 大学/nis 新闻系//w 频道/n 主编/v 。/w 2013年12月9日/t ,/w [俄罗斯/nsf 总统/nnt]/nz 普京/nrf 下令/v 在/p 三个月/t 内/f 将/d 《/w 俄新社/nt 》/w 和/cc 《/w [俄罗斯/nsf 之/uzhi 声/qv]/nz 》/w 电台/nis 合并/v 为/p 《/w [今日/t 俄罗斯/nsf]/nz 》/w [国际/n 通讯社/nis]/nt 。/w ";

//把字符串根据空格整理成数组

var strArr = a1.split(" ");

console.log(strArr)

for(var i= 0;i<=strArr.length;i++){

var ssd = strArr[i]

//数组元素存放容器

$("body").append('<div class="q1" display:inline-block;font-size:12px;fontFamily:"Serif""></div> ');


$(".q1").text(ssd) var wid =$(".q1").text(strArr[i]).width(); $(".q1").remove();


//获取宽度赋值给input宽度


$(".a1").append($('<input type="text">').val(strArr[i]).css({


width: wid +18,


fontSize: "12px",


fontFamily:"Serif",


boxSizing:"border-box",


padding:"5px"


}))


}

想法:

首先,在body里新创建一个div(不建议使用span等块状级元素),设置display:inline-block、字体、字体大小。然后把字符串值赋值进去,获取div宽度,再删除掉div。把获取的宽度设置成input的宽度,这里的width = wid +18,需要在页面调试合适宽度。其中,input内的字符串也要设置字体、字体大小,减少误差。最后成为这样~

小实例---关于input宽度自适应以及多个input框合并拆分

方法二:根据scrollWidth、clientWidth判断。

scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大。

clientWidth:对象内容的可视区的宽度。

在input内,scrollWidth也就相对于input中value值的长度。clientWidth相当于input默认宽度(能看到的宽度)。

for (var i = 0; i < strArr.length; i++) {

var ssd = strArr[i];

$(".a1").append($('<input type="text">').val(strArr[i]));

}

$("input").each(function(index,item){

if (item.scrollWidth > item.clientWidth) {

item.style.width = item.scrollWidth + 4 + "px";

}

})

注意两点:

一点是,代码中展示的scrollWidth > clientWidth的时候,因为value值内容含字母符号等,获取scrollWidth有几像素的误差,加上就可以了,调试过后,没问题。

第二点,scrollWidth < clientWidth 时候又该怎么让input自适应呢??? 做东西呢,不能过于死脑筋。把input的宽度设置5px或者10px,让scrollWidth 总是大于clientWidth不就可以了吗!老铁,没毛病吧,哈哈哈哈~

小实例---关于input宽度自适应以及多个input框合并拆分

二、input合并

关于合并,在开始解决这个功能之前,应该分析出该功能实现所遇到的核心问题。

点击多个input是否连续,非连续不可合并。(项目需求)

获取到的value值如何添加到合并的位置上。

分析完问题,方向明确了,也就好做了。

首先是连续问题,先看代码:

var inputArr = [];

var item = 0;

var len;

var inputVal="";

$("#demo").on("click","input",function(){

//添加选中样式

$(this).toggleClass('bd1');

item = $(this).index();

inputArr.push(item);

//再次点击,inputArr数组删除 所对应的item值

len=inputArr.length;

for(var i=0;i<len;i++){

if(item == inputArr[i]){

inputArr.splice(i,1);

console.log(inputArr);

return;

}

};

//数组排序

inputArr.sort();

console.log(inputArr)

});

说明:

这里只是做了准备工作。点击input框获取它的index值,然后把index值push到一个新数组,然后进行排序。其中for循环是input框取消选中时,删除新数组中所对应的index值。

接下来需要一个判断数组是否为连续的如[1,2,3,4,5]方法,网上这类的有很多,我用了其中一个:

function isContinuationInteger(arr){

if(!arr){

return false;

}

if(arr.length==0){

return true;

}

var len=arr.length;

var n0=arr[0];

var sortDirection=1;

if(arr[0]>arr[len-1]){

sortDirection=-1;

}

if((n0*1+(len-1)*sortDirection)!==arr[len-1]){

return false;

}

var isContinuation=true;

for(var i=0;i<len;i++){

if(arr[i]!==(i+n0*sortDirection)){

isContinuation=false;

break;

}

}

return isContinuation;

}

然后就是点击合并按钮,所要处理的事件了。

$("#combine").on("click",function(){

var strArr = '';

if(!isContinuationInteger(inputArr)){

alert('不合法');

return ;

}else{

inputArr.map(function(v){

strArr += $('input').eq(v).val();

})

$(".bd1").each(function(e){

console.log(e);

$(this).eq(e).before($('<input type="text" readonly>').val(strArr));

$(this).remove();

inputArr =[];

//console.log($(this).eq(e))

})

}

})

这里要注意的有:

点击事件需要用到on()方法,不可直接用click方法,主要原因是在这个点击事件内添加了新的input框,然后,新的input也可以实现合并功能,也就有了事件委托。

数组遍历map()方法,调用数组中的每一个元素,然后把相对应的value值合并成一个字符串。

新的input添加,这里用到点击input动态添加的class,然后是each()方法返回的index值,再根据input框所在位置eq(),在它之前添加input,然后删除它本身。

以上步骤完成之后,一定要清空存放input框index值的数组。这点要注意。

三、input拆分

input拆分,核心问题在于,获取光标所在位置,然后根据空格键进行拆分,用js或者jq实现的话,很麻烦,为了效率在网上找一些封装方法。要是用angluar或者vue,根据ng-model或者v-model双向数据绑定,再用watch监督,根据value值中的光标位置,点击快捷键会出现空格,然后进行字符串拆分,应该就容易了!(纯想法,有兴趣的可以尝试一下)

这里主要是jq实现:

首先是封装方法,还是前边讲的,有很多时候不能死脑筋,换种思路,问题就迎刃而解了。如果说,根据光标位置进行快捷键进行拆分不好获取,是不是可以找一些方法在光标位置插入某个字符串,然后再根据这个字符串进行分割,然后就找到了下面的封装方法:

/* 在textarea处插入文本--Start */

(function($) {

$.fn.extend({

insertContent : function(myValue,t) {

var $t = $(this)[0];

if (document.selection) { // ie

this.focus();

var sel = document.selection.createRange();

sel.text = myValue;

this.focus();

sel.moveStart('character',-l);

var wee = sel.text.length;

if (arguments.length == 2) {

var l = $t.value.length;

sel.moveEnd("character",wee + t);

t <= 0 ? sel.moveStart("character",wee - 2 * t - myValue.length) : sel.moveStart( "character",wee - t - myValue.length);

sel.select();

}

} else if ($t.selectionStart

|| $t.selectionStart == '0') {

var startPos = $t.selectionStart;

var endPos = $t.selectionEnd;

var scrollTop = $t.scrollTop;

$t.value = $t.value.substring(0,startPos)

+ myValue

+ $t.value.substring(endPos,$t.value.length);

this.focus();

$t.selectionStart = startPos + myValue.length;

$t.selectionEnd = startPos + myValue.length;

$t.scrollTop = scrollTop;

if (arguments.length == 2) {

$t.setSelectionRange(startPos - t,

$t.selectionEnd + t);

this.focus();

}

} else {

this.value += myValue;

this.focus();

}

}

})

})(jQuery);

/* 在textarea处插入文本--Ending */

使用方法是:$(文本域选择器).insertContent("插入的内容");

贴码:

$("#split").on("click",function(){

var splitArr=[];

$(".bd1").each(function(e){

splitArr.push(e);

});

if(splitArr.length>1){

alert("只能选择一个字符串拆分!");

$(this).removeClass("bd1");

return;

}else{

$(".bd1").each(function(e){

//inputVal是选中input框的value值

if(inputVal.length<2){

alert("字符数量必须大于两个!");

$(this).removeClass("bd1");

return;

}else{

if( $(this).hasClass("bd1")){

$(this).toggleClass("dw1");

$(this).removeAttr("readonly");

//console.log("sdasdsad");

$(this).keypress(function(event){

if ( $(this).hasClass('dw1')){

if (event.keyCode == 32) {

$(this).insertContent("#");

//console.log($(this).insertContent("#"))

var value1 = $(this).val();

console.log(value1.split("#"))

var valueone = value1.split("#")[0];

var valuetwo = value1.split("#")[1];

$(this).eq(e).before($('<input type="text" readonly>').val(valueone));

$(this).eq(e).after($('<input type="text" readonly>').val(valuetwo));

$(this).remove();

}

}

})

}

}

});

}

});

这里用到了字符串分割成数组的split()方法,js文档中有详细介绍,在这里就不说明了。

后记:内容虽然很少,可我偏偏整理了将近一天的时间 ,真的是哭笑不得啊~

2017.12.19

0

上一篇:

:下一篇

精彩评论

暂无评论...
验证码 换一张
取 消

热门标签