如何检查值、空值和!条件语句中的值



我有一个包含国家列表的select字段。我想展示一些只供美国选择的东西,还有一些其他的!美国选择。但我也希望它在什么都不选的情况下做其他事情。问题是,在非美国的选择中,没有什么是包容性的。

提前谢谢。这是代码:

var selectedCountry, selectAutograph
$('.country, .autograph').on('change', function() {
selectedCountry = $('.country').find('option:selected').val();
selectAutograph = $('.autograph').is(":checked")
if (selectedCountry === "United States" && !selectAutograph) {
console.log("Show US Only");
$(".us").show();
$(".int, .intauto, .usauto").hide();
} else if (selectedCountry !== "United States" && !selectAutograph) {
console.log("Show Int Only");
$(".int").show();
$(".us, .intauto, .usauto").hide();
} else if (selectedCountry === "United States" && selectAutograph) {
console.log("Show US and Autograph");
$(".usauto").show();
$(".intauto, .us, .int").hide();
} else if (selectedCountry !== "United States" && selectAutograph) {
console.log("Show Int and Autograph");
$(".intauto").show();
$(".usauto, .us, .int").hide();
} else {
console.log("Show Nothing");
$(".intauto, .usauto, .us, .int").hide();
}
});
.hide {
display: none;
}
<form id="order-form" method="post" role="form">
<select class="country" name="country" id="country">
<option value="Select Country">Select Country</option>
<option value="United States">United States</option>
<option value="Canada">Canada</option>
<option value="United Kingdom">United Kingdom</option>
<!-- ... -->
<option value="Zimbabwe">Zimbabwe</option>
</select>
<div class="form-check">
<input class="autograph" type="checkbox" value="" id="autograph" name="autograph">
<label class="form-check-label"> Add autograph </label>
</div>
</form>
<div>
<div class="us hide">
US shipping
</div>
<div class="int hide">
International shipping
</div>
<div class="usauto hide">
US shipping + add autograph
</div>
<div class="intauto hide">
International shipping + add autograph
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

这里还有一个JSFiddle

else永远不会运行,因为Select Country国家选项将在selectedCountry !== "United States" && !selectAutographselectedCountry !== "United States" && selectAutograph条件下运行。此外,您还可以通过添加dataatttibutes来简化代码。

请检查一下。

var selectedCountry, selectAutograph
var country = {
"Select Country": "non",
"United States": "us",
}

$('.country, .autograph').on('change', function() {   
selectedCountry = $('.country').find('option:selected').val();     
selectAutograph = $('.autograph').is(":checked")
$('[data-autograpgh], [data-country="non-us"], [data-country="us"]').hide()
if(country[selectedCountry] === "us" && !selectAutograph) {
$('[data-country="us"]:not([data-autograpgh])').show()
} else if(!country[selectedCountry] && !selectAutograph)   {
$('[data-country="non-us"]:not([data-autograpgh])').show()
} else if(country[selectedCountry] === "us" && selectAutograph)   {
$('[data-country="us"][data-autograpgh]').show()
} else if(!country[selectedCountry] && selectAutograph)   {
$('[data-country="non-us"][data-autograpgh]').show()
}

});
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form  id="order-form" method="post" role="form">
<select  class="country"  name="country"  id="country" required="">
<option value="Select Country">Select Country</option>
<option value="United States">United States</option>
<option value="Canada">Canada</option>
<option value="United Kingdom">United Kingdom</option>
<option value="Zimbabwe">Zimbabwe</option>
</select>
<div class="form-check">
<input class="autograph" type="checkbox" value="" id="autograph" name="autograph">
<label class="form-check-label"> Add autograph </label>
</div>
</form>
<div>
<div class="us hide" data-country="us">
US shipping                   
</div>
<div class="int hide" data-country="non-us">
International shipping                                    
</div> 
<div class="usauto hide" data-country="us" data-autograpgh>
US shipping + add autograph
</div>  
<div class="intauto hide" data-country="non-us" data-autograpgh>
International shipping + add autograph
</div>
</div>

