如何通过按下按钮使不透明度停止褪色?

How do I get the opacity to stop fading with a button press?

目前我的线条不透明度每 400 毫秒降低 3%。我希望此功能继续,但我还想创建一个按钮按下功能,一旦用户按下按钮,褪色就会停止,并且可以记录褪色停止时的不透明度。非常感谢!

const step = 0.03

// Helper function to extract the stimulus elements
const getLines = () => 
  ['one', 'two', 'five', 'fourteen', 'fifteen']
    .map(id => document.getElementById(id))

getLines().forEach(line => line.style.opacity = 1);

// Setup event handler
var timer = undefined;
function decreaseOpacity() {
  getLines().forEach(line => {
        line.style.opacity -= step
        console.log(line.style.opacity);
  });
  timer = setTimeout(() => {
    decreaseOpacity();
  }, 400);
}
decreaseOpacity();

您可以使用clearTimeout(timer)来停止计时器。我使用了一个额外的变量来存储不透明度以便于访问。它可以像这样工作。我试着猜你的台词会是什么样子,但它可能是错误的(笑)...

const step = 0.03

// Helper function to extract the stimulus elements
const getLines = () => 
  ['one', 'two', 'five', 'fourteen', 'fifteen']
    .map(id => document.getElementById(id))

getLines().forEach(line => line.style.opacity = 1);

// Setup event handler
var timer = undefined;
var opac = 1;
function decreaseOpacity() {
  opac -= step;
  if (opac>0) {
    getLines().forEach(line => {
      line.style.opacity -= step
      //console.log(line.style.opacity);
    });
    timer = setTimeout(() => {
      decreaseOpacity();
    }, 400);
  }
}
decreaseOpacity();

document.getElementById("stopButton").onclick=e=>{
clearTimeout(timer);
e.target.value=opac;
}
.line {margin:30px;line-height:0;font-size:0;border-bottom:1px solid black;}
#two {border-bottom-width:2px;}
#five {border-bottom-width:5px;}
#fourteen {border-bottom-width:14px;}
#fifteen {border-bottom-width:15px;}
<input type="button" id="stopButton" value="Stop">
<div id="one" class="line"></div>
<div id="two" class="line"></div>
<div id="five" class="line"></div>
<div id="fourteen" class="line"></div>
<div id="fifteen" class="line"></div>

答案:

您可以创建构造函数来将按钮方法和计时器绑定在一起:

function FadeMechanic(element) {
  let proto = {};
  proto.start = function() {
    proto.timer = setInterval(function() {
      element.style.opacity = getComputedStyle(element).opacity - .1;
    }, 1000);
  }
  proto.stop = function() {
    clearInterval(proto.timer);
    console.log(element.style.opacity);
  }
  return proto;
}

示例:

let el = document.querySelector.bind(document),
  start = el("#start"),
  stop = el("#stop"),
  target = el("#fader");

function FadeMechanic(element) {
  let proto = {};
  proto.start = function() {
    proto.timer = setInterval(function() {
      element.style.opacity = getComputedStyle(element).opacity - .1;
    }, 1000);
  }
  proto.stop = function() {
    clearInterval(proto.timer);
    console.log(element.style.opacity);
  }
  return proto;
}

let fader = FadeMechanic(target);
start.addEventListener("click", fader.start);
stop.addEventListener("click", fader.stop);
section {
  width: 100px;
  height: 100px;
  background: black;
  opacity: 1;
}
<button id="start">start</button>
<button id="stop">stop</button>
<section id="fader"></section>


扩展为多个:

由于我们的构造函数可以与一个元素一起使用,我们只需为多个元素创建一个包装器:

function FadeController(elements) {
  let proto = {};
  proto.elements = elements.map(FadeMechanic);
  proto.start = () => proto.elements.forEach(element => element.start());
  proto.record = [];
  proto.stop = () => proto.record.push(proto.elements.map(element => element.stop())[0]);

  proto.stopAndPrintRecord = () =>( proto.stop(), console.log(proto.record) );
  return proto;
}

这也允许我们存储 record 当前和之前停止的不透明度。


示例:

let el = document.querySelector.bind(document),
  start = el("#start"),
  stop = el("#stop"),
  targets = [el("#fader"), el("#fader2")];

function FadeMechanic(element) {
  let proto = {};
  proto.start = function() {
    proto.timer = setInterval(function() {
      element.style.opacity = getComputedStyle(element).opacity - .1;
    }, 1000);
  }
  proto.stop = function() {
    clearInterval(proto.timer);
    return element.style.opacity;
  }
  return proto;
}

function FadeController(elements) {
  let proto = {};
  proto.elements = elements.map(FadeMechanic);
  proto.start = () => proto.elements.forEach(element => element.start());
  proto.record = [];
  proto.stop = () => proto.record.push(proto.elements.map(element => element.stop())[0]);

  proto.stopAndPrintRecord = () =>( proto.stop(), console.log(proto.record) );
  return proto;
}

let fader = FadeController(targets);
start.addEventListener("click", fader.start);
stop.addEventListener("click", fader.stopAndPrintRecord);
section {
  width: 100px;
  height: 100px;
  background: black;
  opacity: 1;
  border: 1px solid grey;
}
<button id="start">start</button>
<button id="stop">stop</button>
<section id="fader"></section>
<section id="fader2"></section>


使用您的代码:

const step = 0.03,
click = (sel, fn) => document.querySelector(sel).addEventListener("click", fn),

// Helper function to extract the stimulus elements
  getLines = () => ['one', 'two', 'five']
  .map(id => document.getElementById(id))

function FadeMechanic(element) {
  let proto = {};
  proto.start = function() {
    proto.timer = setInterval(function() {
      element.style.opacity = getComputedStyle(element).opacity - step;
    }, 400);
  }
  proto.stop = function() {
    clearInterval(proto.timer);
    return element.style.opacity;
  }
  return proto;
}

function FadeController(elements) {
  let proto = {};
  proto.elements = elements.map(FadeMechanic);
  proto.start = () => proto.elements.forEach(element => element.start());
  proto.record = [];
  proto.stop = () => proto.record.push(proto.elements.map(element => element.stop())[0]);
  proto.stopAndPrintRecord = () =>( proto.stop(), console.log(proto.record) );
  return proto;
}

const lineFader = FadeController(getLines());

click("#start", lineFader.start);
click("#stop", lineFader.stopAndPrintRecord);
<span id="one">one</span>
<span id="two">two</span>
<span id="three">three</span>
<span id="four">four</span>
<span id="five">five</span>

<button id="start">Start</button>
<button id="stop">Stop</button>

您需要清除点击时的超时才能使其停止。

function stopTimeout(e) {
  clearTimeout(timer);
  opacity_level = e.target.style.opacity;
}

document.getElementById("#somebutton").onclick = stopTimeout()