【问题标题】:How to beat a JavaScript condition riddle?如何破解 JavaScript 条件谜题?
【发布时间】:2017-09-01 05:47:13
【问题描述】:

我在 php 中使用 foreach 循环从 mysql 表中加载数据。我正在使用从数据库加载的数据 ID 并将其应用于按钮值。

按钮有两种颜色,绿色和白色。按钮代表喜欢 cmets 或帖子的喜欢。

现有的总点赞数从 6 开始(div id="total")

白色按钮

如果按钮 1 的颜色为白色并且您点击它,总喜欢 (6) 将增加 1。如果您再次点击按钮 1,总喜欢 (7) 将减少 1。

如果单击按钮 1、按钮 2 和按钮 3,总喜欢 (6) 会增加 3(每个按钮 1)。如果再次点击按钮 1、按钮 2 和按钮 3,总点赞数(9)将减少 3。

谜题

绿色按钮

我是怎么做到的,当点击一个绿色按钮时,总数(6)减少1,如果再次点击按钮,它应该增加1。与白色按钮不同。

如果单击绿色按钮 3、5 和 6,则总数 (6) 应减少 3。如果再次单击相同的按钮,则总数 (6) 将增加 3。

这是我的代码

var colorcode = "rgb(116, 204, 49)";
var buttonid = str;
var elem = document.getElementById(buttonid);
var theCSSprop = window.getComputedStyle(elem, null).getPropertyValue("background-color");

var initialtotal = parseInt(document.getElementById("total").innerHTML, 10);
var likes = new Array();

function showUser(str) {
  ////// 1st condition /////
  if (theCSSprop == colorcode) {

    if (likes[value] == 0 || !likes[value]) {
      likes[value] = 1;
    } else {
      likes[value] = 0;
    }
    var sum = 0;
    for (i = 0; i < likes.length; i++) {
      if (likes[i] == 1) {
        sum--
      }
    }

  }
  ////// 2nd condition /////
  else {
    if (likes[str] == 0 || !likes[str]) {
      likes[str] = 1;
    } else {
      likes[str] = 0;
    }

    var sum = 0;
    for (i = 0; i < likes.length; i++) {
      if (likes[i] == 1) {
        sum++
      }
    }

  }
  var tot = initialtotal + sum;

  document.getElementById("total").innerHTML = tot;

}
<div id="total" style="width:100px;padding:50px 0px; background-color:whitesmoke;text-align:center;">6 </div>

<!---------------------------------------------------------------------------------------------------------------------->
<button id="5" value="5" onclick="showUser(this.value)">LIKE </button>

<button id="346" value="346" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>

<button id="128" value="128" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>

<button id="687" value="687" onclick="showUser(this.value)">LIKE </button>

<button id="183" value="183" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>

<button id="555" value="555" onclick="showUser(this.value)">LIKE </button>
<!---------------------------------------------------------------------------------------------------------------------->

【问题讨论】:

  • 我在这里没有看到任何问题。
  • 我看到你所有的按钮都共享相同的id... ID 应该是唯一的!
  • @Barma 我编辑了帖子并提出了一个问题。我正在尝试使绿色按钮减少总值。
  • 抱歉,按钮 id 与按钮的值相同,我现在改一下
  • 在设置str 之前在哪里设置var buttonid = str;

标签: javascript


【解决方案1】:

不要将this.value 传递给showUser(),而是传递this。这样,该函数可以直接获取值和样式,而无需调用 getElementById()(您没有传递 ID)。然后你需要在函数内部设置theCSSprop,所以它是当前按钮的属性。

要使绿色按钮从递增到递减交替方向,您需要一个全局变量来记住上次调用该函数时它做了什么。

另外,你不需要写if(likes[str] == 0 || !likes[str]),因为0 是faley。写if(!likes[str])就行了。

var colorcode = "rgb(116, 204, 49)";

var likes = new Array();
var greenIncr = -1;

function showUser(elem) {
  var initialtotal = parseInt(document.getElementById("total").innerHTML, 10);
  ////// 1st condition /////
  var str = elem.value;
  var theCSSprop = window.getComputedStyle(elem, null).getPropertyValue("background-color");
  if (theCSSprop == colorcode) {

    if (!likes[str]) {
      likes[str] = 1;
    } else {
      likes[str] = 0;
    }
    var sum = 0;
    for (i = 0; i < likes.length; i++) {
      if (likes[i] == 1) {
        sum += greenIncr;
      }
    }
    greenIncr = -greenIncr; // revese the direction of green button

  }
  ////// 2nd condition /////
  else {
    if (!likes[str]) {
      likes[str] = 1;
    } else {
      likes[str] = 0;
    }

    var sum = 0;
    for (i = 0; i < likes.length; i++) {
      if (likes[i] == 1) {
        sum++
      }
    }

  }
  var tot = initialtotal + sum;

  document.getElementById("total").innerHTML = tot;

}
<div id="total" style="width:100px;padding:50px 0px; background-color:whitesmoke;text-align:center;">6 </div>

