我正在处理一个表单,我们可以选择将产品分配给对象,或者在这种情况下是用户。根据我们的数据库中提供的值在代码中检索和使用,默认情况下,此用户可能拥有这些特定产品之一。
if($Pants=="1"){
echo "<input type='checkbox' onclick='PantsInput(this);' checked>Pants<br>";
}
else {
echo "<input type='checkbox'> Pants<br>";
}
如果选中此复选框,则会创建一个用于创建文本输入字段的JavaScript。它可以工作,但只有我继续并手动选择它。
我想要完成的是让脚本识别是否已经选中了复选框。仍然可以手动执行此操作,但如果已选中复选框,则字段在加载时显示会很棒。
这是脚本:
function PantsInput(cbox) {
if (cbox.checked) {
var input = document.createElement("input");
input.type = "text";
input.value = "1";
input.name = "AmountPants"
var div = document.createElement("div");
div.id = cbox.name;
div.innerHTML = "Amount of pants: ";
div.appendChild(input);
document.getElementById("pantsinput").appendChild(div);
} else {
document.getElementById(cbox.name).remove();
}
}
这是一个JSFiddle,显示了我正在努力的方面: https://jsfiddle.net/orqweyzc/
此框已经过检查,但只有在您继续操作并取消选中并自行重新检查时,该字段才会显示。我尝试了一些不同的DOM活动,但似乎无法做到。
答案 0 :(得分:1)
您已点击复选框注册了PantsInput
,这意味着在您点击它之前它不会自动运行。因此,为了实现这一目标,您必须强行称之为。
if($Pants=="1"){
echo "<input type='checkbox' onclick='PantsInput(this);' name='checkbox1' checked>Pants<br>";
echo "<script>PantsInput(document.getElementsByName('checkbox1')[0])</script>";
}
else {
echo "<input type='checkbox'> Pants<br>";
}
希望这会有所帮助!!
答案 1 :(得分:1)
你可以做这样的事情
window.addEventListener('load', function() {
var inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++) {
switch (inputs[i].getAttribute("data-type")) {
case 'pants':
case 'shirts':
inputs[i].addEventListener('click', function(e) {
if (e.target.checked) {
addElement(e.target);
} else {
document.getElementById(e.target.name).remove();
}
})
if (inputs[i].checked) {
addElement(inputs[i]);
}
break;
}
}
})
function addElement(t) {
var vals = t.getAttribute('data-text').split('|');
var input = document.createElement("input");
input.type = "text";
input.value = vals[0];
input.name = vals[1];
var div = document.createElement("div");
div.id = t.name;
div.innerHTML = vals[2];
div.appendChild(input);
document.getElementById(vals[3]).appendChild(div);
}
<p>Clothing</p>
<input type="checkbox" name="check1" checked data-type="pants"
data-text="1|AmountPants|Amount of pants: |pantsinput" />Pants
<br>
<input type="checkbox" name="check2" data-type="shirts"
data-text="2|AmountShirts|Amount of shirts: |shirtinput" />Shirt
<br>
<p id="pantsinput"></p>
<p id="shirtinput"></p>
答案 2 :(得分:1)
解决问题的最简单方法是设置一种方法,通过该方法可以在页面加载时触发您正在侦听的事件,以生成<input>
元素。要做到这一点,您需要添加以下内容:
// creating the event that we're listening for:
var clickEvent = new Event('click');
// using document.querySelectorAll('input[type=checkbox]:checked')
// to return the nodeList of <input> elements whose 'type' attribute
// is equal to 'checkbox' which are also checked, and passing that
// nodeList to Array.from() to convert the Array-like nodeList into
// an Array, allowing us to use Array methods:
Array.from(document.querySelectorAll('input[type=checkbox]:checked'))
// Array.prototype.forEach() allows us to iterate over every node
// in the Array of nodes:
.forEach(function(input){
// 'input': a reference to the current <input> element in the
// Array of <input> elements over which we're iterating.
// firing the clickEvent (created above) from the <input>
// element, causing the event-handler to be fired:
input.dispatchEvent(clickEvent);
});
function PantsInput(cbox) {
if (cbox.checked) {
var input = document.createElement("input");
input.type = "text";
input.value = "1";
input.name = "AmountPants"
var div = document.createElement("div");
div.id = cbox.name;
div.innerHTML = "Amount of pants: ";
div.appendChild(input);
document.getElementById("pantsinput").appendChild(div);
} else if (document.getElementById(cbox.name)) {
document.getElementById(cbox.name).remove();
}
}
function ShirtInput(cbox) {
if (cbox.checked) {
var input = document.createElement("input");
input.type = "text";
input.value = "2";
input.name = "AmountShirt"
var div = document.createElement("div");
div.id = cbox.name;
div.innerHTML = "Amount of shirts: ";
div.appendChild(input);
document.getElementById("shirtinput").appendChild(div);
} else if (document.getElementById(cbox.name)) {
document.getElementById(cbox.name).remove();
}
}
var clickEvent = new Event('click');
Array.from(document.querySelectorAll('input'))
.forEach(function(input) {
input.dispatchEvent(clickEvent);
});
<p>Clothing</p>
<input type="checkbox" name="check1" checked onclick="PantsInput(this);" />Pants
<br>
<input type="checkbox" name="check2" onclick="ShirtInput(this);" />Shirt
<br>
<p id="pantsinput"></p>
<p id="shirtinput"></p>
请注意,因为我们正在遍历DOM中的元素,所以此代码必须在元素创建之后运行并存在于DOM中,这最容易通过放置{在结束<script>
标记之前{1}}。
现在,虽然问题表面上已经解决了,但你仍然有两个相同的函数,所以如果我们可以重构那个使用相同的函数来产生稍微不同的结果,基于被检查的元素,那应该是更有意义。
此外,使用内联事件处理程序被认为是不好的做法,并且“突兀的JavaScript”会让您更难以及将来需要更新时维护代码的人。此外,我们会使用</body>
将<input>
元素与<input>
元素相关联。
因此,在下文中,我们将使用JavaScript来绑定事件处理程序,我们将重构代码,以便我们只使用一个函数:
<label>
// using a single named function (the name of which tries to
// convey the functionality):
function amountsOf() {
// caching the 'this' (passed automatically from the
// EventTarget.addEventListener() method (later in
// the code):
var changed = this,
// caching the textContent of the <input> element's
// parentNode (the <label> element), with the leading
// and trailing white-space removed courtesy of
// String.prototype.trim():
inputName = changed.parentNode.textContent.trim(),
// creating a new <input> element:
input = document.createElement("input"),
// creating a new <label> element:
label = document.createElement('label'),
// creating text for the <label> element, via the creation
// of a new TextNode:
text = document.createTextNode("Amount of " + inputName + ": "),
// finding the element to which the content should be
// appended, or from which it should be removed:
contentTo = document.getElementById(inputName.toLowerCase() + 'input');
// if the current <input> element is checked:
if (changed.checked) {
// we append the textNode to the <label>:
label.appendChild(text);
// then append the <input> to the <label>:
label.appendChild(input);
// setting the type property/attribute of the <input>:
input.type = "text";
// setting the current value of the <input> from the
// (valid) custom data-inputvalue attribute added to
// the <input>, though honestly I don't think this
// adds any benefit to the user of the site:
input.value = changed.dataset.inputvalue;
// setting the <input> element's name property:
input.name = "Amount" + inputName;
// appending the <label> to the element to which
// content should be added:
contentTo.appendChild(label);
} else {
// finding the <label> element within the <p>
// to which content was added, and removing
// it:
contentTo.querySelector('label').remove();
}
}
// using document.querySelectorAll() to find all <input>
// elements of type=checkbox, and passing that nodeList
// to Array.from(), to convert the Array-like NodeList
// into an Array, to enable the use of Array methods:
Array.from(document.querySelectorAll('input[type=checkbox]'))
// her we use Array.forEach() to iterate over the Array of
// <input> elements, using an Arrow function syntax;
// 'input' is a reference to the current <input> node of
// the Array, and we then pass that to the Arrow function,
// which binds the amountsOf() function (though note the
// deliberate absence of parentheses) as the 'change'
// event-handler for the current <input> element:
.forEach(input => input.addEventListener('change', amountsOf))
// here we create a new Event, in order to fire the named
// 'change' event on those elements that have the checked
// attribute/property:
var changeEvent = new Event('change');
// here we create an Array of all the <input> elements of
// type=checkbox, which are currently checked:
Array.from(document.querySelectorAll('input[type=checkbox]:checked'))
// we iterate over that Array of elements using the
// anonymous method (though we could use an Arrow
// function instead):
.forEach(function(input) {
// 'input' is a reference to the current <input>
// element in the array of <input> elements over
// which we're currently iterating:
// here we fire the 'change' event on those
// found checked <input> elements:
input.dispatchEvent(changeEvent);
});
function amountsOf() {
var changed = this,
inputName = changed.parentNode.textContent.trim(),
input = document.createElement("input"),
label = document.createElement('label'),
text = document.createTextNode("Amount of " + inputName + ": "),
contentTo = document.getElementById(inputName.toLowerCase() + 'input');
if (changed.checked) {
label.appendChild(text);
label.appendChild(input);
input.type = "text";
input.value = changed.dataset.inputvalue;
input.name = "Amount" + inputName;
document.getElementById(inputName.toLowerCase() + 'input').appendChild(label);
} else {
contentTo.querySelector('label').remove();
}
}
Array.from(document.querySelectorAll('input[type=checkbox]'))
.forEach(input => input.addEventListener('change', amountsOf))
var changeEvent = new Event('change');
Array.from(document.querySelectorAll('input[type=checkbox]:checked'))
.forEach(function(input) {
input.dispatchEvent(changeEvent);
});
label {
display: block;
}
请注意,您的HTML和JavaScript函数都有一些更改。
我们将<p>Clothing</p>
<label>
<input type="checkbox" name="check1" data-inputvalue="1" checked />Pants</label>
<label>
<input type="checkbox" name="check2" data-inputvalue="2" />Shirts</label>
<p id="pantsinput"></p>
<p id="shirtsinput"></p>
元素中的<input>
元素包装到html中,以便点击<label>
元素的文本可以关注或更改关联的<label>
元素(为了更好的用户界面)。我更新了'衬衫'段落的<input>
,从'shirtinput'到'shirtsinput',只是为了保持id
结构的一致性,因为我们只使用了一个函数。鉴于用户可能想要选择多件衬衫,这也具有语义意义。
在JavaScript函数中,我完全删除了id
元素,因为<div>
不能是<div>
元素的子元素,并且创建的<p>
元素是现在无论如何包裹在<input>
。
此外,我没有对JavaScript中新创建的<label>
元素的值进行硬编码,而是将这些值移动到HTML中的自定义<input>
属性中,data-*
属性。虽然我保持了你的价值观和插入,但我真的不确定这给用户带来了什么好处;当然,默认应该是data-inputvalue
或1
,因为衬衫或裤子的数量完全取决于他们(我认为0
可能是更好的选择,否则他们会'不太可能在第一时间点击1
。
参考文献:
Array.prototype.from()
。Array.prototype.forEach()
。ChildNode.remove()
。document.createElement()
。document.createTextNode()
。document.querySelectorAll()
。Event()
constructor。EventTarget.addEventListener()
。EventTarget.dispatchEvent()
。HTMLElement.dataset
。Node.appendChild()
。Node.parentNode
。参考书目: