计算不会返回正确的值

时间:2016-04-04 02:47:33

标签: javascript html

任何人都可以告诉我这个javascript代码有什么错误吗?

计划:http://utilizaweb.com.br/aposentadorianovo/

function calcula(){
var fieldsContainer=document.getElementsByClassName("trabalho")[0].
                             getElementsByClassName("row"),
    i,
    jobFields=[],
    len,
    newAge=0,
    selfGender=document.aposentadoria.sexo.value,
    workedDays=0,
    workedMonthies=0,
    workedYears=0;
len=fieldsContainer.length;
for(i=0;len>i;i++){
    jobFields[i]={
        admissionDate:new Date(fieldsContainer[i].getElementsByClassName("admissao-area")[0].children[1].value),//data de admissão,
        ageRule:fieldsContainer[i].getElementsByClassName("regra-area")[0].children[0].value,//regra
        demissionDate:new Date(fieldsContainer[i].getElementsByClassName("demissao-area")[0].children[1].value),//data de demissão
        jobBusiness:fieldsContainer[i].getElementsByClassName("empresa-area")[0].children[1].value//empresa do trabalho
    };
    if (jobFields[i].demissionDate > jobFields[i].admissionDate) {
        jobFields[i].workedYears=jobFields[i].demissionDate.getFullYear() - jobFields[i].admissionDate.getFullYear();
        jobFields[i].workedMonthies=jobFields[i].demissionDate.getMonth() - jobFields[i].admissionDate.getMonth();
        jobFields[i].workedDays=jobFields[i].demissionDate.getDate() - jobFields[i].admissionDate.getDate();
        alert(jobFields[i].workedYears)
    } else {
        alert("A data de admissão deve ser anterior à data de demissão.");
        throw new Error("Conversor :: Admission date must be older than demission date.")
    }
}
var fieldsRule=[];
len=jobFields.length;
for(i=0;len>i;i++){
    fieldsRule[i]=jobFields[i].ageRule
}
var calculateFields=[],
    higherRule=Math.max.apply(fieldsRule)
len=jobFields.length;
for(i=0;len>i;i++){
    if(fieldsRule[i]===higherRule){
        calculateFields[i]=i
    }
}
var ageMultiplyBy,
    missingYears,
    jobYearsEnd;
len=calculateFields.length;
if (selfGender === "M") {
    for(i=0;len>i;i++){
        ageMultiplyBy=
                    jobFields[calculateFields[i]].ageRule==="25"?1.40:
                    jobFields[calculateFields[i]].ageRule==="20"?1.75:
                    jobFields[calculateFields[i]].ageRule==="15"?2.33:
                    1.75;
        newAge=jobFields[calculateFields[i]].workedYears*ageMultiplyBy;
        missingYears=newAge - 35
    }
} else {
    for(i=0;len>i;i++){
        ageMultiplyBy=
                    jobFields[calculateFields[i]].ageRule==="25"?1.20:
                    jobFields[calculateFields[i]].ageRule==="20"?1.50:
                    jobFields[calculateFields[i]].ageRule==="15"?2:
                    1.20;
        newAge=jobFields[calculateFields[i]].workedYears*ageMultiplyBy;
        missingYears=newAge - 30
    }
}

alert(missingYears)
if (missingYears < 0) {
    jobYearsEnd=missingYears * -1;
}
document.getElementById("anosTrabalhados").innerHTML = workedYears+ " anos";
document.getElementById("result").innerHTML = "<img src='./img/aviso.png'>" +"Você trabalhou " +workedYears+ " anos, " +workedMonthies+ " meses e " +workedDays+ " dias"+ "<br />" +"Faltam " +jobYearsEnd+ " anos para se aposentar"
}

