如何在CSS中更改变量的颜色?

时间:2020-09-10 00:48:56

标签: javascript html css

我只想 computerScoreplayerScore中的数字来更改颜色。在CSS中可以做到这一点吗?

function computerPlay(){
  let values = ['Rock', 'Paper', 'Scissors'],
  valueToUse = values [Math.floor(Math.random()* values.length)];
  return valueToUse;
};

const rock = document.querySelector('#rock');
const paper = document.querySelector('#paper');
const scissors = document.querySelector('#scissors');
let computerSelection = document.querySelector('.computerSelection');
let result = document.querySelector('.result');
let score = document.querySelector('.computerScore', computerScore = 0, 'playerScore', playerScore = 0);


rock.addEventListener('click', pickRock) 

function pickRock() { 
  let comp = computerPlay()//the variable comp had to be created. Otherwirse, if I use computerPlay() in if statements, sometimes the text content would not appear. See stackoverflow comment.
  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"
    score.textContent = `Computer Score: ${computerScore +=0} Your Score: ${playerScore +=0}`
    
  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";
    score.textContent = `Computer Score: ${computerScore +=1} Your Score: ${playerScore +=0}`
    
  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";
    score.textContent = `Computer Score: ${computerScore +=0} Your Score: ${playerScore +=1}`
  }
};
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My javascript</title>
    <link rel="stylesheet" href="javascript.css">
  </head>
  <body>
    <main>
    <div class="wrapper">
      <h1>Rock, Paper, Scissors!</h1>
      <h3>Instructions:</h3>
      <p>You will be playing against the computer. There will be a total of 3 rounds. Good luck!</p>
      <h2 id="choose">Choose:</h2>
    </div>
    <div class="container">
      <button>
        <img id="rock" src="https://static.thenounproject.com/png/477914-200.png">
      </button>
    </div>
    <div class="wrapper">
      <p class='computerSelection'></p>
      <p class='result'></p>
      <p class='computerScore'></p>
      <p class='playerScore'></p>
      <p class='finalResult'></p>
    </main>
    <script src="javascript.js"></script>
</html>

2 个答案:

答案 0 :(得分:2)

您可以设置元素的innerHTML,并在应用CSS的得分周围添加span标签。

例如:

score.innerHTML = `Computer Score: <span style="color:red;">${++computerScore}</span> Your Score: <span style="color:blue;">${playerScore}</span>`

您还可以使用类:

score.innerHTML = `Computer Score: <span class="computer-score">${++computerScore}</span> Your Score: <span class="player-score">${playerScore}</span>`

答案 1 :(得分:1)

首先是,您在结束</div>标记之前缺少结束</main>标记。在下面的示例中,该错误/典型错误已得到解决。

由于您不熟悉JavaScript(可能还包括HTML和CSS),因此我将尝试相对缓慢且分阶段地解决这一问题。解决“简单问题”时,我要做的第一件事是整理演示文稿,然后向您展示一种减少页面上要更新的内容量的方法

我将要实现的演示文稿更改主要是为了减少上下滚动,以便更轻松地可视化正在发生的事情和更改。为此,我们将使用CSS Grid和以下CSS:

/* We use the universal selector ('*') to select all elements on
   the page, and also we select all of the ::before and ::after
   pseudo-elements; here we reset margin and padding to a known
   default (what the default is doesn't matter, just that you know
   what it is), and set all matching elements to the border-box
   means of box-sizing: */
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  /* We use CSS grid to layout the contents of the <main> element: */
  display: grid;
  /* We define a two-column layout, using the repeat() function, with
     each column taking one fractional unit of the available space: */
  grid-template-columns: repeat(2, 1fr);
  /* We define the width - using the CSS clamp() function as being
     50vw (fifty percent of the width of the viewport, with a
     minimum size of 200px and a maximum size of 600px: */
  width: clamp(200px, 50vw, 600px);
  /* A 1em top and bottom margin, with margin auto for left and right,
     this automatically centers the <main> element within its parent
     container: */
  margin: 1em auto;
  /* defining a gap between the grid-items (the child elements within
     an element set to display: grid); this also applies to elements 
     that are children of 'display: flex' elements: */
  gap: 0.5em;
}

