无法从HTML元素中删除添加类

时间:2022-11-22 23:16:34

I have three coloured buttons. When I pick a button, I want it to be selected, and the other two to be deselected. red, blue and yellow are objects with the property isSelected set to true or false. I can select one button once, setting isSelected to true for that button. However, I can't seem to select a new button and deselect the current one.

我有三个彩色按钮。当我选择一个按钮时,我希望它被选中,另外两个被取消选择。红色,蓝色和黄色是属性isSelected设置为true或false的对象。我可以选择一个按钮,为该按钮设置isSelected为true。但是,我似乎无法选择一个新按钮并取消选择当前按钮。

(I know I can do this with jQuery easily... but I'm trying to learn how to use Javascript objects here...)

(我知道我可以轻松地使用jQuery做到这一点......但我正在尝试学习如何在这里使用Javascript对象......)

The code below doesn't run, it's the bits I think are relevant to the problem without the HTML and CSS. The app is on CodePen: http://codepen.io/isachenx/pen/LxEOOR

下面的代码没有运行,这是我认为与没有HTML和CSS的问题相关的位。该应用程序在CodePen上:http://codepen.io/isachenx/pen/LxEOOR

My idea is to set isSelected to true or false for each of the selectors. If isSelected is true, I add the class .selected to the html string, if it's false, the string does not include the class. I then re-render (at least that's what I think I'm doing) the string every time the li element is clicked...

我的想法是为每个选择器设置isSelected为true或false。如果isSelected为true,我将类.selected添加到html字符串,如果它为false,则该字符串不包含该类。每次点击li元素时,我会重新渲染(至少我认为我正在做的事情)字符串...

    //create constructor
    function Selector(colour){
      this.colour = colour
      this.isSelected = false
    }

    //set method to select and deselect the list items
    Selector.prototype.selectColour = function(){
      this.isSelected = true
    }

    Selector.prototype.deselectColour = function(){
      this.isSelected = false
    }

    //render the string for the list item to HTML 
    Selector.prototype.toHTML = function(){
      let htmlString = ""
      htmlString += '<li id="' + this.colour + '" class="' + this.colour
      if (this.isSelected){
        htmlString += ' selected'
      }
      htmlString += '"></li>'
      return htmlString
    }
    
    //Constructor to render every list item to html
    function Controls(){
      this.selectors = []
    }

    Controls.prototype.add = function(selector){
      this.selectors.push(selector)
    }

    Controls.prototype.renderInElement = function(list){
      list.innerHTML = ''
      for (let i=0; i<this.selectors.length; i++){
        list.innerHTML += this.selectors[i].toHTML()
      }
    }

    let controls = new Controls

    let red = new Selector('red')
    let blue = new Selector('blue')
    let yellow = new Selector('yellow')

    controls.add(red)
    controls.add(blue)
    controls.add(yellow)

    let controlElement = document.getElementById('controlButtons')
    controls.renderInElement(controlElement)

    let redButton = document.getElementById('red')
    redButton.onclick = function(){
      red.selectColour()
      blue.deselectColour()
      yellow.deselectColour()
      controls.renderInElement(controlElement)
    }

    let blueButton = document.getElementById('blue')
    blueButton.onclick = function(){
      blue.selectColour()
      red.deselectColour()
      yellow.deselectColour()
      controls.renderInElement(controlElement)
    }

    let yellowButton = document.getElementById('yellow')
    yellowButton.onclick = function(){
      yellow.selectColour()
      red.deselectColour()
      blue.deselectColour()
      controls.renderInElement(controlElement)
    }

2 个解决方案

#1


1  

By your code, a second click on either button does not work. The reason is that onclick is set only for the first time.

根据您的代码,再次单击任一按钮都不起作用。原因是onclick只是第一次设置。

Your toHTML function clears the existing buttons (line 33: list.innerHTML = ''), as a result clears their onclick events. You have to set them again inside toHTML.

你的toHTML函数清除了现有的按钮(第33行:list.innerHTML =''),结果清除了它们的onclick事件。你必须在toHTML中再次设置它们。

Like so:

像这样:

Selector.prototype.toHTML = function(){

  // set the on click function to the desired color
  let onclickStr = 'setOnClick(\'' + this.colour + '\')';

  let htmlString = ""
  htmlString += '<li id="' + this.colour + '" class="' + this.colour
  if (this.isSelected){
    htmlString += ' selected'
  }

  // Note the following change
  htmlString += '" onclick="' + onclickStr + '"></li>'
  return htmlString
}

Then, wrap your xxxbutton.onclick functions with:

然后,使用以下命令包装xxxbutton.onclick函数:

function setOnClick(color) {
  let redButton = document.getElementById('red')
  let blueButton = document.getElementById('blue')
  let yellowButton = document.getElementById('yellow')
  if(color==='red'){    
    red.selectColour()
    blue.deselectColour()
    yellow.deselectColour()
  }else if(color==='blue'){
    blue.selectColour()
    red.deselectColour()
    yellow.deselectColour()
  }else{
    yellow.selectColour()
    red.deselectColour()
    blue.deselectColour()
  }
  controls.renderInElement(controlElement)
}

JSFIDDLE DEMO

JSFIDDLE DEMO

#2


1  

Setting isSelected to true or false doesn't change the class on the DOM element. To add/remove a class:

将isSelected设置为true或false不会更改DOM元素上的类。添加/删除类:

var colourObj = document.querySelector(colour);
colourObj.classList.add('selected');
//or to remove a class
colourObj.classList.remove('selected');

#1


1  

By your code, a second click on either button does not work. The reason is that onclick is set only for the first time.

根据您的代码,再次单击任一按钮都不起作用。原因是onclick只是第一次设置。

Your toHTML function clears the existing buttons (line 33: list.innerHTML = ''), as a result clears their onclick events. You have to set them again inside toHTML.

你的toHTML函数清除了现有的按钮(第33行:list.innerHTML =''),结果清除了它们的onclick事件。你必须在toHTML中再次设置它们。

Like so:

像这样:

Selector.prototype.toHTML = function(){

  // set the on click function to the desired color
  let onclickStr = 'setOnClick(\'' + this.colour + '\')';

  let htmlString = ""
  htmlString += '<li id="' + this.colour + '" class="' + this.colour
  if (this.isSelected){
    htmlString += ' selected'
  }

  // Note the following change
  htmlString += '" onclick="' + onclickStr + '"></li>'
  return htmlString
}

Then, wrap your xxxbutton.onclick functions with:

然后,使用以下命令包装xxxbutton.onclick函数:

function setOnClick(color) {
  let redButton = document.getElementById('red')
  let blueButton = document.getElementById('blue')
  let yellowButton = document.getElementById('yellow')
  if(color==='red'){    
    red.selectColour()
    blue.deselectColour()
    yellow.deselectColour()
  }else if(color==='blue'){
    blue.selectColour()
    red.deselectColour()
    yellow.deselectColour()
  }else{
    yellow.selectColour()
    red.deselectColour()
    blue.deselectColour()
  }
  controls.renderInElement(controlElement)
}

JSFIDDLE DEMO

JSFIDDLE DEMO

#2


1  

Setting isSelected to true or false doesn't change the class on the DOM element. To add/remove a class:

将isSelected设置为true或false不会更改DOM元素上的类。添加/删除类:

var colourObj = document.querySelector(colour);
colourObj.classList.add('selected');
//or to remove a class
colourObj.classList.remove('selected');