admin管理员组

文章数量:1425711

I'm trying to create two number counters that can increment and decrement the other counter in real-time. Also I don't know Javascript too well.

 <input type="number" step="1" value="10" name="counter1" id="counter1">

 <input type="number" step="1" value="10" name="counter2" id="counter2">

If counter1 is increased, counter2 should be decreased, and vice versa; they are basically the inverse of each other. I've tried to implement some Javascript but it's not going well and I'm unsure of how to implement both incrementing and decrementing at the same time.

 <script type="text/javascript"> //some non-working example code
  function count() {
    var counter1 = document.getElementById('counter1').value;
    var counter2 = document.getElementById('counter2').value;
    document.getElementById('counter2').onclick = function() { //onclick doesn't take into account if the input was increased or decreased.
      counter2++;
      counter1--;
    }​
    document.getElementById('counter1').onclick = function() {
      counter1++;
      counter2--;
    }​
  }
 count();
 </script>

I'm trying to create two number counters that can increment and decrement the other counter in real-time. Also I don't know Javascript too well.

 <input type="number" step="1" value="10" name="counter1" id="counter1">

 <input type="number" step="1" value="10" name="counter2" id="counter2">

If counter1 is increased, counter2 should be decreased, and vice versa; they are basically the inverse of each other. I've tried to implement some Javascript but it's not going well and I'm unsure of how to implement both incrementing and decrementing at the same time.

 <script type="text/javascript"> //some non-working example code
  function count() {
    var counter1 = document.getElementById('counter1').value;
    var counter2 = document.getElementById('counter2').value;
    document.getElementById('counter2').onclick = function() { //onclick doesn't take into account if the input was increased or decreased.
      counter2++;
      counter1--;
    }​
    document.getElementById('counter1').onclick = function() {
      counter1++;
      counter2--;
    }​
  }
 count();
 </script>
Share Improve this question edited Feb 6, 2017 at 17:07 Mike Cluck 32.5k13 gold badges83 silver badges94 bronze badges asked Feb 6, 2017 at 16:39 ChazMcDingleChazMcDingle 6752 gold badges11 silver badges18 bronze badges 3
  • 1 try to set element value directly instead of changing a local variable. And use onChange callback – digital illusion Commented Feb 6, 2017 at 16:45
  • @ZakariaAcharki I am also unclear why I'm using onclick with input. – ChazMcDingle Commented Feb 6, 2017 at 16:49
  • @digitalillusion How does onChange know if the value was increased or decreased? – ChazMcDingle Commented Feb 6, 2017 at 16:52
Add a ment  | 

5 Answers 5

Reset to default 1

Two major problems:

  1. Assigning an input's value to a variable does not create a reference, it creates a copy. That means it isn't going to modify the number stored in the input, just the copied variable that you created.

  2. You shouldn't use the click event. You should use the change event since it will fire whenever the value changes.

Finally, you can track the previous value of each input and pare it against the new value to determine if it increased or decreased. Even more simply, you can calculate the difference between those values and subtract that difference from the other inputs value.

var counter1 = document.getElementById('counter1');
var counter2 = document.getElementById('counter2');
var prevCounter1 = counter1.value;
var prevCounter2 = counter2.value;

counter1.addEventListener('change', function() {
  var value1 = parseInt(counter1.value);
  var value2 = parseInt(counter2.value);
  var delta = value1 - prevCounter1;
  counter2.value = value2 - delta;
  prevCounter1 = value1;
});

counter2.addEventListener('change', function() {
  var value1 = parseInt(counter1.value);
  var value2 = parseInt(counter2.value);
  var delta = value2 - prevCounter2;
  counter1.value = value1 - delta;
  prevCounter2 = value2;
});
<input type="number" step="1" value="10" name="counter1" id="counter1">
<input type="number" step="1" value="10" name="counter2" id="counter2">

Simply..

console.log(counter1);
10

What you can understand here, is that you are assigning the value of document.getElementById('counter1').value to counter1, and not the element.

Proper USE

You should use something like :

counter1 = document.getElementById('counter1');

And to update it :

counter1.value++;

Minimalist CODE :

counter1 = document.getElementById('counter1');
counter2 = document.getElementById('counter2');

counter2.onclick = function() { counter2.value++; counter1.value--; };
counter1.onclick = function() { counter1.value++; counter2.value--; };

Here is a working fiddle, that as you change one input, it will update the other input.