<!---------------------------------------------------------------------------------------------------------------------->
<button id="5" value="5" onclick="showUser(this)">LIKE </button>

<button id="346" value="346" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>

<button id="128" value="128" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>

<button id="687" value="687" onclick="showUser(this)">LIKE </button>

<button id="183" value="183" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>

<button id="555" value="555" onclick="showUser(this)">LIKE </button>
<!---------------------------------------------------------------------------------------------------------------------->

【讨论】:

  • 感谢您的出色想法。但是,如果单击赞按钮 1,则总数会增加 1。如果单击相同的赞按钮,则总数必须减少。现在,如果您单击相同的按钮两次,该值会不断增加并且不会反转。谢谢
  • 我不太明白你在用 likes 数组做什么。
  • 我正在使用 like 数组来存储多个按钮 ID。如果我们有按钮 1、2 和 3,并且单击按钮 1 的 2 和 3,则单击按钮 1,like 数组用于从总喜欢中减少特定按钮 id
  • 如果你还想帮忙的话,我可以做个插图解释一下吗?
【解决方案2】:

第一个简单的实现可能如下所示

class Counter {
  constructor(initial) {
    this.initial = initial
    this.white = [false, false, false]
    this.green = [false, false, false]
  }

  changeGreen(index) {
    this.green[index] = !this.green[index]
  }

  changeWhite(index) {
    this.white[index] = !this.white[index]
  }

  get total() {
    return this.initial + this.white.reduce((total, current) => total + current, 0) + this.green.reduce((total, current) => total - current, 0)
  }
}

let counter = new Counter(6)

const render = counter => {
  document.querySelector('#total').innerHTML = counter.total
}

render(counter)

;['#first', '#second', '#third'].map((selector, index) => {
  document.querySelector(selector).addEventListener('click', e => {
    e.target.classList.toggle('pressed')
    counter.changeWhite(index)
    render(counter)
  })
})

;['#fourth', '#fifth', '#sixth'].map((selector, index) => {
  document.querySelector(selector).addEventListener('click', e => {
    e.target.classList.toggle('pressed')
    counter.changeGreen(index)
    render(counter)
  })
})
.green {
  background: #00aa00
}

.pressed {
  border-style: inset
}
<div id="total">0</div>

<p>
  <button id="first">First</button>
  <button id="second">Second</button>
  <button id="third">Third</button>
  <button id="fourth" class="green">Fourth</button>
  <button id="fifth" class="green">Fifth</button>
  <button id="sixth" class="green">Sixth</button>
</p>

但毕竟我已经完成了类似的事情

class Counter {
  constructor(initial, strategy) {
    this.initial = initial;
    this.elements = [];
    this.strategy = typeof strategy === 'function' ? strategy : () => {}
  }

  addElement(content, type, next) {
    const element = {
      content: content,
      type: type,
      state: false
    };
    this.elements.push(element);
    return next(element, this.elements.length - 1);
  }

  toggleElementState(index) {
    this.elements[index].state = !this.elements[index].state
  }

  get total() {
    return this.strategy(this.initial, this.elements)
  }
}

const initialize = () => {

  Counter.WHITE = Symbol('white');
  Counter.GREEN = Symbol('green');

  const counter = new Counter(6, (initial, buttons) => {
    return initial +
      buttons.filter(button => button.type === Counter.WHITE).reduce((total, current) => total + Number(current.state), 0) +
      buttons.filter(button => button.type === Counter.GREEN).reduce((total, current) => total - Number(current.state), 0)
  });

  const render = counter => {
    document.querySelector('#total').innerHTML = counter.total
  };

  const createButton = (element, index) => {
    const button = document.createElement('button');
    button.setAttribute('data-id', index);
    button.classList.add(element.type === Counter.GREEN ? 'green' : 'none');
    button.textContent = element.content;
    document.querySelector('#buttons').appendChild(button)
  };

  const addButton = (type, ...selectors) => {
    selectors.forEach(selector => counter.addElement(selector, type, createButton));
  };

  render(counter);

  addButton(Counter.WHITE, '#first', '#second', '#third');
  addButton(Counter.GREEN, '#fourth', '#fifth', '#sixth');
  addButton(Counter.WHITE, '#first', '#second', '#third');

  document.querySelector('#buttons').addEventListener('click', function(e) {
    e.target.classList.toggle('pressed');
    counter.toggleElementState(parseInt(e.target.dataset.id));
    render(counter)
  })

};

document.addEventListener('DOMContentLoaded', initialize);
.green {
  background: #00aa00
}

.pressed {
  border-style: inset
}
<div id="total">0</div>

<p id="buttons">
</p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2018-07-07
    • 2011-07-26
    相关资源
    最近更新 更多