虽然您已经接受了答案,但我想提供一种替代方法:

// creating an Object in which we can access properties
// of individual countries; the key of each object is
// the value from the <select> element:
const countries = {
us: {
country: 'United States',
international: false,
},
canada: {
country: 'Canada',
international: true,
},
uk: {
country: 'United Kingdom',
international: true,
},
zimbabwe: {
country: 'Zimbabwe',
international: true,
}
};
// caching the elements:
let countrySelect = $('.country'),
autograph = $('.autograph');
// binding the anonymous function of the on() method as the event-handler
// for the 'change' event:
$('.country, .autograph').on('change', function() {
// hiding the children of the '.details' element:
$('.details > *').hide();
// retrieving the selected <option> element:
let selectedOption = countrySelect.find(':selected');
// HTMLOptionElement.defaultSelected is a Boolean property which is
// true if the <option> had the selected attribute on page-load, or
// false if the <option> did not have the 'selected' attribute on
// page-load:
if (selectedOption.prop('defaultSelected')) {
// all elements are now hidden by default in the function,
// so no action taken except for logging a statement to the
// console:
console.log("No country selected.");
} else {
// here we retrieve the value of the selected <option>:
let value = selectedOption.val(),
// using destructuring to declare the variables that
// are also property-names from the countries[value]
// property-value:
{
country,
international
} = countries[value],
// determining whether the checkbox is checked, the
// .is() method returns a Boolean reflecting that
// the collection matches the supplied selector:
withAutograph = autograph.is(':checked'),
// here we create the CSS selector, using a template-literal String;
// the first conditional operator tests whether the 'international'
// variable is true; if yes this returns the string 'int', otherwise
// returning the string 'us'
// the second conditional tests to see if 'withAutograph' is true,
// if so returning the string 'auto', othewise an empty string:
selector = `.${international ? 'int' : 'us'}${withAutograph ? 'auto' : ''}`;
// we then use that selector, and call the show() method:
$(selector).show();
}
});
.hide {
display: none;
}
<form id="order-form" method="post" role="form" action="#">
<select class="country" name="country" id="country">
<option value="Select Country" selected>Select Country</option>
<!--
Here I've changed the value to a lower-case single string, in
order to reduce the chance of a mis-typed white-space character
causing trouble elsewhere, and use an abbreviation where
possible/obvious to do so:
-->
<option value="us">United States</option>
<option value="canada">Canada</option>
<option value="uk">United Kingdom</option>
<option value="zimbabwe">Zimbabwe</option>
</select>
<div class="form-check">
<input class="autograph" type="checkbox" value="" id="autograph" name="autograph">
<label class="form-check-label"> Add autograph </label>
</div>
</form>
<!--
This element was given a class-name ('details') in order to easily hide
the contents without having to refer to them individually:
-->
<div class="details">
<div class="us hide">
US shipping
</div>
<div class="int hide">
International shipping
</div>
<div class="usauto hide">
US shipping + add autograph
</div>
<div class="intauto hide">
International shipping + add autograph
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

JS Fiddle演示。

当然,这在使用纯JavaScript时是完全可能的:

