上次更新时间:下午4:15
我有三个类别供人们选择:性别,年龄,种族。每个都有自己的选项男/女; 35岁以下,36-64岁,65岁以上;白色,黑色,原住民,梅蒂斯人和亚洲人。
单击其中一个选项时,该数字应从var total
中减去(这是MLA的数量)。我为这些数字设置了全局变量,这会更改位于我的span.number
文件中的index.html
来说明,"有多个适合您人口统计数据的x-MLAs。&& #34;
a)我正在寻找一种更有效的Javascript数学计算方法,现在它非常笨拙。如果您查看scripts.js
中的“性别”选项,我已创建变量var resultMale = total - female
但是
当生成span.number
依赖于先前选择的选项的结果时,它会变得不那么漂亮。
b)我尝试过使用管道布尔值,但我不清楚第二类"年龄"如何包括var resultLow = resultMale || resultFemale -(middle + high)
它将如何知道什么已被点击/选择类别"性别"这样它就可以做正确的数学运算。
$(function() {
// Numbers
var total = 56
var male = 41;
var female = 15;
var low = {}
var middle = {}
var high = {}
var white = 41
var black = 0;
var aboriginal = null;
var metis = null;
var asian = null;
// MLAs
var MLAs = [
{
"Name": "Nancy Allan",
"Age": 62,
"Constuency": "St. Vital",
"Party": "NDP",
"Gender": "Female",
"Ethnicity": "White"
},
{
"Name": "James Allum",
"Age": null,
"Constuency": "Fort Garry-Riverview",
"Party": "NDP",
"Gender": "Male",
"Ethnicity": "White"
},
{
"Name": "Rob Altemeyer",
"Age": null,
"Constuency": "Wolseley",
"Party": "NDP",
"Gender": "Male",
"Ethnicity": "White"
}]
// Option #1: Gender
$( ".G1" ).click(function() {
$(".G2").toggleClass("disabled");
$(".headshot").not(".Female").toggleClass("opacity");
var resultMale = total - female;
$(".number").html(resultMale);
});
$( ".G2" ).click(function() {
$(".G1").toggleClass("disabled");
$(".headshot").not(".Male").toggleClass("opacity");
var resultFemale = total - male
$(".number").html(resultFemale);
});
// Option #2: Age
$( ".A1" ).click(function() {
$(".A2").toggleClass("disabled");
$(".A3").toggleClass("disabled");
$(".Low").toggleClass("show");
var resultLow = resultMale || resultFemale - (middle + high);
$(".number").html("?");
});
$( ".A2" ).click(function() {
$(".A1").toggleClass("disabled");
$(".A3").toggleClass("disabled");
$(".Medium").toggleClass("show");
var resultMiddle = resultMale || resultFemale - (low + high);
$(".number").html("?");
});
$( ".A3" ).click(function() {
$(".A1").toggleClass("disabled");
$(".A2").toggleClass("disabled");
$(".High").toggleClass("show");
var resultHigh = resultMale || resultFemale - (low + middle);
$(".number").html("?");
});
// OLD
$( ".E1" ).click(function() {
$( ".White" ).toggleClass("show");
var resultWhite = resultLow || resultMiddle || resultHigh - (black + aboriginal + metis + asian);
$(".number").html(resultWhite);
});
$( ".E2" ).click(function() {
$( ".Black" ).toggleClass("show");
var resultBlack = resultLow || resultMiddle || resultHigh - (white + aboriginal + metis + asian);
$(".number").html("0");
});
$( ".E3" ).click(function() {
$( ".Aboriginal" ).toggleClass("show");
var resultAboriginal = resultLow || resultMiddle || resultHigh - (white + black + metis + asian);
$(".number").html(null);
});
$( ".E4" ).click(function() {
$( ".Metis" ).toggleClass("show");
var resultMetis = resultLow || resultMiddle || resultHigh - (white + black + aboriginal + asian);
$(".number").html(null);
});
$( ".E5" ).click(function() {
$( ".Asian" ).toggleClass("show");
var resultAsian = resultLow || resultMiddle || resultHigh - (white + black + aboriginal + metis);
$(".number").html(null);
});
// Option #3: Ethnicity
// $("input[name='ethnicity']").on("change", function() {
// var $checkedbox = $("input[name='ethnicity']:checked");
// if($checkedbox.length >= 2)
// {
// var $uncheckedbox = $("input[name='ethnicity']:not(:checked)");
// $.each($uncheckedbox,function() {
// $(this).attr("disabled", "disabled");
// });
// }
// else
// {
// $("input[name='ethnicity']").removeAttr("disabled");
// }
// });
// Shows a popup with MLA information
$(".headshot").click(function(){
var idx = $(this).index() - 1;
$(".tooltip").fadeIn("slow");
$(".tooltipName").html(MLAs[idx].Name);
$(".tooltipParty").html(MLAs[idx].Party);
$(".tooltipConstuency").html(MLAs[idx].Constuency);
$(".tooltipEthnicity").html(MLAs[idx].Ethnicity) + ",";
$(".tooltipAge").html(MLAs[idx].Age);
});
// Bounce and show result
$(".rect").click(function(){
console.log("Bounce test");
$(".others").fadeIn("slow");
$(".others").effect( "bounce",
{times:3}, 600 );
});
// This hides the footer on click
$(".crossContainer").click(function(){
$("footer").slideUp("slow", function(){
console.log("No feedback makes us sad.");
});
});
// This hides the credits
$(".credits").hide();
});
<!-- Three options readers can click -->
<section class="interactive clearfix">
<section class="selection" id="selection">
<div class="gender">
<p class="category">Gender</p>
<div class="options">
<p class="rect G1">Male</p>
<p class="rect G2">Female</p>
</div><!-- /.options -->
</div><!-- /.gender -->
<div class="age">
<p class="category">Age</p>
<div class="options">
<p class="rect A1">Under 35</p>
<p class="rect A2">36-64</p>
<p class="rect A3">65+</p>
</div><!-- /.options -->
</div><!-- /.age -->
<div class="ethnicity">
<p class="category">Ethnicity<span>*<span></p>
<div class="options">
<p class="rect E1 E">White</p>
<p class="rect E2 E">Black</p>
<p class="rect E3 E">Aboriginal</p>
<p class="rect E4 E">Metis</p>
<p class="rect E5 E">Asian</p>
</div><!-- /.options -->
</div><!-- /.ethnicity -->
</section>
<section class="others">
<h2>There are <span class="number">56</span> MLAs that fit in your demographic</h2>
<figcaption class="special">(Does not include the single vacant seat for the Pas.)</figcaption>
</section>
答案 0 :(得分:1)
如果我理解正确,下面的演示应该做你想要的。您可以在jsFiddle找到下面和此处的代码。 (旧版本的jsfiddle,新版本见下面的编辑。)
它基本上是在做什么和我建议的。对于“计算”,我使用UnderscoreJS使用where
方法查找当前点击的选择的匹配键/值对。然后很容易得到长度选择的总和。
在演示中,我为男性,女性和少数民族做过。它应该与其他选项完全相同。
编辑07.02.2015
我改进了代码。现在,您可以在列表中激活多个过滤器。此外,删除减法因为过滤后的列表始终包含具有length属性的项目数。
代码正在运行,但仍有一些要改进的地方:
removeFilter
以轻松删除过滤器而不指定过滤器参数setFilter
改进:if ( index == -1 ) {
并非真正需要,因为在添加新过滤器之前始终会删除过滤器。我可能还没有测试过滤器的任何组合是否正常工作,因为我只有三个列表项。所以你必须用代码做更多的测试。
我在这里将代码更新为最新版本,这里是jsFiddle。
更多代码说明16.02.2015
函数refreshList
和setTotal
用于更新DOM。
过滤器函数gender
,ethnicity
和age
在应用过滤器后返回新数组。
数组activeFilters
正在存储当前选定的过滤器。它存储过滤器函数,以便通过遍历此数组来调用它们。稍后会详细介绍。
setFilter
方法正在设置过滤器。它将过滤器添加到activeFilters
数组,然后应用过滤器。
applyFilter
函数可能是最难理解的。它遍历activeFilters
数组的每个项目。如果您有两个有效过滤器(此处为性别和种族),则数组activeFilters将如下所示:
activeFilters = [{
method: function(array, gender){...},
param: 'male'
}, {
method: function (array, ethnic){...},
param: 'white'
}];
使用activeFilters[0].method(MLAs,'male')
,您可以手动调用性别过滤器。这就是$ .each循环在循环this
内所做的是{method: ..., param: ...}
。因此,对于this.method(filtered, this.param)
,过滤器将应用于变量filtered
。
循环之后,每个活动过滤器都将应用于数组。
var $total = $('#total');
var $MLA_List = $('#MLA_List');
// MLAs
var MLAs = [{
"Name": "Nancy Allan",
"Age": 62,
"Constuency": "St. Vital",
"Party": "NDP",
"Gender": "Female",
"Ethnicity": "White"
}, {
"Name": "James Allum",
"Age": 34,
"Constuency": "Fort Garry-Riverview",
"Party": "NDP",
"Gender": "Male",
"Ethnicity": "Black"
}, {
"Name": "Rob Altemeyer",
"Age": 36,
"Constuency": "Wolseley",
"Party": "NDP",
"Gender": "Male",
"Ethnicity": "White"
}];
var filteredMLAs = MLAs.slice(0); // copy MLAs
var total = filteredMLAs.length;
var refreshList = function () {
var list = filteredMLAs;
setTotal(list.length);
$MLA_List.empty();
$.each(list, function (index, value) {
$MLA_List.append($('<li/>').text(list[index].Name));
});
};
var setTotal = function (value) {
$total.text(value);
};
// filter methods
var gender = function (array, gender) {
//console.log('gender filter called!', gender);
return _.where(array, {
"Gender": gender
});
};
var ethnicity = function (array, ethnic) {
//console.log('ethnic filter called!', array, ethnic);
return _.where(array, {
"Ethnicity": ethnic
});
};
var age = function(array, ageRange) {
//under 35, 36-64, 65+
return _.filter(array, function(MLA) {
//console.log(MLA.Age);
switch(ageRange) {
case 35:
return ( MLA.Age <= 35 );
case 36:
return ( MLA.Age >= 35 && MLA.Age <= 64);
case 65:
return ( MLA.Age >= 65 );
};
return false;
});
};
var activeFilters = [];
var setFilter = function (method, param) {
var newFilter = {
method: method,
param: param
};
var matchedFilter = _.find(activeFilters, newFilter),
index = activeFilters.indexOf(matchedFilter);
if ( index == -1 ) {
activeFilters.push(newFilter);
}
applyFilter();
};
var removeFilter = function(method, param) {
var filter = {
method: method,
param: param
};
var index = activeFilters.indexOf(_.find(activeFilters, filter));
if (index > -1) {
activeFilters.splice(index, 1);
}
applyFilter(); // re-apply filter to update list
};
var applyFilter = function () {
var filtered = MLAs.slice(0);
$.each(activeFilters, function () {
filtered = this.method(filtered, this.param);
});
filteredMLAs = filtered ? filtered: [];
refreshList();
};
$('#Male, #Female').click(function () {
//console.log(this.id);
removeFilter(gender, this.id=='Male'? 'Female': 'Male'); // remove not active filter
setFilter(gender, this.id);
});
$('#White, #Black').click(function () {
//console.log(this.checked);
if ( this.checked )
setFilter(ethnicity, this.id); //'White');
else
removeFilter(ethnicity, this.id); //'White');
});
$('.Age').click(function() {
removeFilter(age, 35); // improvement of remove filter required, e.g. remove all age filters
removeFilter(age, 36);
removeFilter(age, 65);
setFilter(age, parseInt(this.value));
});
$('#reset').click(function(){
//console.log('reset form');
activeFilters = [];
$(':checkbox, :radio').attr('checked', false);
applyFilter();
});
$(function () {
refreshList();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
There are <span id="total"></span> MLAs matching.
<ul id="MLA_List"></ul>
<hr/>
<p>click to filter:</p>
<input type="radio" id="Male" name="gender">male</input>
<input type="radio" id="Female" name="gender">female</input>
<input type="checkbox" id="White">white</input>
<input type="checkbox" id="Black">black</input>
<input type="radio" class="Age" name="age" value="35">under 35</input>
<input type="radio" class="Age" name="age" value="36">36-64</input>
<input type="radio" class="Age" name="age" value="65">65+</input>
<button id="reset">reset</button>
<!-- <a href="#" id="male">male</a>
<a href="#" id="female">female</a>
<a href="#" id="white">white</a>
-->
答案 1 :(得分:0)
如果通过循环每个MLA并递增计数器,每次点击一个类别时重新计算number
怎么样?我认为你通过尝试使用以前的计算作为起点使你复杂化,但每次重新开始都更容易。