.wrapper {
  /* places the element in the first column of the defined grid,
     and extending it to the last column of that defined grid: */
  grid-column: 1 / -1;
  text-align: center;
}

.container {
  /* anticipating at least two other elements to be added to this
     element ('scissors' and 'paper', unless you're playing 'rock,
     paper, scissors, lizard, Spock') so setting up the container
     to accept, and lay out, more elements automatically and
     predictably: */
  display: flex;
  /* allowing the flex-item elements to wrap into a new row (or
     column) if necessary: */
  flex-wrap: wrap;
  /* flex-items will be laid out spaced evenly with space between
     the elements and their parent-element's boundaries: */
  justify-content: space-around;
}

.container button {
  /* to show interactivity on hover: */
  cursor: pointer;
}

.results::before {
  /* using CSS generated content to display a header/title/hint
     as to what the element is for: */
  content: "Results: ";
  display: block;
  font-size: 1.2em;
  border-bottom: 2px solid #000;
}

function computerPlay() {
  let values = ['Rock', 'Paper', 'Scissors'],
    valueToUse = values[Math.floor(Math.random() * values.length)];
  return valueToUse;
};

const rock = document.querySelector('#rock');
const paper = document.querySelector('#paper');
const scissors = document.querySelector('#scissors');
let computerSelection = document.querySelector('.computerSelection');
let result = document.querySelector('.result');
let score = document.querySelector('.computerScore', computerScore = 0, 'playerScore', playerScore = 0);


rock.addEventListener('click', pickRock)

function pickRock() {
  let comp = computerPlay() //the variable comp had to be created. Otherwirse, if I use computerPlay() in if statements, sometimes the text content would not appear. See stackoverflow comment.
  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"
    score.textContent = `Computer Score: ${computerScore +=0} Your Score: ${playerScore +=0}`

  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";
    score.textContent = `Computer Score: ${computerScore +=1} Your Score: ${playerScore +=0}`

  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";
    score.textContent = `Computer Score: ${computerScore +=0} Your Score: ${playerScore +=1}`
  }
};
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  width: clamp(200px, 50vw, 600px);
  margin: 1em auto;
  gap: 0.5em;
}

.wrapper {
  grid-column: 1 / -1;
  text-align: center;
  background-color: #f903;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.container button {
  cursor: pointer;
}

.results::before {
  content: "Results: ";
  display: block;
  font-size: 1.2em;
  border-bottom: 2px solid #000;
}
<main>
  <div class="wrapper">
    <h1>Rock, Paper, Scissors!</h1>
    <h3>Instructions:</h3>
    <p>You will be playing against the computer. There will be a total of 3 rounds. Good luck!</p>
    <h2 id="choose">Choose:</h2>
  </div>
  <div class="container">
    <button>
      <img id="rock" src="https://static.thenounproject.com/png/477914-200.png">
    </button>
  </div>
  <!-- The following <div> was changed from div.wrapper to div.results,
       since while it remains a wrapping element, its role is different:
       it exists to present the results or outcome. Name your components
       appropriately and meaningfully, that way maintenance becomes easier
       because you know where to look and what each section is for -->
  <div class="results">
    <p class='computerSelection'></p>
    <p class='result'></p>
    <p class='computerScore'></p>
    <p class='playerScore'></p>
    <p class='finalResult'></p>
  </div>
</main>

JS Fiddle demo

接下来,我们将整理JavaScript并更正似乎是您的代码错误的内容;首先,所有不会更改的变量都将用const声明(您的代码中混合了constlet),我们将修复{ {1}}:

document.querySelector()

我可以理解一下您的意图,即它应该在初始化相关变量时以某种方式选择let score = document.querySelector('.computerScore', computerScore = 0, 'playerScore', playerScore = 0); p.computerScore元素;但是,尽管变量已初始化(这与我的预期很不符),p.playerScore会&ndash和 can –只会返回一个元素节点或document.querySelector()。这种误解的结果是,您只更新过null元素的文本内容,而没有按照HTML的意图使用这两个元素。

所以,这就是说:经修改的JavaScript:

p.computerScore

// There was nothing wrong here, except that you initialised
// a variable purely in order to return it in the next line;
// this is a matter of preference and personal taste but I
// removed the variable instantiation and simply returned the
// result directly:
function computerPlay() {
  const values = ['Rock', 'Paper', 'Scissors'];
    return values[Math.floor(Math.random() * values.length)];
}