https://jsfiddle/ctor9qk3/

Code :

Html:

 <input type="number" step="1" value="10" name="counter1" id="counter1">
 <input type="number" step="1" value="10" name="counter2" id="counter2">

Javascript:

var counter1 = document.getElementById("counter1");
var counter1Value = counter1.value;
var counter2 = document.getElementById("counter2");
var counter2Value = counter2.value;

counter1.addEventListener('change', function() {    
  var amountOfChange = diff(this.value,counter1Value);
  counter1Value = this.value;    
  counter2Value = counter2.value = parseInt(counter2Value - amountOfChange);   
}, false);

counter2.addEventListener('change', function() {    
  var amountOfChange = diff(this.value,counter2Value);  
  counter2Value = this.value;  
  counter1Value = counter1.value = parseInt(counter1Value - amountOfChange);
}, false);

function diff (a, b) { return a - b }

This should work:

var ConnectedCounter = (function ConnectedCounter(selector) {
  var connectedCounter = {
    element: null,
    value: 0
  };
  var self = {
    element: null,
    value: 0
  };

  function init() {
    self.element = document.querySelector(selector);
    if(self.element) {
      self.value = parseInt(self.element.value);
      connectedCounter.element = document.querySelector(self.element.dataset.target);
    }
    if(connectedCounter) {
      connectedCounter.value = parseInt(connectedCounter.element.value);
      ['keyup', 'mouseup'].forEach(event => self.element.addEventListener(event, onUpdate));
      ['keyup', 'mouseup'].forEach(event => connectedCounter.element.addEventListener(event, onUpdate));
    }
  }
  
  function onUpdate(event) {
    var target = event.target;
    var currentValue = +target.value;
    var connectedTarget = null;
    if(target === self.element) {
      target = self;
      connectedTarget = connectedCounter
    }
    else if(target === connectedCounter.element) {
      target = connectedCounter;
      connectedTarget = self;
    }
    currentValue = isNaN(currentValue)? target.value: currentValue;
    connectedTarget.element.value = connectedTarget.value += (target.value > currentValue? 1: -1)*Math.abs(currentValue - target.value);
    target.value = currentValue;
  }

  init();

  return {
    element: self,
    connected: connectedCounter
  }
})

document.addEventListener('DOMContentLoaded', function(e) { var x = new ConnectedCounter('#counter1')});
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
   <input type="number" step="1" value="10" name="counter1" id="counter1" data-target="#counter2">
   <input type="number" step="1" value="10" name="counter2" id="counter2">
   
    <script src="script.js"></script>
  </body>

</html>

After you change a variable you have to set it in the DOM e.g. through document.getElementById('counter1').value = counter1; To get the changes of the inputs the click event works but I would prefer to listen for change events.


UPDATE I have to e up with a slightly more elegant solution. When one value should increase while the other is decreased the sum of both values will be the same. So it's just easier to initially sum up the values and afterwards calculate the second value by substracting the first (changed) value from the sum:

var input1 = document.getElementById('counter1');
var input2 = document.getElementById('counter2');
var sum = parseInt(input2.value) + parseInt(input1.value);

function onChange(e) {
    if (this===input1) 
        input2.value = sum - parseInt(input1.value);
    else
        input1.value = sum - parseInt(input2.value);    
}

input1.onchange = onChange;
input2.onchange = onChange;
<input type="number" step="1" value="10" name="counter1" id="counter1">
<input type="number" step="1" value="10" name="counter2" id="counter2">


You can try something like this:

var input1 = document.getElementById('counter1');
var input2 = document.getElementById('counter2');
var lastCounter1 = parseInt(input1.value);
var lastCounter2 = parseInt(input2.value);

input2.onclick = function() {
        var counter2 = parseInt(input2.value);
        var counter1 = parseInt(input1.value);
        counter1 += (lastCounter2 - counter2);
        input1.value = counter1;
        lastCounter2 = counter2;
        lastCounter1 = counter1;
}

input1.onclick = function() {
        var counter1 = parseInt(input1.value);
        var counter2 = parseInt(input2.value);
        counter2 += (lastCounter1 - counter1);
        input2.value = counter2;
        lastCounter1 = counter1;
        lastCounter2 = counter2;
}
<input type="number" step="1" value="10" name="counter1" id="counter1">
<input type="number" step="1" value="10" name="counter2" id="counter2">

本文标签: htmlDynamic input for number counters in JavascriptStack Overflow