这是一个老问题,但是……我会试一试。工作 jsfiddle:http://jsfiddle.net/a0nnrfua/
我认为很大程度上取决于您打算如何定义“最接近”,但假设 jQuery 解决方案并希望您的浏览器要求不是太远,您可以使用 data- 属性和 jQuery 来提出有一些比较简单的功能。甚至真正使用复选框的值部分。
伪代码,它看起来像:
- 定义单击或更改处理程序以检测复选框何时被触摸/更改。
- 定义一个函数,该函数将扫描所有选中的项目并将值传递到“最近的包”函数中。
- 根据该函数的结果,过滤您的包选择,以便以某种方式突出显示或标记您的选择。
所以让我们假设以下 HTML 标记:
<h3>TV Channels</h3>
<div id="TVChannelSelections">
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_Discovery" value="Discovery" />
<label for="tvchannel_Discovery">Discovery Channel</label>
<br/>
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_AnimalPlanet" value="Animal Planet" />
<label for="tvchannel_AnimalPlanet">Animal Planet</label>
<br/>
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_DisneyChannel" value="Disney Channel" />
<label for="tvchannel_Disney">Disney Channel</label>
<br/>
</div>
<div id="message"></div>
<h3>Packages</h3>
<div id="FilteredPackages">
<div class="package deselected" id="Package1" data-channels="Discovery,Disney Channel">Package #1</div>
<div class="package deselected" id="Package2" data-channels="Animal Planet,Disney Channel">Package #2</div>
<div class="package deselected" id="Package3" data-channels="Animal Planet">Package #3</div>
</div>
因此,在 jQuery 中,您的通用更改或单击处理程序将在代码中定义:请注意,我是说,您页面上定义了“tvchannel”类的任何元素,如果发生更改,请运行我的过滤功能。
<script type="text/javascript" src="../path/to/jQuery/library"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".tvchannel").on("change", function() {
FilterMySelectedChannels();
});
});
</script>
现在我们可以定义您的过滤器功能。我们将假设两件事。 #1,我们想要找到所有选中的复选框及其值。然后我们将遍历所有包的 data-channels 属性(定义为具有 class= "package" 的元素)。我们将使用某种形式的字符串比较和布尔逻辑来定义完全匹配与关闭但没有雪茄匹配与完全失败。
为了跟踪我正在使用的 3 个类,选中、取消选中和关闭。
在 css 中,您可以决定是否要 notselected 表示“完全隐藏包”(即显示:无;)或者您希望它可见但变灰并“突出显示”(即文本装饰:删除线;颜色:灰色;}
我将使用一种蛮力的方式进行比较。 javascript 中有更好的数组函数和比较函数,但这对于大多数人来说应该是相对清楚的,我相信 stackoverflow 的好人会提出更好的解决方案。但这应该让你开始。 :)
<script type="text/javascript">
function FilterMySelectedChannels() {
$checkedboxes = $(".tvchannel:checked");
$packages = $(".package");
var bAnyFound = false;
$packages.each(function () {
var bCloseButNoCigar = false;
var bCompleteMatch = true;
var packagearray = $(this).data("channels").split(",");
var $currentPackage = $(this);
$checkedboxes.each(function () {
if ($.inArray($(this).val(), packagearray) != -1) {
bCloseButNoCigar = true;
} else {
bCompleteMatch = false;
}
});
if (bCompleteMatch) {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("selected");
bAnyFound = true;
} else if (bCloseButNoCigar) {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("close");
} else {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("deselected");
}
});
if (bAnyFound) {
$("#message").html("The following matches were found");
} else {
$("#message").html("No actual matches were found, but here are some close matches based on your selections");
$(".package.close").removeClass("deselected").removeClass("close").removeClass("selected").addClass("selected");
}
}
</script>
<style type="text/css">
.selected {
color: red;
background-color: yellow !important;
}
.deselected {
color: grey;
text-decoration: strike-through !important;
background-color: white !important;
}
</style>
这里有一些明显的优化可能会起作用,但对于那些尝试做类似事情的人来说,这是一个开始。请注意,它假定您的标记是动态生成或正确编码的。如果您需要防止人为拼写错误,使用 .toLowerCase/UpperCase 转换您的文本并使用 .Trim 函数来消除多余的空间会有所帮助。但是您仍然必须明智地选择数据值,以免重叠。如果你选择得足够好,你可以使用更好的技术,比如正则表达式和通配符搜索来使代码更短。
希望这对某人有所帮助!