// caching a reference to the document, along with some utility
// helper functions to simplify life (and reduce typing):
const D = document,
// here we define an alias for querySelector(), which will use
// either document.querySelector() or element.querySelector()
// depending on whether a context is passed to the function;
// if no context is passed document.querySelector() will be
// used, otherwise with a context that Element will be used:
get = (sel, context = D) => context.querySelector(sel),
// as above, but here we call querySelectorAll() and return
// the retrieved NodeList as an Array of Nodes in order to
// utilise Array methods:
getAll = (sel, context = D) => [...context.querySelectorAll(sel)],
// creating an Object in which we can access properties
// of individual countries; the key of each object is
// the value from the <select> element:
countries = {
us: {
country: 'United States',
international: false,
},
canada: {
country: 'Canada',
international: true,
},
uk: {
country: 'United Kingdom',
international: true,
},
zimbabwe: {
country: 'Zimbabwe',
international: true,
}
};
// caching the elements:
let countrySelect = get('.country'),
autograph = get('.autograph'),
// the change-handling function:
changeHandler = (evt) => {
// hiding the children of the '.details' element:
getAll('.details > *').forEach(
(el) => el.classList.add('hide')
);
// retrieving the selected <option> element, with CSS
// the selected <option> matches the :checked pseudo-
// class, and we're looking within the context of the
// countrySelect <select> element:
let selectedOption = get(':checked', countrySelect);
// HTMLOptionElement.defaultSelected is a Boolean property which is
// true if the <option> had the selected attribute on page-load, or
// false if the <option> did not have the 'selected' attribute on
// page-load:
if (selectedOption.defaultSelected) {
// all elements are now hidden by default in the function,
// so no action taken except for logging a statement to the
// console:
console.log("No country selected.");
} else {
// here we retrieve the value of the selected <option>:
let value = selectedOption.value,
// using destructuring to declare the variables that
// are also property-names from the countries[value]
// property-value:
{
country,
international
} = countries[value],
// determining whether the checkbox is checked, the
// property itself returns a Boolean indicating whether
// the node is checked (true) or unchecked (false):
withAutograph = autograph.checked,
// here we create the CSS selector, using a template-literal String;
// the first conditional operator tests whether the 'international'
// variable is true; if yes this returns the string 'int', otherwise
// returning the string 'us'
// the second conditional tests to see if 'withAutograph' is true,
// if so returning the string 'auto', othewise an empty string:
selector = `.${international ? 'int' : 'us'}${withAutograph ? 'auto' : ''}`;
// here we retreive all elements matching the selector, and then use
// Array.prototype.forEach() to iterate over that Array of Nodes with
// an Arrow function:
getAll(selector).forEach(
// here we pass in a reference to the current Node of the Array,
// and we remove the 'hide' class-name from the Element's classList:
(el) => el.classList.remove('hide')
);
}
};
// using Array.prototype.forEach() to iterate over the Array-literal which
// contains both interactive elements with which the user interacts:
[countrySelect, autograph].forEach(
// binding the changeHandler function as the event-handler for the 'change' event:
(el) => el.addEventListener('change', changeHandler)
);
.hide {
display: none;
}
<form id="order-form" method="post" role="form" action="#">
<select class="country" name="country" id="country">
<option value="Select Country" selected>Select Country</option>
<!--
Here I've changed the value to a lower-case single string, in
order to reduce the chance of a mis-typed white-space character
causing trouble elsewhere, and use an abbreviation where
possible/obvious to do so:
-->
<option value="us">United States</option>
<option value="canada">Canada</option>
<option value="uk">United Kingdom</option>
<option value="zimbabwe">Zimbabwe</option>
</select>
<div class="form-check">
<input class="autograph" type="checkbox" value="" id="autograph" name="autograph">
<label class="form-check-label"> Add autograph </label>
</div>
</form>
<!--
This element was given a class-name ('details') in order to easily hide
the contents without having to refer to them individually:
-->
<div class="details">
<div class="us hide">
US shipping
</div>
<div class="int hide">
International shipping
</div>
<div class="usauto hide">
US shipping + add autograph
</div>
<div class="intauto hide">
International shipping + add autograph
</div>
</div>

参考文献:

  • JavaScript:
    • Array.prototype.forEach()
    • 箭头功能
    • 条件运算符
    • HTMLOptionElement
    • 模板文字
  • jQuery:
    • find()
    • hide()
    • CCD_ 10
    • CCD_ 11
    • prop()
    • show()

最新更新