单击元素时,Javascript中的数学问题

未解

最后更新时间:下午4:15

我在哪里

我有三个类别供人们选择:性别,年龄,种族。 每个都有自己的选项男/女; 35岁以下,36-64岁,65岁以上; 白色,黑色,原住民,梅蒂斯人和亚洲人。

单击其中一个选项时,该数字应从var total减去(即MLA的数量)。 我已经为数字设置了全局变量,这会更改位于我的index.html文件中的span.number ,说“有适合您人口统计的x-MLA。”

我被困在哪里

a)我正在寻找一种更有效的Javascript数学运算方法,现在它很漂亮。 如果你看一下scripts.js中的Gender选项,我已经创建了一个变量var resultMale = total - female但是当生成span.number依赖于之前选择的选项的结果时,它会变得不那么漂亮。

b)我尝试过使用管道布尔值,但我不清楚在第二类“Age”中如何包含var resultLow = resultMale || resultFemale -(middle + high) var resultLow = resultMale || resultFemale -(middle + high)如何知道在“性别”类别中点击/选择的内容,以便它可以进行正确的数学运算。

scripts.js中

 $(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(); }); 

index.html(包括span.number)

  

Gender

Male

Female

Age

Under 35

36-64

65+

Ethnicity*

White

Black

Aboriginal

Metis

Asian

There are 56 MLAs that fit in your demographic

(Does not include the single vacant seat for the Pas.)

如果我理解正确,下面的演示应该做你想要的。 你可以在jsFiddle找到下面的代码。 (旧版本的jsfiddle,新版本见下面的编辑。)

它基本上是做和我建议的。 对于“计算”,我使用UnderscoreJS使用where方法查找当前单击选择的匹配键/值对。 然后很容易得到长度选择的总和。

在演示中,我已经为男性,女性和种族做过。 它应该与其他选项完全相同。


编辑07.02.2015

我改进了代码。 现在,您可以在列表中激活多个filter。 此外,删除减法因为筛选列表始终包含具有length属性的项目数。

代码正在运行,但仍有一些要改进的地方:

  • 需要更改removeFilter以轻松删除filter而不指定filter参数
  • setFilter改进: if ( index == -1 ) {并不是真的需要,因为在添加新filter之前总是删除filter。
  • 为每个无线电组添加重置按钮。 目前,只有一个“全部重置”按钮。
  • 使用AngularJS更新DOM会更好,因为脚本总是在每次filter更改时重新创建DOM。
  • 也许使用AngularJS,你可以检查是否有ng-repeat的filter来做类似的行为。

我可能还没有测试filter的任何组合是否正常工作,因为我只有三个列表项。 所以你必须用代码做更多的测试。

我在这里更新了代码到最新版本,这里是jsFiddle 。


更多代码解释16.02.2015

函数refreshListsetTotal用于更新DOM。

应用filter后,filter函数的genderethnicityage将返回新数组。

数组activeFilters正在存储当前选定的filter。 它存储filter函数,以便通过遍历此数组来调用它们。 稍后会详细介绍。

setFilter方法正在设置filter。 它将filter添加到activeFilters数组,然后应用filter。

applyFilter函数可能是最难理解的。 它遍历activeFilters数组的每个项目。 如果您有两个有效filter(此处为性别和种族),则数组activeFilters将如下所示:

 activeFilters = [{ method: function(array, gender){...}, param: 'male' }, { method: function (array, ethnic){...}, param: 'white' }]; 

使用activeFilters[0].method(MLAs,'male')您可以手动调用性别filter。 这就是$ .each循环在循环中执行的操作, this{method: ..., param: ...} 。 因此,使用this.method(filtered, this.param) ,filter将应用于已filtered的变量。 在循环之后,每个活动filter将应用于arrays。

 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($('
  • ').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, eg 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(); });
       There are  MLAs matching. 

      click to filter:

      male female white black under 35 36-64 65+

      如果通过循环每个MLA并递增计数器,每次点击一个类别时重新计算number ? 我认为你通过尝试使用以前的计算作为起点使其复杂化,但每次重新开始都更容易。