最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to prevent 0 as null in javascript - Stack Overflow

programmeradmin1浏览0评论

I have the following code with following conditions:

  • A value less than 60 seconds is fast
  • A value more than 60 seconds is slow
  • Must fill out both input fields to show "fast" or "slow"

My only problem is that the code interprets 0 as null. So, If I put 1 minutes 0 seconds, then nothing shows.

I want it to show "fast" when I enter 1 minute 0 seconds.

Thanks in advance.

<html>
<head>

  <script type="text/javascript" src="//code.jquery/jquery-1.9.1.js"></script>

  <!-- TODO: Missing CoffeeScript 2 -->

  <script type="text/javascript">//<![CDATA[

    $(window).load(function(){
      
        $('input').keyup(function(){
            var min = 60 * Number($('#D').val());
            var sec = Number($('#E').val());

            if ((min+sec) <= 60) {document.getElementById("Run").innerHTML = "Fast";}
            if ((min+sec) >= 61) {document.getElementById("Run").innerHTML = "Slow";}
            
            if (min == null | min == "") {document.getElementById("Run").innerHTML = "";}
            if (sec == null | sec == "") {document.getElementById("Run").innerHTML = "";}
            
        });
        
	});
</script>

<style>
	h1 { margin: 0 10px 25px 5px; padding: 5px; font-size: 32px; font-family: Arial }
	input { margin: 0 10px 10px 10px; padding: 5px; font-size: 24px; width: 200px }
    label { margin: 0 10px 10px 10px; font-size: 20px; display: block; font-family: Arial }
	span { margin: 0 0px 0px 10px; font-size: 44px; font-family: Arial }
	stat { margin: 0 0px 0px 10px; font-size: 24px; font-family: Arial }
</style>

</head>
<body>
    
    <input id="D"
    	type="number" 
        class="form-control formBlock" 
        placeholder="Minutes" 
        required="" 
        min="1" 
        max="59"
        onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
        >
    <stat id="Run"></stat><br>
    <input id="E" 
    	type="number" 
    	class="form-control formBlock" 
    	placeholder="Seconds" 
        required="" 
        min="1" 
        max="59"
        onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
        >
        <br>
    <br>

  <script>
    // results
    if (window.parent && window.parent.parent){
      window.parent.parent.postMessage(["resultsFrame", {
        height: document.body.getBoundingClientRect().height,
        slug: ""
      }], "*")
    }
    window.name = "result"
    
    //
    
  </script>

</body>

</html>

I have the following code with following conditions:

  • A value less than 60 seconds is fast
  • A value more than 60 seconds is slow
  • Must fill out both input fields to show "fast" or "slow"

My only problem is that the code interprets 0 as null. So, If I put 1 minutes 0 seconds, then nothing shows.

I want it to show "fast" when I enter 1 minute 0 seconds.

Thanks in advance.

<html>
<head>

  <script type="text/javascript" src="//code.jquery./jquery-1.9.1.js"></script>

  <!-- TODO: Missing CoffeeScript 2 -->

  <script type="text/javascript">//<![CDATA[

    $(window).load(function(){
      
        $('input').keyup(function(){
            var min = 60 * Number($('#D').val());
            var sec = Number($('#E').val());

            if ((min+sec) <= 60) {document.getElementById("Run").innerHTML = "Fast";}
            if ((min+sec) >= 61) {document.getElementById("Run").innerHTML = "Slow";}
            
            if (min == null | min == "") {document.getElementById("Run").innerHTML = "";}
            if (sec == null | sec == "") {document.getElementById("Run").innerHTML = "";}
            
        });
        
	});
</script>

<style>
	h1 { margin: 0 10px 25px 5px; padding: 5px; font-size: 32px; font-family: Arial }
	input { margin: 0 10px 10px 10px; padding: 5px; font-size: 24px; width: 200px }
    label { margin: 0 10px 10px 10px; font-size: 20px; display: block; font-family: Arial }
	span { margin: 0 0px 0px 10px; font-size: 44px; font-family: Arial }
	stat { margin: 0 0px 0px 10px; font-size: 24px; font-family: Arial }
</style>

</head>
<body>
    
    <input id="D"
    	type="number" 
        class="form-control formBlock" 
        placeholder="Minutes" 
        required="" 
        min="1" 
        max="59"
        onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
        >
    <stat id="Run"></stat><br>
    <input id="E" 
    	type="number" 
    	class="form-control formBlock" 
    	placeholder="Seconds" 
        required="" 
        min="1" 
        max="59"
        onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
        >
        <br>
    <br>

  <script>
    // results
    if (window.parent && window.parent.parent){
      window.parent.parent.postMessage(["resultsFrame", {
        height: document.body.getBoundingClientRect().height,
        slug: ""
      }], "*")
    }
    window.name = "result"
    
    //
    
  </script>

</body>

</html>

Share Improve this question asked May 10, 2020 at 23:53 Jim O.Jim O. 1,1111 gold badge14 silver badges33 bronze badges 8
  • Can you explain what you mean by "the code interprets 0 as null?" – Jacob Commented May 10, 2020 at 23:56
  • 8 === – Marco Bonelli Commented May 10, 2020 at 23:56
  • Thanks, Marco. If you post an answer to my question, then I will select it as the correct answer. – Jim O. Commented May 10, 2020 at 23:57
  • @MarcoBonelli Strict equality doesn't solve the problem here. Both conditions would simply never be entered if === is used since a type "number" can't ever be === null or === ''. – plalx Commented May 11, 2020 at 1:10
  • @plalx a type number will be "" with any NaN values, or without any value. To OP, note that you have your min attributes set to "1", if you really want to allow "0", then set them to "0" ;-) – Kaiido Commented May 11, 2020 at 1:27
 |  Show 3 more ments