// You were using document.querySelector() so many times that,
// just to save your fingertips, it was worth defining a
// simple function (using Arrow syntax) to reduce the need to
// repeatedly type a longer method-call; here the function
// dQS() is defined as accepting an 'el' argument and will
// pass that argument to the inner document.querySelector()
// and simply returning the result:
const dQS = (el) => document.querySelector(el),

  // here all the document.querySelector() calls have been
  // changed, and still work perfectly:
  rock = dQS('#rock'),
  paper = dQS('#paper'),
  scissors = dQS('#scissors'),
  computerSelection = dQS('.computerSelection'),
  result = dQS('.result'),
  computerScoreElement = dQS('.computerScore'),
  // you were never getting, and therefore never using, this
  // element in your original code, I assumed - as the paragraph
  // above states - that you meant to, so I changed this around
  // in order that you could:
  playerScoreElement = dQS('.playerScore');

// all preceding variables are constants, but the scores will
// necessarily change therefore we declare with 'let' rather
// than const:
let computerScore = 0,
  playerScore = 0;

rock.addEventListener('click', pickRock)

function pickRock() {
  const comp = computerPlay();

  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"
    // here the score doesn't change, so there's no need
    // to adjust the score; therefore that's been removed.

  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";

    // here only the computerScore variable changes, so we
    // update only that score; we use the increment operator
    // as a prefix because we want to increment the variable
    // and then return it (computerScore++ would return the
    // variable unchanged, and then increment it):
    ++computerScore;

  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";

    // as above:
    ++playerScore;
  }

  // here we update the scores in the elements:
  computerScoreElement.textContent = `Computer: ${computerScore}`;
  playerScoreElement.textContent = `Player: ${playerScore}`;
}
function computerPlay() {
  const values = ['Rock', 'Paper', 'Scissors'];
  return values[Math.floor(Math.random() * values.length)];
}

const dQS = (el) => document.querySelector(el),
  rock = dQS('#rock'),
  paper = dQS('#paper'),
  scissors = dQS('#scissors'),
  computerSelection = dQS('.computerSelection'),
  result = dQS('.result'),
  computerScoreElement = dQS('.computerScore'),
  playerScoreElement = dQS('.playerScore');
let computerScore = 0,
  playerScore = 0;

rock.addEventListener('click', pickRock)

function pickRock() {
  const comp = computerPlay();

  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"

  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";
    ++computerScore;

  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";
    ++playerScore;
  }

  computerScoreElement.textContent = `Computer: ${computerScore}`;
  playerScoreElement.textContent = `Player: ${playerScore}`;
}
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  width: clamp(200px, 50vw, 600px);
  margin: 1em auto;
  gap: 0.5em;
}

.wrapper {
  grid-column: 1 / -1;
  text-align: center;
  background-color: #f903;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.container button {
  cursor: pointer;
}

.results::before {
  content: "Results: ";
  display: block;
  font-size: 1.2em;
  border-bottom: 2px solid #000;
}

因此,现在,尽管我们对JavaScript进行了一些改进,但仍然存在您提出的问题:如何在不更改所有文本颜色的情况下轻松为乐谱着色?

