这就是它应该如何工作的。默认情况下,有两组输入字段,其中百分比字段的值均为50%。现在,无论何时添加新的输入字段,都应在所有百分比字段之间分配百分比字段值,例如,如果有3组,则每个百分比字段应该具有33.33%。如果有4,则各占25%。现在,这部分工作正常。
现在,我正在尝试在其之上添加更多功能。我将简要介绍这些功能以及与之相关的问题。
当用户单击percentage input field
时,以前的值消失,用户键入一个新的百分比值,并在两个输入字段之间进行划分。但是问题在于,它在用户刚刚输入的值的末尾添加了两个"%"
符号。
第二个问题是,假设用户在第一个percentage field
或第二个input field
中键入新的百分比值,然后通过Add Field
按钮添加一个新的input field
,这些百分比不会在所有输入值之间划分。新的percentage value
没有考虑新的percInput
。我能想到的一个原因是input field
变量没有以某种方式更新。
第三个问题与第二个问题相似。如果用户先添加新的percentage value
,然后在该新input field
中键入percInput
,则百分比值将完全不除。这也可能是因为percInput
变量未更新。与此相关的另一个问题是,单击新的百分比输入字段不会像以前的默认字段一样删除先前的值。
这很奇怪。如果用户单击百分比输入字段,但未添加值,而是继续添加新字段,则百分比值将在所有百分比之间分配。
所有这些问题在某种程度上都是相互关联的,我感到它们都是由于一个变量calculatePercentage
而引起的。我想添加新的输入字段时不会更新。以前,我使用percInput
函数来更新const form = document.querySelector("form");
const span = document.querySelector("span");
const addBtn = document.querySelector("#addField");
const html = `
<div class="url-pair">
<input type="url" placeholder="3">
<input type="text" class="perc">
<button class="delete-btn" type="button">Delete</button>
</div>
`;
// percentage variable and percentage calculation for the first time
let percInput = document.querySelectorAll('.urls-container .perc');
let percentage = (100 / percInput.length).toFixed(0).toString() + "%";
percInput.forEach((item) => {
item.setAttribute("value", percentage);
});
const removeField = (e) => {
if (!e.target.classList.contains('delete-btn')) return;
e.target.parentElement.remove();
calculatePercentage();
}
// percentage input variable update and percentage calculation
const calculatePercentage = () => {
percInput = document.querySelectorAll('.urls-container .perc');
percentage = (100 / percInput.length).toFixed(0).toString() + "%";
percInput.forEach((item) => {
item.setAttribute("value", percentage);
});
}
// remove a field
form.addEventListener('click', removeField);
// add input field
addBtn.addEventListener('click', () => {
span.insertAdjacentHTML("beforeBegin", html);
calculatePercentage();
});
const percInputChange = function() {
let val = this.value,
$allInputs = $(percInput);
if(val > 100) {
$allInputs.val((100 / $allInputs.length) + "%");
calculatePercentage();
}else {
$(percInput).not(this).val( (100 - val) / ($allInputs.length - 1) + "%");
setTimeout(() => {
this.value = this.value + "%";
}, 500);
calculatePercentage();
return;
}
};
// event listener when user types in a new percentage value
$( percInput ).on('keyup', percInputChange);
// event listener to hide previous input value
$( percInput ).focus(function() {
this.value = "";
});
// event listener to divide the percetange values when the user clicks away
$( percInput ).blur(function() {
if(this.value === ""){
percInput.forEach(item => {
item.value = ( 100 / percInput.length ).toFixed(0).toString() + "%";
return;
});
}
});
变量,并在此起作用。但是当我在上述情况下尝试使用它时,它将无法正常工作。
这是我到目前为止尝试过的代码:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#" method="POST">
<div class="urls-container">
<div class="url-pair">
<input type="url" placeholder="1">
<input type="text" class="perc">
<button class="delete-btn" type="button">Delete</button>
</div>
<div class="url-pair">
<input type="url" placeholder="2">
<input type="text" class="perc">
<button class="delete-btn" type="button">Delete</button>
</div>
<span></span>
</div>
<div>
<div>
<button type="button" id="addField">Add Field</button>
</div>
<div>
<button type="submit">Create</button>
</div>
</div>
</form>
{{1}}
我知道这篇文章很奇怪,有很多问题。但是请耐心等待,因为我仍在学习中,如果我不将自己推入这些复杂的编码问题并陷入困境,我将无法学习。昨天我整天都在根据自己的知识尝试各种方法。如果我尝试使用所有方法,则帖子的篇幅会很大。所以,请忍受我。请帮助有需要的编码员。谢谢
PS。我一起使用jQuery和JS,这不是正确的选择。但是,一旦解决问题,我将重构并更改它们。 PS。
答案 0 :(得分:1)
我不太确定您要使用脚本真正实现什么目标。但是我可以通过删除冗余位来重新开始。以下代码段将允许您添加或删除输入行,并将相应地调整百分比。
也许您可以指定如何您希望脚本对任何用户输入做出反应?
// add flields:
function addfields(){
let all=$('.urls-container'), r=$('div:last',all).clone(),
url=r.find('input[type=url]')[0];
url.placeholder=+url.placeholder+1;
$('.perc',r).removeAttr('data-manual');
all.append(r); calcperc();
}
// even distribution:
function calcperc(){
let fix=$('.perc[data-manual]'),sum=0;
fix.each(function(){sum+=parseFloat(this.value)});
let rest= $('.perc').not(fix);
rest.val(((100-sum)/rest.length).toFixed(2)+'%')
}
// manual distribution:
function recalc(){let inps=$('.perc'),cur=parseFloat(this.value);
if (inps.length>1){
this.value=cur.toFixed(2)+'%'; this.dataset.manual=1;
calcperc();
} else this.value="100%"
}
// delegated event management:
$('form')
.on('submit',function(e){e.preventDefault()}) // de-activate submit for testing
.on('change','.perc',recalc)
.on('click','.delete-btn',function(){$(this).parent().remove();calcperc()})
.on('click','#addField',addfields);
// initial distribution:
calcperc();
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<form action="#" method="POST">
<div class="urls-container">
<div class="url-pair">
<input type="url" placeholder="1">
<input type="text" class="perc">
<button class="delete-btn" type="button">Delete</button>
</div>
<div class="url-pair">
<input type="url" placeholder="2">
<input type="text" class="perc">
<button class="delete-btn" type="button">Delete</button>
</div>
<span></span>
</div>
<div>
<div>
<button type="button" id="addField">Add Field</button>
</div>
<div>
<button type="submit">Create</button>
</div>
</div>
</form>
我的recalc()
当前版本允许您覆盖百分比值的一个。然后将调整所有其他值,因此总和再次为100%。
还请注意,在我的版本中,recalc()
事件是在input
事件上触发的,而不是keyup
事件,否则添加百分号的动作会严重干扰任何输入由用户尝试。
修改
Lastet编辑涉及在输入字段中使用data-manual
属性“标记”手动更改的百分比。这将保护该字段免受将来的重新计算。其余百分比将在非固定字段之间平均分配。