3 Answers 3

Reset to default 3

"My only problem is that the code interprets 0 as null"

That's an incorrect assumption, since Number('0') == null is false.

The reason your code behaves like that is 0 == '' is true in JavaScript. You could use === for strict equality, but then both of your conditions would never be entered since min nor sec can be === null or === ''.

min and sec are assigned the result of a number conversion which can only yield a valid number or NaN. Anything that doesn't coerce to a number would give NaN. Unfortunately blank strings does coerce to 0, but you can use the || operator to coerce '' into NaN, since empty string is the only falsy value you can get from your input values (given type="number").

From that point the values can either be numbers or NaN. Given that NaN + number gives out NaN you can safely assume that if isNaN(min + sec) then one of the inputs were invalid or blank.

Also note that you're using | (bitwise or) instead of ||. The if branching oute was the same as || in your code because the left-hand-side and right-hand-side were booleans, but it's more semantically correct to use ||.

EDIT: @Kaiido makes a point using input.valueAsNumber, which properly coerces '' to NaN already, removing the need for Number(input.value || NaN). See his answer for a slightly better solution.

<html>
<head>

  <script type="text/javascript" src="//code.jquery./jquery-1.9.1.js"></script>

  <!-- TODO: Missing CoffeeScript 2 -->

  <script type="text/javascript">//<![CDATA[

    $(window).load(function(){
      
        $('input').keyup(function(){
            const min = 60 * Number($('#D').val() || NaN);
            const sec = Number($('#E').val() || NaN);
            const total = min + sec;

            const speed = isNaN(total)? '' : (total <= 60? 'Fast' : 'Slow');
            
            document.getElementById("Run").innerHTML = speed;     
        });
        
	});
</script>

<style>
	h1 { margin: 0 10px 25px 5px; padding: 5px; font-size: 32px; font-family: Arial }
	input { margin: 0 10px 10px 10px; padding: 5px; font-size: 24px; width: 200px }
    label { margin: 0 10px 10px 10px; font-size: 20px; display: block; font-family: Arial }
	span { margin: 0 0px 0px 10px; font-size: 44px; font-family: Arial }
	stat { margin: 0 0px 0px 10px; font-size: 24px; font-family: Arial }
</style>

</head>
<body>
    
    <input id="D"
    	type="number" 
        class="form-control formBlock" 
        placeholder="Minutes" 
        required="" 
        min="1" 
        max="59"
        onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
        >
    <stat id="Run"></stat><br>
    <input id="E" 
    	type="number" 
    	class="form-control formBlock" 
    	placeholder="Seconds" 
        required="" 
        min="1" 
        max="59"
        onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }"
        >
        <br>
    <br>

  <script>
    // results
    if (window.parent && window.parent.parent){
      window.parent.parent.postMessage(["resultsFrame", {
        height: document.body.getBoundingClientRect().height,
        slug: ""
      }], "*")
    }
    window.name = "result"
    
    //
    
  </script>

</body>

</html>

Marco's got the fix for your immediate problem, where you need to pare for type as well as value by using === (strict parison). More info: https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

You also have an issue with your logic, where you are using the bitwise OR | in your conditionals. I'm sure you mean to use a normal OR parison, ||:

        if (min === null || min === "") {document.getElementById("Run").innerHTML = "";}
        if (sec === null || sec === "") {document.getElementById("Run").innerHTML = "";}

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

When using type="number" inputs, use it pletely.

They do offer a valueAsNumber property getter, which will coerce your values directly to Numbers, so all you have to do next, is to use them after a fool-guard check against isNaN():

$(window).load(function() {

  const min_input = $('#D')[0];
  const sec_input = $('#E')[0];
  const run_elem = document.getElementById("Run");

  $('input').keyup(function() {
    var min = 60 * min_input.valueAsNumber;
    var sec = sec_input.valueAsNumber;

    if( isNaN(min + sec) ) {
      run_elem.innerHTML = "";
    }
    else if ((min + sec) <= 60) {
      run_elem.innerHTML = "Fast";
    }
    else if ((min + sec) >= 61) {
      run_elem.innerHTML = "Slow";
    }

  });

});
h1 {
  margin: 0 10px 25px 5px;
  padding: 5px;
  font-size: 32px;
  font-family: Arial
}

input {
  margin: 0 10px 10px 10px;
  padding: 5px;
  font-size: 24px;
  width: 200px
}

label {
  margin: 0 10px 10px 10px;
  font-size: 20px;
  display: block;
  font-family: Arial
}

span {
  margin: 0 0px 0px 10px;
  font-size: 44px;
  font-family: Arial
}

stat {
  margin: 0 0px 0px 10px;
  font-size: 24px;
  font-family: Arial
}
<script type="text/javascript" src="//code.jquery./jquery-1.9.1.js"></script>
<input id="D" type="number" class="form-control formBlock" placeholder="Minutes" required="" min="0" max="59" onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }">
<stat id="Run"></stat><br>
<input id="E" type="number" class="form-control formBlock" placeholder="Seconds" required="" min="0" max="59" onkeyup="if(parseInt(this.value) > 59){ this.value = 59; return false; }">

发布评论

评论列表(0)

  1. 暂无评论