一个函数的多个对象事件?

时间:2018-04-17 16:14:54

标签: javascript html5

所以我正在尝试制作一个带有3个滑块的html页面作为背景(R,G,B)

我希望每个滑块调用一个改变输入背景的函数,但除非我为每个事件重写函数,否则我无法工作。请耐心等待,我是一个新的编码器,其中大部分都是意大利面。

var red = document.getElementById("red"); //slider values
var routput = document.getElementById("reddemo"); //display values
routput.innerHTML = red.value; //for function

var green = document.getElementById("green");
var goutput = document.getElementById("greendemo");
goutput.innerHTML = green.value;

var blue = document.getElementById("blue");
var boutput = document.getElementById("bluedemo");
boutput.innerHTML = blue.value;

red.oninput && blue.oninput && green.oninput = function() {
  //this is what I want to do; string all of these oninputs together... obviously this way doesn't work
  var x = Math.round([Number(red.value) + Number(blue.value) + Number(green.value)] / 3);
  //this is for later, the text color in body changes to white when color values get too low 

  routput.innerHTML = Math.round(this.value);
  boutput.innerHTML = Math.round(this.value);
  goutput.innerHTML = Math.round(this.value);

  document.body.style.backgroundColor = "rgb(" + routput.innerHTML + "," + routput.innerHTML + "," + routput.innerHTML + ")";

  if (x < 127.5) {
    document.body.style.color = "rgb(255,255,255)";
  } else {
    document.body.style.color = "rgb(0,0,0)";
  }
}
<p>Red</p>
<div class="slidecontainer">
  <input type="range" min="0" max="255" value="255" class="slider" id="red">
  <p>Value: <span id="reddemo"></span></p>
</div>
<p>Green</p>
<div class="slidecontainer">
  <input type="range" min="0" max="255" value="255" class="slider" id="green">
  <p>Value: <span id="greendemo"></span></p>
</div>
<p>Blue</p>
<div class="slidecontainer">
  <input type="range" min="0" max="255" value="255" class="slider" id="blue">
  <p>Value: <span id="bluedemo"></span></p>
</div>

3 个答案:

答案 0 :(得分:1)

JavaScript中的函数是一等公民,这意味着您可以将函数视为变量:

var changeBackground = function () {…};

red.oninput = changeBackground;
blue.oninput = changeBackground;
…

答案 1 :(得分:0)

另一种解决方案--Makhiel's也是正确的:

red.oninput = blue.oninput = green.oninput = function() {
在JavaScript中,

&&是'逻辑的':它总是变为真或假。虽然“将red.oninput和blue.oninput设置为相同的函数”在英语中有效,但英语中的并不会转换为Javascript中的。

答案 2 :(得分:0)

使用HTMLFormControlsCollection API非常简单。 将元素更改为更多语义和功能表单控件元素:<form><output><fieldset><legend><label>。使用Template Literals将所有3个值混合在一个值中。

减少函数和事件数量的关键是通过使用一个元素作为范围的共同祖先来使用Event Delegation,监听输入事件。然后,通过引用Event.target,我们可以确切地确定与用户交互的范围。

在这种情况下,BTW不需要将任何值转换为数字,因为CSS作为RGB颜色的值实际上是具有表示数字的字符的字符串。

更新

添加了第二个Demo,它与Demo 1完全相同,但使用 On Event Attributes 只需极少的代码。虽然强烈建议不要使用它们,但我已经看到它在当前但很少使用的代码中的应用越来越多。

演示1

在演示中评论的详细信息

form {
  display: flex;
  flex-flow: column wrap;
  height: 100vh;
}

.slidecontainer {
  width: 40%;
  height: 15vh
}

output {
  transform: translate(5px, -7px);
  display: inline-block;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <form id='rgb'>

    <fieldset class="slidecontainer">
      <legend>Red</legend>
      <input type="range" min="0" max="255" value="255" class="slider" id="red0">
      <output id="redO"></output>
    </fieldset>

    <fieldset class="slidecontainer">
      <legend>Green</legend>
      <input type="range" min="0" max="255" value="255" class="slider" id="grn0">
      <output id="grnO"></output>
    </fieldset>

    <fieldset class="slidecontainer">
      <legend>Blue</legend>
      <input type="range" min="0" max="255" value="255" class="slider" id="blu0">
      <output id="bluO"></output>
    </fieldset>

  </form>
  <script>
    //Reference the form
    var form = document.forms.rgb;
    //Reference all of form's form controls
    var rgb = form.elements;
    //Register input event on form
    form.addEventListener('input', composeColor);

    // Callback function pass Event Object
    function composeColor(e) {
      //if the node interacting with user is type=range...
      if (e.target.type === "range") {
        // Reference active range
        var rng = e.target;
        // Get range's "little brother" output 
        var viewVal = rng.nextElementSibling;
        // Sync their values
        viewVal.value = rng.value;
        // Collect the values of all ranges then interpolate them
        // into a template literal.
        // The TL is the color of body
        document.body.style.background = `rgb(${red0.value}, ${grn0.value}, ${blu0.value})`;
      } else return false;
    }
  </script>
</body>

</html>

演示2

On Event Attribute

form {
  display: flex;
  flex-flow: column wrap;
  height: 100vh;
}

.slidecontainer {
  width: 40%;
  height: 15vh
}

output {
  transform: translate(5px, -7px);
  display: inline-block;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <form id='rgb' oninput="document.body.style.background = `rgb(${red0.value},${grn0.value}, ${blu0.value})`">

    <fieldset class="slidecontainer">
      <legend>Red</legend>
      <input type="range" min="0" max="255" value="255" class="slider" id="red0" oninput='redO.value = this.value'>
      <output id="redO" for='red0'></output>
    </fieldset>

    <fieldset class="slidecontainer">
      <legend>Green</legend>
      <input type="range" min="0" max="255" value="255" class="slider" id="grn0" oninput='grnO.value = this.value'>
      <output id="grnO" for='grn0'></output>
    </fieldset>

    <fieldset class="slidecontainer">
      <legend>Blue</legend>
      <input type="range" min="0" max="255" value="255" class="slider" id="blu0" oninput='bluO.value = this.value'>
      <output id="bluO" for='blu0'></output>
    </fieldset>

  </form>
  <script>
  
  </script>
  </body>
  </html>