下午好,
我有以下代码:
$(document).ready(function() {
var mod = $('#modality').val();
if (mod == "On Site") {
$('#l_clinic').attr("hidden", false);
$('#clinic').attr("hidden", false);
$('#l_phone').attr("hidden", true);
$('#phone').attr("hidden", true);
$('#l_link').attr("hidden", true);
$('#link').attr("hidden", true);
}
if (mod == "Telephonic") {
$('#l_clinic').attr("hidden", true);
$('#clinic').attr("hidden", true);
$('#l_phone').attr("hidden", false);
$('#phone').attr("hidden", false);
$('#l_link').attr("hidden", true);
$('#link').attr("hidden", true);
}
if (mod == "Videochat") {
$('#l_clinic').attr("hidden", true);
$('#clinic').attr("hidden", true);
$('#l_phone').attr("hidden", true);
$('#phone').attr("hidden", true);
$('#l_link').attr("hidden", false);
$('#link').attr("hidden", false);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label style="font-weight: bold;">Modality:</label>
<input type="text" name="" id="modality" class="form-control">
<label id="l_clinic" style="font-weight: bold;">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control">
<label id="l_phone" style="font-weight: bold;">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control">
<label id="l_link" style="font-weight: bold;">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control">
我需要根据模态输入的值隐藏和显示一些标签和输入,但是它不起作用
请帮助! !
如前所述,您的代码在文档就绪时检索#modality
<input>
的值,因为<input>
没有默认值,并且用户还没有-尚未-有机会在<input>
中输入值,该值不匹配列出的任何匹配。
因为你的代码中没有else
子句,所以什么都不会发生。
<input>
元素之后发生,则应该将该功能包含在事件处理程序中,如下所示:
$(document).ready(function() {
// we use the on() method to bind the anonymous (arrow) function
// as the event-handler for the 'input' event, which handles
// paste, keyup, keydown...
$('#modality').on('input', () => {
var mod = $('#modality').val();
if (mod == "On Site") {
$('#l_clinic').attr("hidden", false);
$('#clinic').attr("hidden", false);
$('#l_phone').attr("hidden", true);
$('#phone').attr("hidden", true);
$('#l_link').attr("hidden", true);
$('#link').attr("hidden", true);
// using else-if in order to group the
// various conditions together (rather than
// having multiple independent 'if'
// statements that (theoretically) may
// all be executed:
} else if (mod == "Telephonic") {
$('#l_clinic').attr("hidden", true);
$('#clinic').attr("hidden", true);
$('#l_phone').attr("hidden", false);
$('#phone').attr("hidden", false);
$('#l_link').attr("hidden", true);
$('#link').attr("hidden", true);
} else if (mod == "Videochat") {
$('#l_clinic').attr("hidden", true);
$('#clinic').attr("hidden", true);
$('#l_phone').attr("hidden", true);
$('#phone').attr("hidden", true);
$('#l_link').attr("hidden", false);
$('#link').attr("hidden", false);
}
});
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
/* to style all <label> elements, rather than using
the in-line style attribute: */
label {
font-weight: bold;
}
/* forcing each <label> element to a new line: */
label::before {
content: '';
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- added the "for" attribute, filling the attribute-value equal to the
id of the input-element to which the label relates: -->
<label for="modality">Modality:</label>
<input type="text" name="" id="modality" class="form-control">
<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control">
<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control">
<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control">
JS Fiddle demo.
当然,值得注意的是,如果有人从#modality
输入中清除文本,这不会重置其他元素的可见性(尽管如果用户随后输入与另一个元素的id
匹配的值,该元素将被显示)。
考虑到这一点,当<input>
被清空时,允许元素的可见性重置为所有可见性可能是一个好处:
$(document).ready(function() {
$('#modality').on('input', () => {
var mod = $('#modality').val();
if (mod == "On Site") {
$('#l_clinic').attr("hidden", false);
$('#clinic').attr("hidden", false);
$('#l_phone').attr("hidden", true);
$('#phone').attr("hidden", true);
$('#l_link').attr("hidden", true);
$('#link').attr("hidden", true);
} else if (mod == "Telephonic") {
$('#l_clinic').attr("hidden", true);
$('#clinic').attr("hidden", true);
$('#l_phone').attr("hidden", false);
$('#phone').attr("hidden", false);
$('#l_link').attr("hidden", true);
$('#link').attr("hidden", true);
} else if (mod == "Videochat") {
$('#l_clinic').attr("hidden", true);
$('#clinic').attr("hidden", true);
$('#l_phone').attr("hidden", true);
$('#phone').attr("hidden", true);
$('#l_link').attr("hidden", false);
$('#link').attr("hidden", false);
// here we add a further else-if clause,
// which matches an empty-string:
} else if (mod == "") {
$('#l_clinic').attr("hidden", false);
$('#clinic').attr("hidden", false);
$('#l_phone').attr("hidden", false);
$('#phone').attr("hidden", false);
$('#l_link').attr("hidden", false);
$('#link').attr("hidden", false);
}
});
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
label {
font-weight: bold;
}
label::before {
content: '';
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="modality">Modality:</label>
<input type="text" name="" id="modality" class="form-control">
<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control">
<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control">
<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control">
JS Fiddle demo.
但是在发布的代码中有很多重复的地方,以及"dry"的格言。("Don't Repeat Yourself")代码是我们不应该这样做的,因为它有助于减少错误的可能性。因此,我们可以使用一个简单的switch/evaluate来访问所有元素并更新它们:
$(document).ready(function() {
$('#modality').on('input', () => {
const mod = $('#modality').val(),
// here we select the relevant <input> elements via
// their id:
group = $('#clinic, #phone, #link');
// we iterate over the <input> elements using the prop() method
// (most, if not all, jQuery methods interally iterate over the
// collection they're working on) to update the 'hidden' property;
// the arguments passed to the function are:
// _i: the index of the current element in the collection, and
// current: the current property-value of the property we're
// updating:
group.prop('hidden', function(_i, current) {
// here we retrieve the attribute-value of the custom
// data-mode attribute, and use the
// String.prototype.startsWith() method to obtain a Boolean
// result indicating whether the data-mode attribute-value of
// the current element starts with the String stored in the
// 'mod' variable; we then use the NOT operator to invert that
// result because passing a Boolean true to the 'hidden' property
// will hide the element, whereas we want to show the element
// whose data-mode attribute-value begins with the entered string:
const evaluation = !$(this).data('mode').startsWith(mod);
// here we retrieve the <label> elements associated with (their
// for attribute, or htmlFor property) the relevant <input> and
// we update them in a similar way to the <input> elements (though
// we pass a single argument rather than using a callback function):
$(this.labels).prop('hidden', evaluation);
// and here we return the evaluation true (to hide an element) or
// false (to show an element):
return evaluation;
});
});
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
label {
font-weight: bold;
}
label::before {
content: '';
display: block;
}
<label for="modality">Modality:</label>
<input type="text" name="" id="modality" class="form-control">
<label id="l_clinic" for="clinic">Clinic:</label>
<!-- I've added a custom data-* attribute - here 'data-mode' - to define
the string that the user should type to show this specific <input>,
this is absolutely configurable to your own needs/preferences: -->
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">
<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">
<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">
JS Fiddle demo.
值得注意的是,任何要求用户键入特定字符串& &;ndash(即使大小写匹配不严格)的解决方案都意味着任何给定的用户可能会感到沮丧;因此,我建议通过使用<select>
或<input>
来改进UI。
<select>
:
$(document).ready(function() {
$('#modality').on('change', () => {
const mod = $('#modality').val(),
group = $('#clinic, #phone, #link');
group.prop('hidden', function(_i, current) {
const evaluation = !$(this).data('mode').startsWith(mod);
$(this.labels).prop('hidden', evaluation);
return evaluation;
});
});
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
label {
font-weight: bold;
}
label::before {
content: '';
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="modality">Modality:</label>
<select id="modality">
<!-- we set the disabled property to prevent the user from
re-selecting the 'please select' option, and we set
the 'selected' property in order to ensure that this
option is visible on page-load: -->
<option value="-1" disabled selected>Please select:</option>
<option value="clinic">Clinic</option>
<option value="phone">Telephone</option>
<option value="link">Videochat</option>
</select>
<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">
<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">
<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">
最后,使用<input>
元素:
$(document).ready(function() {
// here we select all <input> elements with a type equal to "radio" and
// a name equal to "modality", and we then use the on() method with the
// anonymous function (not an arrow function, as we need use 'this' within
// the function body) as the handler for the 'change' event, since the
// radio <input> takes only that one type of input-related event:
$('input[type="radio"][name="modality"]').on('change', function() {
const mod = $(this).val(),
group = $('#clinic, #phone, #link');
group.prop('hidden', function(_i, current) {
const evaluation = !$(this).data('mode').startsWith(mod);
$(this.labels).prop('hidden', evaluation);
return evaluation;
});
});
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
legend,
label {
font-weight: bold;
}
label::before {
content: '';
display: block;
}
/* selecting those <label> elements inside of a
<fieldset> element, and using the 'initial'
property-value for the 'display' property to
revert them to their native/unstyled form: */
fieldset label::before {
display: initial;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset>
<legend>Modality:</legend>
<label>
<span>Clinic</span>
<input type="radio" name="modality" value="clinic">
</label>
<label>
<span>Telephone</span>
<input type="radio" name="modality" value="phone">
</label>
<label>
<span>Videochat</span>
<input type="radio" name="modality" value="link">
</label>
</fieldset>
<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">
<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">
<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">
值得注意的是,这一切都是完全可能的,没有jQuery,在原生JavaScript:
// we trigger the JavaScript to run once the window receives the DOMContentLoaded event,
// implying that the elements exist on the page (but not necessarily that all <img> elements
// have finished loading); we use an anonymous Arrow function to wrap the JavaScript:
window.addEventListener('DOMContentLoaded', () => {
// here we use document.querySelectorAll() to find all elements that are
// <input> elements, with a type of "radio" and a name-attribute equal to
// "modality":
document.querySelectorAll('input[type=radio][name=modality]')
// we use NodeList.prototype.forEach() to iterate over those elements:
.forEach(
// and use an Arrow function to bind an anonymous event-handling (arrow)
// function to handle the 'change' event:
(el) => {
el.addEventListener('change', (e) => {
// we retrieve the changed <input> via the EventObject's
// 'target' property, which retrieves the element that
// fired the event to which we're currently reacting:
const changed = e.target,
// we retrieve the value from that <input> element:
value = changed.value,
// and we then select the <input> elements upon which
// we wish to act, using a simple CSS selector which
// selects all <input> elements which do not have
// a name attribute equal to "modality":
group = document.querySelectorAll('input:not([name="modality"])');
// we again use NodeList.prototype.forEach() to iterate over the
// group of elements, using an Arrow function:
group.forEach(
// the first argument of the arrow function is a reference to
// the current Node of the NodeList over which we're iterating:
(input) => {
// here we do as before, retrieve the value, assess whether
// the current element's data-mode attribute is exactly equal
// to the value we retrieved earlier, and then invert that
// Boolean:
const evaluation = !(input.dataset.mode === value);
// We again use NodeList.prototype.forEach() to iterate
// over the NodeList of <label> elements held in the
// <input> element's 'labels' property, and update their
// hidden property to match the earlier evaluation:
input.labels.forEach(
(label) => label.hidden = evaluation
)
// and then, finally, we update the hidden property of
// the current <input>:
input.hidden = evaluation;
});
});
});
});
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.4;
margin: 0;
padding: 0;
}
legend,
label {
font-weight: bold;
}
label::before {
content: '';
display: block;
}
fieldset label::before {
display: initial;
}
<fieldset>
<legend>Modality:</legend>
<label>
<span>Clinic</span>
<input type="radio" name="modality" value="clinic">
</label>
<label>
<span>Telephone</span>
<input type="radio" name="modality" value="phone">
</label>
<label>
<span>Videochat</span>
<input type="radio" name="modality" value="link">
</label>
</fieldset>
<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">
<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">
<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">
JS Fiddle demo.