有两种显而易见的方法(并且<main> <div class="wrapper"> <h1>Rock, Paper, Scissors!</h1> <h3>Instructions:</h3> <p>You will be playing against the computer. There will be a total of 3 rounds. Good luck!</p> <h2 id="choose">Choose:</h2> </div> <div class="container"> <button> <img id="rock" src="https://static.thenounproject.com/png/477914-200.png"> </button> </div> <div class="results"> <p class='computerSelection'></p> <p class='result'></p> <p class='computerScore'></p> <p class='playerScore'></p> <p class='finalResult'></p> </div> </main>的使用并不真正明智,因为每次调用innerHTML函数时都要销毁并重新创建DOM的一部分。< / p>

第一种方法是在HTML中使用嵌套元素,例如pickRock(),第二种方法是使用CSS生成的内容(以两种不同方式之一)。

因此,使用嵌套的<span>(其他元素可用),只需进行三个更改:

  • 在JavaScript中调整选择器,
  • 更新CSS以设置<span>元素的样式,并且
  • 插入相关的HTML。

<span>
function computerPlay() {
  const values = ['Rock', 'Paper', 'Scissors'];
  return values[Math.floor(Math.random() * values.length)];
}

const dQS = (el) => document.querySelector(el),
  rock = dQS('#rock'),
  paper = dQS('#paper'),
  scissors = dQS('#scissors'),
  computerSelection = dQS('.computerSelection'),
  result = dQS('.result'),
  // note the adjusted selectors below, selecting a
  // <span> which is the direct child of the '.computerScore'
  // element, and likewise with the '.playerScore':
  computerScoreElement = dQS('.computerScore > span'),
  playerScoreElement = dQS('.playerScore > span');
let computerScore = 0,
  playerScore = 0;

rock.addEventListener('click', pickRock)

function pickRock() {
  const comp = computerPlay();

  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"

  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";
    ++computerScore;

  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";
    ++playerScore;
  }

  computerScoreElement.textContent = computerScore;
  playerScoreElement.textContent = playerScore;
}
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  width: clamp(200px, 50vw, 600px);
  margin: 1em auto;
  gap: 0.5em;
}

.wrapper {
  grid-column: 1 / -1;
  text-align: center;
  background-color: #f903;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.container button {
  cursor: pointer;
}

.results::before {
  content: "Results: ";
  display: block;
  font-size: 1.2em;
  border-bottom: 2px solid #000;
}

/* The CSS to style the relevant <span> elements, obviously
   they're both the same here but equally obviously they
   can be adjusted individually to your preference: */
.computerScore > span,
.playerScore > span {
  color: darkblue;
  font-weight: 900;
}
/* Here we use generated content to insert a starting value of
   zero if - and only if - there is no content at all in the
   relevant element; no white-space, no descendants, no text;
   so as soon as there is any textContent inserted into the span
   it ceases to match the :empty selector and therefore the
   ::before element no longer shows: */
.computerScore > span:empty::before,
.playerScore > span:empty::before {
  content: '0';
}

JS Fiddle demo

另一种方法是仅使用现有元素并使用CSS进行更改-并少量减少JavaScript –

<main>
  <div class="wrapper">
    <h1>Rock, Paper, Scissors!</h1>
    <h3>Instructions:</h3>
    <p>You will be playing against the computer. There will be a total of 3 rounds. Good luck!</p>
    <h2 id="choose">Choose:</h2>
  </div>
  <div class="container">
    <button>
      <img id="rock" src="https://static.thenounproject.com/png/477914-200.png">
    </button>
  </div>
  <div class="results">
    <p class='computerSelection'></p>
    <p class='result'></p>
    <!-- Note the inserted <span> elements below: -->
    <p class='computerScore'>Computer: <span></span></p>
    <p class='playerScore'>Player: <span></span></p>
    <p class='finalResult'></p>
  </div>
</main>
function computerPlay() {
  const values = ['Rock', 'Paper', 'Scissors'];
  return values[Math.floor(Math.random() * values.length)];
}

const dQS = (el) => document.querySelector(el),
  rock = dQS('#rock'),
  paper = dQS('#paper'),
  scissors = dQS('#scissors'),
  computerSelection = dQS('.computerSelection'),
  result = dQS('.result'),
  computerScoreElement = dQS('.computerScore'),
  playerScoreElement = dQS('.playerScore');
let computerScore = 0,
  playerScore = 0;

rock.addEventListener('click', pickRock)

function pickRock() {
  const comp = computerPlay();

  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"

  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";
    ++computerScore;

  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";
    ++playerScore;
  }
  // here we've reduced the text we're inserting into the document to
  // just the variable:
  computerScoreElement.textContent = computerScore;
  playerScoreElement.textContent = playerScore;
}
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  width: clamp(200px, 50vw, 600px);
  margin: 1em auto;
  gap: 0.5em;
}

.wrapper {
  grid-column: 1 / -1;
  text-align: center;
  background-color: #f903;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.container button {
  cursor: pointer;
}

.results::before {
  content: "Results: ";
  display: block;
  font-size: 1.2em;
  border-bottom: 2px solid #000;
}

.computerScore,
.playerScore {
  /* styles the color of all the content, but includes the
     score color: */
  color: #000;
}