[如果WASN&#39; TELL解释,请告诉我。我不能说英语]

我需要获取admissionDate的值以及每行的demissionDate和subtract的值,包括用户添加的值。然后,我需要获得规则的最大值相等,并将每个规则的工作时间加起来。然后,程序将所加工的时间加起来并乘以每个规则的值,在男性的情况下减去35,在女性的情况下减去30。然后显示最后计算的值(减去30或35)。

代码错在哪里?

按查看源代码查看代码

1 个答案:

答案 0 :(得分:0)

我尽力做到这一点,因为有几个挑战和几点,我不是百分之百确定你的意图。我相信你可以在这里工作。处理多个相关日期时,日期很难。如果边界跨越夏令时等,该怎么办。为了帮助我使用日期库,随意获取另一个或使用它,我将其粘贴到小提琴代码中;使用它或得到另一个做那些东西,而不是重新发明一个。我没有广泛使用它。

这是一个保存的小提琴来测试/试用:(见底部的好部分)https://jsfiddle.net/MarkSchultheiss/1ttmecoe/

链接日期库:http://slingfive.com/pages/code/jsDate/jsDate.html

说明:

首先,您未公开的代码会复制一个ID,而且这些ID必须是唯一的,当您使用它时,它是错误的。我通过使用jQuery .clone()修复了这个问题。我还提出了一个方法来添加/删除列表中的行(除了最后一行),这些行在页面上是缺少的。

代码片段:

document.getElementById("anosTrabalhados").innerHTML

我将向您展示如何解决这个问题(请参阅标记和.clone()

  • 你有一些相当复杂的选择器,可以通过使用类来简化。

代码片段:

jobFields[i]={
    admissionDate:new Date(fieldsContainer[i].getElementsByClassName("admissao-area")[0].children[1].value),//data de admissão,

修订:

var thisRow = fieldsContainer[i];
jobFields[i] = {
  admissionDate: new Date(thisRow.getElementsByClassName("dataAdmissao")[0].value),
  • 在循环中间检查/验证日期,也许您可​​以在循环之前检查这些日期?我现在离开那里了。

代码片段:

if (jobFields[i].demissionDate > jobFields[i].admissionDate) {

这似乎是一个语法问题:

higherRule=Math.max.apply(fieldsRule) //old
higherRule=Math.max.apply(null, fieldsRule); //repaired

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

  • 从代码中删除常量并将它们放在一个对象中:

代码片段:

var calcVals = {
  rules: {
    male: {
      sex: "M",
      defaultRate: 1.75,
      ageVar: 35,
      ageRules: [{
        age: "25",
        val: 1.40
      }, {
        age: "20",
        val: 1.75
      }, {
        age: "15",
        val: 2.33
      }]
    },
    female: {
      sex: "M",
      defaultRate: 1.50,
      ageVar: 30,
      ageRules: [{
        age: "25",
        val: 1.20
      }, {
        age: "20",
        val: 1.50
      }, {
        age: "15",
        val: 2.00
      }]
    }
  }
};

然后再使用它:(这摆脱了重复的硬编码条件,使其更简单,更易于维护)

calcT = (selfGender === "M") ? calcT = calcVals.rules.male : calcT = calcVals.rules.female;
ageMultiplyBy = calcT.defaultRate;
for (i = 0; len > i; i++) {
  for (var j = 0; j < calcT.ageRules.length; j++) {
    if (jobFields[calculateFields[i]].ageRule === calcT.ageRules[j].age) {
      ageMultiplyBy = calcT.ageRules[j].val;
      break;
    }
  }
  ...more code
  • 将字符串分配给数组

代码片段:

fieldsRule[i]=jobFields[i].ageRule

这改变了这种比较:(也见下一个代码段)

if(fieldsRule[i]===higherRule){

fieldsRule[i]是字符串,higherRule是数字(请参阅上面的Math.max.apply

您可以根据len设置迭代变量jobFields,但访问可能未定义的fieldsRule[i]。你的意思是推送到阵列而不是分配给它吗?我问,因为稍后您使用len=calculateFields.length;作为迭代值。请注意,如果数组上的长度不同,则可能不会评估所有fieldsRule[i],或者它可能具有undefined值。 (请注意,这是您所需功能变得不那么清晰的地方)

len=jobFields.length;
for(i=0;len>i;i++){
    if(fieldsRule[i]===higherRule){
        calculateFields[i]=i
    }
}

稍后会看到这一点:newAge=jobFields[calculateFields[i]].workedYears*ageMultiplyBy;其中calculateFields[i]可能未定义。

修订标记:

<form class="form-calculadora" name="aposentadoria">
  <fieldset class="sexo">
    <legend>Sexo</legend>
    <select id="sexo" class="text-area">
      <option value="M">Masculino</option>
      <option value="F">Feminino</option>
    </select>
  </fieldset>
  <fieldset class="trabalho">
    <div class="row p_scents">
      <div class="empresa-area">
        <p class="title">Empresa</p>
        <input type="text" class="text-area empresa" placeholder="Empresa: ">
      </div>
      <div class="regra-area">
        <p class="title">Regra</p>
        <select class="text-area regra">
          <option value="25">25 anos</option>
          <option value="20">20 anos</option>
          <option value="15">15 anos</option>
        </select>
      </div>
      <div class="admissao-area">
        <p class="title">Admissão</p>
        <input type="date" class="text-area dataAdmissao" placeholder="Admissão: " />
      </div>
      <div class="demissao-area">
        <p class="title">Demissão</p>
        <input type="date" class="text-area dataDemissao" placeholder="Demissão: " />
      </div>
      <div class="anos-area">
        <p class="anosTrabalhados">0 anos</p>
      </div>
      <button class="removerow">
        Remove Row
      </button>
    </div>
  </fieldset>

  <p class="add-empresa"><a href="#" id="addScnt"><i class="fa fa-user-plus"></i> Adicionar Empresa</a></p>
  <p id="result">Você trabalhou 0 anos, 0 meses e 0 dias
    <br/>Faltam undefined anos para se aposentar</p>
  <input type="button" value="Calcular" class="btn" id="calcular" />
</form>

修订代码:

var calcVals = {
  rules: {
    male: {
      sex: "M",
      defaultRate: 1.75,
      ageVar: 35,
      ageRules: [{
        age: "25",
        val: 1.40
      }, {
        age: "20",
        val: 1.75
      }, {
        age: "15",
        val: 2.33
      }]
    },
    female: {
      sex: "M",
      defaultRate: 1.50,
      ageVar: 30,
      ageRules: [{
        age: "25",
        val: 1.20
      }, {
        age: "20",
        val: 1.50
      }, {
        age: "15",
        val: 2.00
      }]
    }
  }
};

function calcula() {
  var rows = $('.row');
  var fieldsContainer = document.getElementsByClassName("trabalho")[0].
  getElementsByClassName("row"),
    i,
    jobFields = [],
    len,
    newAge = 0,
    selfGender = document.aposentadoria.sexo.value,
    workedDays = 0,
    workedMonthies = 0,
    workedYears = 0;
  var fieldsRule = [];
  var calculateFields = [],
    len = fieldsContainer.length;
  for (i = 0; i < len; i++) {
    var thisRow = fieldsContainer[i];
    jobFields[i] = {
      admissionDate: new Date(thisRow.getElementsByClassName("dataAdmissao")[0].value),
      demissionDate: new Date(thisRow.getElementsByClassName("dataDemissao")[0].value),
      ageRule: thisRow.getElementsByClassName("regra")[0].value,
      jobBusiness: thisRow.getElementsByClassName("empresa")[0].value
    };
    //  console.dir(jobFields);
    if (jobFields[i].demissionDate > jobFields[i].admissionDate) {
      jobFields[i].workedYears = Date.DateDiff('yyyy', jobFields[i].admissionDate, jobFields[i].demissionDate);
      // get months after remove years
      jobFields[i].workedMonthies = Date.DateDiff('m', jobFields[i].admissionDate, jobFields[i].demissionDate) - (jobFields[i].workedYears * 12);
      //    console.log('days:' + Date.DateDiff('d', jobFields[i].admissionDate, jobFields[i].demissionDate) );
      // get days worked after remove years/months
      var adate = new Date(jobFields[i].demissionDate);
      adate = new Date(adate.setFullYear(jobFields[i].demissionDate.getFullYear() - jobFields[i].workedYears));
      adate = new Date(adate.setMonth((adate.getMonth()) - jobFields[i].workedMonthies));
      jobFields[i].workedDays = Date.DateDiff('d', jobFields[i].admissionDate, adate); //- (new Date(jobFields[i].admissionDate) - new Date(jobFields[i].demissionDate));
      //   console.log('worked' + i + ":" + jobFields[i].workedYears);
    } else {
      alert("A data de admissão deve ser anterior à data de demissão. not less");
      // throw new Error("Conversor :: Admission date must be older than demission date.")
    }
  }
  len = jobFields.length;
  for (i = 0; len > i; i++) {
    fieldsRule[i] = +jobFields[i].ageRule;
  }
  var higherRule = Math.max.apply(null, fieldsRule);
  console.log("higherRule:" + higherRule + " fLen:" + fieldsRule.length);
  len = jobFields.length;
  console.dir({
    "jobf": jobFields
  });
  //console.dir(fieldsRule);
  for (i = 0; i < len; i++) {
    if (fieldsRule[i] === higherRule) {
      calculateFields[i] = i;
    }
  }
  console.dir({
    "calcf": calculateFields
  });
  var ageMultiplyBy,
    missingYears,
    jobYearsEnd;
  console.dir(fieldsRule);
  len = calculateFields.length;
  var calcT = {};
  calcT = (selfGender === "M") ? calcT = calcVals.rules.male : calcT = calcVals.rules.female;

  ageMultiplyBy = calcT.defaultRate;
  for (i = 0; len > i; i++) {
    for (var j = 0; j < calcT.ageRules.length; j++) {
      if (jobFields[calculateFields[i]].ageRule === calcT.ageRules[j].age) {
        ageMultiplyBy = calcT.ageRules[j].val;
        break;
      }
    }
    newAge = jobFields[calculateFields[i]].workedYears * ageMultiplyBy;
    missingYears = newAge - calcT.ageVar;
  }
  console.log('mys:' + missingYears);
  if (missingYears < 0) {
    jobYearsEnd = (+missingYears) * -1;
  }
  len = jobFields.length;
  for (i = 0; i < len; i++) {
    workedYears = workedYears + jobFields[i].workedYears;
    workedMonthies = workedMonthies + jobFields[i].workedMonthies;
    workedDays = workedDays + jobFields[i].workedDays;;
  }
  //invalid id cannot be dupe  document.getElementById("anosTrabalhados").innerHTML = workedYears + " anos";
  for (var m = 0; m < rows.length; m++) {
    console.log('wy:' + workedYears);
    $('.row').eq(m).find('.anosTrabalhados').text(workedYears + " anos");
  }
  //  document.getElementById("anosTrabalhados").innerHTML = workedYears + " anos";
  document.getElementById("result").innerHTML = "<img src='./img/aviso.png'>" + "Você trabalhou " + workedYears + " anos, " + workedMonthies + " meses e " + workedDays + " dias" + "<br />" + "Faltam " + jobYearsEnd + " anos para se aposentar"
}
$(function() {
  // set defaults for testing
  makedefaults(0);

  $('#calcular').on('click', function() {
    calcula();
  });
  // add a row
  $('#addScnt').on('click', function(e) {
    var rowContainer = $('.trabalho');
    var rows = rowContainer.find('.row');
    var newRow = rows.eq(0).clone(true);
    rowContainer.append(newRow);
    e.preventDefault();
    return false;
  });
  // remove any row but last one
  $('.trabalho').on('click', '.removerow', function(e) {
    var rowsCount = $('.trabalho').find('.row').length;
    if (rowsCount > 1) {
      $(this).parents('.row').remove();
    }
    e.preventDefault();
    return false;
  });
});