Я создал это маленькое средство смены цвета фона просто для развлечения и немного поиграть с JS, но у меня возникла проблема, которую я не знаю, как решить.
Это мой HTML:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<script src = "script.js" defer></script>
<link rel = "stylesheet" href = "style.css">
<link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel = "stylesheet" integrity = "sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin = "anonymous">
<title>Color picker</title>
</head>
<body>
<div class = "container d-flex align-items-center justify-content-center">
<div>
<button id = "main_button" class = "btn btn-danger">Change color</button>
</div>
</div>
</body>
</html>
и мой JS:
const button = document.querySelector("#main_button");
function randomColor(){
let letters = "0123456789ABCDEF";
let color = "#";
for(let i = 0; i < 6; i++){
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
function changeBackground(){
document.body.style.backgroundColor = randomColor();
};
function createParagraph(){
let color = randomColor();
const div = document.querySelector(".container");
let par = document.createElement("p");
par.innerHTML = "Current color is " + color;
div.appendChild(par);
}
button.addEventListener("click", changeBackground);
button.addEventListener("click", createParagraph);
И это моя проблема, каждый раз, когда я нажимаю на кнопку, создается новый абзац с новым цветовым кодом. Но я хочу, чтобы кнопка обновляла цветовой код в том же абзаце.
Меняется весь цвет тела. На картинке темно-синий, но он меняется каждый раз, когда вы нажимаете кнопку. Также я почти уверен, что он не показывает мне правильный цветовой код, но это другая проблема: D
Вы не хотите, чтобы ваш фон изменился? Затем вам нужно удалить прослушиватель событий, который вызывает функцию changeBackground.
Нет, фон должен изменить цвет. По функционалу работает корректно. Мне просто нужен абзац, чтобы показать мне правильный HEX-код и обновлять его каждый раз, когда я нажимаю кнопку.
при каждом щелчке вы добавляете еще один тег p - вместо этого создайте тег p на своей html-странице -
<p id = "colorTag"><p>
в вашей функции createParagraph -
вместо let par = document.createElement("p");
делай let par = document.getElementById('colorTag') par.innerHTML = "Current color is " + color;
Если я правильно вас понял, вы хотите изменить цвет фона на самый новый цвет абзаца. Для этого вам нужно вызвать функцию changebackground в функции createParagraph:
function createParagraph(){
let color = randomColor();
const div = document.querySelector(".container");
let par = document.createElement("p");
par.innerHTML = "Current color is " + color;
div.appendChild(par);
changeBackground(color);
}
function changeBackground(newcolor){
document.body.style.backgroundColor = newcolor;
};
button.addEventListener("click", createParagraph);
Это сделает работу.
Ты каждый раз создаешь новый абзац -
HTML-файл:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8" />
<meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
<script src = "script.js" defer></script>
<link rel = "stylesheet" href = "style.css" />
<link
href = "https://cdn.jsdelivr.net/npm/[email protected]
beta1/dist/css/bootstrap.min.css"
rel = "stylesheet"
integrity = "sha384-
giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin = "anonymous"
/>
<title>Color picker</title>
</head>
<body>
<div class = "container d-flex align-items-center justify-content-center">
<div>
<button id = "main_button" class = "btn btn-danger">Change color</button>
</div>
<p id = "par"></p> <!-- <== You Need this for render every time color -->
</div>
<script src = "./script.js"></script>
</body>
</html>
JS-файл:
const button = document.querySelector("#main_button");
function randomColor() {
let letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function changeBackground() {
document.body.style.backgroundColor = randomColor();
}
function createParagraph() {
let color = randomColor();
const div = document.querySelector(".container");
let par = document.getElementById("par"); // select paragraph as html file
par.innerHTML = "Current color is " + color; // and render color to paragraph
}
button.addEventListener("click", changeBackground);
button.addEventListener("click", createParagraph);
На самом деле вы создаете новый <p>
-элемент каждый раз, когда вызываете createParagraph()
.
Вместо этого вы можете заранее создать тег в своем HTML и сохранить его ссылку (которую вы можете получить, запросив его, используя, например, document.querySelector()
) в переменной.
Затем вы можете изменить его содержимое, присвоив новое значение его .textContent
-свойству.
Вот демонстрация:
var pElement = document.querySelector('#p-id');
document.querySelector('button').addEventListener('click', () => {
pElement.textContent = "This is its new text, assigned using the '.textContent'-property!";
});
<button>Change <p>'s content!</button>
<p id = "p-id">This is the initial text.</p>
Важно отметить, что на самом деле вы не отображаете текущее значение цвета. Вы вызываете randomColor()
дважды: один раз в changeBackground()
и один раз в createParagraph()
, при этом созданный цвет используется только для назначения <body>
нового цвета фона или отображения с помощью <p>
-тега.
Чтобы отобразить фактически используемый цвет, вам нужно использовать одну и ту же строку как для назначения, так и для значения содержимого <p>
. Вы можете сделать это одним из следующих способов:
document.body.style.background
(или .backgroundColor
, в зависимости от того, что вы использовали). Однако это вернет цвет в формате, подобном rgb(123, 213, 132)
, что может быть нежелательным.Я покажу примеры для пунктов 1 и 2.
Пункт 1 может выглядеть так:
const button = document.querySelector('#main_button');
const pElement = document.querySelector('#p_id');
function randomColor(){
let letters = "0123456789ABCDEF";
let color = "#";
for(let i = 0; i < 6; i++){
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function changeAndUpdateColor() {
let color = randomColor();
document.body.style.background = color;
pElement.textContent = 'Current Color is ' + color;
}
button.addEventListener('click', changeAndUpdateColor);
<button id = "main_button">Change Color</button>
<p id = "p_id"></p>
Пункт 2 может выглядеть так:
const button = document.querySelector('#main_button');
const pElement = document.querySelector('#p_id');
var color = '';
function randomColor(){
let letters = "0123456789ABCDEF";
let color = "#";
for(let i = 0; i < 6; i++){
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function changeBackground() {
document.body.style.background = color;
}
function updateParagraph() {
pElement.textContent = 'Current Color is ' + color;
}
function getNewColor() {
color = randomColor();
}
button.addEventListener('click', getNewColor);
button.addEventListener('click', changeBackground);
button.addEventListener('click', updateParagraph);
<button id = "main_button">Change Color</button>
<p id = "p_id"></p>
Однако использование такого количества функций и слушателей делает код неуклюжим. Вместо этого вы должны использовать функциональные выражения ES6 или стрелочные функциональные выражения.
При использовании функционального выражения мы можем инициализировать и использовать переменную цвета внутри, что делает глобальную переменную бесполезной.
const button = document.querySelector('#main_button');
const pElement = document.querySelector('#p_id');
function randomColor(){
let letters = "0123456789ABCDEF";
let color = "#";
for(let i = 0; i < 6; i++){
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
button.addEventListener('click', function() {
let color = randomColor();
document.body.style.background = color;
pElement.textContent = 'Current Color is ' + color;
});
<button id = "main_button">Change Color</button>
<p id = "p_id"></p>
Говоря о глобальном контексте:
Объявление многих переменных и/или функций в глобальном контексте загрязнит глобальное пространство имен и будет доступно пользователю, например. с помощью браузерной консоли. Это проблема для функций, в которых обрабатываются или доступны конфиденциальные данные.
Чтобы освободить глобальное пространство имен, мы можем разместить большую часть нашего скрипта внутри так называемого IIFE, немедленно вызываемого функционального выражения. Добавить это было бы так же просто, как поместить свой код внутри такого:
(function() {
// Your code ...
})();
Скобки вокруг самого функционального выражения сгруппируют его, чтобы его можно было выполнить с помощью вызывающих скобок ()
, подобно тому, как размещение числа внутри скобок позволит нам вызвать для него функцию, например:
(123).toString();
Еще одно замечание: объявления функций внутри блоков (означает: когда они не объявлены в глобальном контексте) не являются частью ECMAScript, что делает эту функцию нестандартизированной. Это может быть неважно для вас, так как в любом случае поддерживается в большинстве (если не во всех) современных браузерах. Однако в этих случаях следует использовать функциональные выражения, на которые ссылается переменная, например. так:
(function() {
var aFunction = function() {
// ...
};
aFunction(); // Executed as usual
})();
Обратите внимание, что выражения функций не поднимаются, в отличие от объявлений функций, а это означает, что они должны предшествовать их использованию в коде.
Доступ к символам строки, подобный доступу к элементам массива, — это еще одна нестандартная функция, опять же поддерживаемая в большинстве браузеров. Стандартным способом было бы использование String.charAt()
.
Рефакторинг вашего кода может выглядеть так:
// Is OK to be globally accessible
function randomColor(){
let letters = "0123456789ABCDEF";
let color = "#";
for(let i = 0; i < 6; i++){
color += letters.charAt(Math.floor(Math.random() * 16));
}
return color;
}
// Should be placed inside an IIFE; the global context is still accessible
(function() {
const button = document.querySelector('#main_button');
const pElement = document.querySelector('#p_id');
button.addEventListener('click', function() {
let color = randomColor();
document.body.style.background = color;
pElement.textContent = 'Current Color is ' + color;
});
})();
<button id = "main_button">Change Color</button>
<p id = "p_id"></p>
Что именно вы хотите изменить? Вы хотите, чтобы цвет кнопки менялся при нажатии, цвет фона абзаца или текст в абзаце?