.computerScore::before {
  content: 'Computer score: ';
  /* styles the color of the CSS generated content,
     overriding the color defined above: */
  color: orange;
}

.playerScore::before {
  content: 'Player score: ';
  /* styles the color of the CSS generated content,
     overriding the color defined above: */
  color: red;
}

JS Fiddle demo

进一步,使用更多CSS生成的内容-带有少量CSS自定义属性-我们还可以使用以下方法:

<main>
  <div class="wrapper">
    <h1>Rock, Paper, Scissors!</h1>
    <h3>Instructions:</h3>
    <p>You will be playing against the computer. There will be a total of 3 rounds. Good luck!</p>
    <h2 id="choose">Choose:</h2>
  </div>
  <div class="container">
    <button>
      <img id="rock" src="https://static.thenounproject.com/png/477914-200.png">
    </button>
  </div>
  <div class="results">
    <p class='computerSelection'></p>
    <p class='result'></p>
    <p class='computerScore'></p>
    <p class='playerScore'></p>
    <p class='finalResult'></p>
  </div>
</main>
function computerPlay() {
  const values = ['Rock', 'Paper', 'Scissors'];
  return values[Math.floor(Math.random() * values.length)];
}

const dQS = (el) => document.querySelector(el),
  rock = dQS('#rock'),
  paper = dQS('#paper'),
  scissors = dQS('#scissors'),
  computerSelection = dQS('.computerSelection'),
  result = dQS('.result'),
  computerScoreElement = dQS('.computerScore'),
  playerScoreElement = dQS('.playerScore');
let computerScore = 0,
  playerScore = 0;

rock.addEventListener('click', pickRock)

function pickRock() {
  const comp = computerPlay();

  if (comp === 'Rock') {
    computerSelection.textContent = "Computer's Selection: Rock";
    result.textContent = "It's a Tie!"

  } else if (comp === 'Paper') {
    computerSelection.textContent = "Computer's Selection: Paper";
    result.textContent = "Sorry! Paper beats Rock";
    ++computerScore;

  } else if (comp === 'Scissors') {
    computerSelection.textContent = "Computer's Selection: Scissors";
    result.textContent = "Great Job! Rock beats Scissors";
    ++playerScore;
  }
  // here we use CSSStyleDeclaration.setProperty() to set a custom
  // CSS property and its value; we use a template-literal because
  // the value has to be quoted and a template-literal makes that
  // easier to do (this property will be read from CSS):
  computerScoreElement.style.setProperty('--currentComputerScore', `"${computerScore}"`);
  // here we update the HTMLOrForeignElement.dataset API to set
  // a property on the dataset Object of the element, and set its
  // value equal to the playerScore (this creates a custom data-*
  // attribute on the element, from which CSS can read the value
  // via the attr() function:
  playerScoreElement.dataset.current_player_score = playerScore;
}
*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  width: clamp(200px, 50vw, 600px);
  margin: 1em auto;
  gap: 0.5em;
}

.wrapper {
  grid-column: 1 / -1;
  text-align: center;
  background-color: #f903;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.container button {
  cursor: pointer;
}

.results::before {
  content: "Results: ";
  display: block;
  font-size: 1.2em;
  border-bottom: 2px solid #000;
}

.computerScore,
.playerScore {
  color: #000;
}

.computerScore::before {
  content: 'Computer score: ';
  color: orange;
}

/* here we use the --currentComputerScore
   custom property - defined in JavaScript -
   as the content for the ::after pseudo-
   element; the '0' following the name of
   the custom property is the fall-back value
   in the event the property doesn't resolve
   to a valid value, it's quoted because it
   needs to be a string rather than a CSS 
   length or number: */
.computerScore::after {
  content: var(--currentComputerScore, '0');
  color: darkblue;
}

.playerScore::before {
  content: 'Player score: ';
  color: red;
}

/* here we use the attr() function to retrieve the
   attribute-value of the 'data-current_player_score'
   defined by the JavaScript, and placed on the
   element; unfortunately while the documentation
   states that a default/fallback value might be
   supplied it's use is not currently usable in
   (my current version of) Chromium or Firefox, so
   I'm unable to verify if it might work: */
.playerScore::after {
  content: attr(data-current_player_score);
  color: limegreen;
}

JS Fiddle demo

参考: