直到最近,以下代码片段工作正常,复选框本身被CSS隐藏,点击按钮改变了复选框的状态,然后可以在表单提交时检测到,但是,最近(不确定何时) )这停止了工作,现在点击按钮什么都不做:
<label for="someCheckBox" class="someCheckBox">
<input type="checkbox" id="someCheckBox" name="someCheckBox" value="checkBox" />
<button type="button" title="Some CheckBox">Some CheckBox</button>
</label>
CSS:
#someCol label.someCheckBox button {
background-color: black;
color: #C0C0C0;
height: 1.5em;
margin: 10px 4px 0 0;
border: 1px solid #C0C0C0;
-moz-border-radius: .75em;
-webkit-border-radius: .75em;
border-radius: .75em;
font-size: 1.0em;
font-family:"Final Frontier";
font-weight: bold;
width: 40px;
}
#someCol label.someCheckBox button:hover {
background-color: #C0C0C0;
color: black;
border: 1px solid #606060;
cursor: pointer;
-moz-animation-duration: 3s;
-moz-animation-name: glow;
-moz-animation-iteration-count: infinite;
-moz-animation-play-state: running;
-webkit-animation-duration: 3s;
-webkit-animation-name: glow;
-webkit-animation-iteration-count: infinite;
-webkit-animation-play-state: running;
animation-duration: 3s;
animation-name: glow;
animation-iteration-count: infinite;
animation-play-state: running;
}
#someCol label.someCheckBox input {
position:absolute;
top:-20px;
}
#someCol label.someCheckBox input:checked + button {
background-color: #C0C0C0;
color: black;
border: 1px solid #606060;
box-shadow: 0 0 15px #C0C0C0;
-webkit-box-shadow: 0 0 15px #C0C0C0;
}
#someCol label.someCheckBox button {
width: 90px;
margin: 10px 0 0 4px;
}
应该注意的是,我简单地尝试将这些按钮/复选框中的一个更新为文本标签而不是按钮,并且复选框状态确实按预期更改,但是,我希望按钮用于表单的外观,我有很多这样的工具,所以要改变它们需要做很多工作......
同样我最初更喜欢这种方法,因为它减少了JS使表单更加HTML友好的需要,所以尽管我可以编写一个脚本来改变复选框的状态,但它并没有为我的根本目的服务,而且,当以前工作时,需要做很多工作来纠正所有设置的按钮。
由于此前确实有效,而且我有时没有触及代码库,我不确定除了浏览器更新之外发生了什么变化,任何人都可以提供帮助,因为我已经撕掉我的头发了现在几个小时,无法弄清楚改变了什么......
答案 0 :(得分:0)
没有得到答案,所以最简单的替代方案是添加JS onClick事件。这不是我希望它如何工作,但却是最快的解决方案:
<label for="someCheckBox" class="someCheckBox">
<input type="checkbox" id="someCheckBox" name="someCheckBox" value="checkBox" />
<button type="button" title="Some CheckBox" onclick="changeStateButton(\'someCheckBox\',\'check\');">Some CheckBox</button>
</label>
function changeStateButton(selID,selType){
if (document.getElementById(selID) !== null && document.getElementById(selID) !== "undefined"){
if (selType="check"){
if (!document.getElementById(selID).checked) {
document.getElementById(selID).checked = "checked";
} else {
document.getElementById(selID).checked = "";
}
} else if (selType="radio"){
if (!document.getElementById(selID).checked) {
document.getElementById(selID).checked = "checked";
}
}
}
}
如果有人能够回答为什么它停止使用纯HTML方式,我仍然有兴趣听听。
答案 1 :(得分:0)
提出的解决方案似乎过于复杂和冗长。我倾向于利用这样一个事实:相关元素既是UI元素,也是响应鼠标事件的。
我还考虑使代码更智能,以便它不需要内联JS将按钮附加到其目标输入元素。也许通过保存目标id的属性,或者更好 - 您可以获得单击按钮(标签)的父级,然后获取它包含的(唯一)输入元素并对其执行操作。
要以我描述的第一种方式进行,你可以调用目标元素的click()
函数,并用3行完成,如下所示:
function myChange(tgtId)
{
var tgtElem = byId(tgtId);
if (tgtElem != undefined)
tgtElem.click();
}
此功能是您已经使用的功能的替代品,也可以使您的html更整洁并且不易出错,无需传递第二个变量。虽然它仍然需要通过内联javascript附加。
也许一个更简洁的解决方案是编写一个处理程序,它可以解决按钮与哪个元素配对,因为它们是同一个父级的唯一兄弟。它还意味着你可以在一个非常小的循环中设置任意数量的它们,同样保持你的html清洁。
首先,执行检查/取消检查的功能。
function myChange2(evt)
{
var clickedButton = this;
var containingLabel = clickedButton.parentNode;
var tgtElem = containingLabel.getElementsByTagName('input')[0];
if (tgtElem != undefined)
tgtElem.click();
}
我们找出导致函数被调用的元素,获取它的父元素然后获取它包含的按钮列表中的第一个元素(应该只有一个,但函数返回一个列表,NodeList是具体)。然后我们只需单击该元素,允许浏览器处理状态的变化。
最后,我们需要一种方法将函数连接到需要它的所有元素。我们将使用querySelectorAll,因为它允许我们使用css选择器,这极大地简化了获取我们实际感兴趣的元素列表的过程。我使用>
字符来表示元素必须是标签的直接子元素 - 它不会以包含在标签中包含的另一个元素中的按钮为目标。 (您可以在我添加的第一个复选框中看到此效果,方法是在标签内的跨区中包含一个按钮。)然后,我们会附加该事件,以便我们访问this
关键字在处理程序函数中,它允许代码知道哪个按钮导致它被调用。
这是一个完整的例子 - 我已经更改了标签的类别,以便将事件附加到我添加的事件中,不会干扰已经存在的事件。我还从每个按钮中删除了type='button'
属性 - 如果您正在使用输入(类型按钮),则只需要此属性。我还从复选框中删除了value
属性,因为它已选中或未选中 - 浏览器会为我们处理此问题。单选按钮需要它,但复选框不需要它。
关于我在评论部分中关于转义'
字符的评论 - 您可以用双引号括起单引号,或者相反。当它被相同类型的引号括起来时,你只需要转义引用。
因此,如果没有使用斜杠转义,'"'
就可以了,"'"
也是如此。
您只需要'''
或"""
,每个'\''
和"\""
<!DOCTYPE html>
<html>
<head>
<script>
function byId(id){ return document.getElementById(id); }
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
var elemsToInit = document.querySelectorAll('label.btnProxy > button');
var i, n = elemsToInit.length;
for (i=0;i<n;i++)
{
elemsToInit[i].addEventListener('click', myChange2, false);
}
}
function myChange(tgtId, tgtType)
{
var tgtElem = byId(tgtId);
if (tgtElem != undefined)
tgtElem.click();
}
function myChange2(evt)
{
var clickedButton = this;
var containingLabel = clickedButton.parentNode;
var tgtElem = containingLabel.getElementsByTagName('input')[0];
if (tgtElem != undefined)
tgtElem.click();
}
</script>
</head>
<body>
<label for="someCheckBox" class="someCheckBox">
<input type="checkbox" id="someCheckBox" name="someCheckBox" value="checkBox" />
<button type="button" title="Some CheckBox" onclick="myChange('someCheckBox','check');">Some CheckBox</button>
</label>
<hr>
<label class="btnProxy"><input type="checkbox"/><button>Toggle</button><span><button>I'm Inert!</button></span></label>
<br>
<label class="btnProxy"><input type="checkbox"/><button>Toggle</button><button>I work too!</button></label>
<br>
<label class="btnProxy"><input type="checkbox"/><button>Toggle</button></label>
<hr>
<label class="btnProxy"><input type="radio" name='gender' value='alien'/><button>Select</button></label>
<br>
<label class="btnProxy"><input type="radio" name='gender' value='female'/><button>Select</button></label>
<br>
<label class="btnProxy"><input type="radio" name='gender' value='male'/><button>Select</button></label>
</body>
</html>