admin管理员组

文章数量:1431307

I wanted to change color according to user preference dynamically like when a user selects a color then it is applied synchronously to the element .

Like when an element is clicked color picker opens and then it works like developer tools color-picker , when a color is chosen from the picker it is applied to element and if user wants to change the color again in same picker than that also applied

Tried to went through following questions but couldn't find answer :

Change background colors dynamically using input event

how to dynamically select a color from a color picker by using jQuery?

HTML Input Color Picker, Apply Changes In Sync With Color Picker Selection

I wanted to code work like this in below snippet, whichever element is clicked than colors are changes of that element.

In original code html is like this : <div id="clockOuterCircle"><div id="clockStyleCircle"></div></div> which can be solved by bubbling/capturing

var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)

function deed() {
  var reed2 = document.getElementById("colorClock");
  reed2.click();
  var reed3 = reed2.value;
  // reed1.addEventListener('change', function() {
  this.style.backgroundColor = reed3;
  document.getElementById("demo").innerHTML = reed3;
  //})
}
#clockStyleCircle {
  position: absolute;
  width: 16vw;
  height: 16vw;
  text-align: center;
  padding: 0%;
  top: 28.5%;
  left: 28.5%;
  border-radius: 50%;
  border: 3px solid black;
  background-color: rgb(255, 233, 35);
}

#clockOuterCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 42vw;
  height: 42vw;
  margin: auto;
  border-radius: 50%;
  border: 4px solid rgb(255, 62, 62);
  background-color: rgb(253, 133, 133);
  user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>
<input type="color" name="colorClock" id="colorClock">

I wanted to change color according to user preference dynamically like when a user selects a color then it is applied synchronously to the element .

Like when an element is clicked color picker opens and then it works like developer tools color-picker , when a color is chosen from the picker it is applied to element and if user wants to change the color again in same picker than that also applied

Tried to went through following questions but couldn't find answer :

Change background colors dynamically using input event

how to dynamically select a color from a color picker by using jQuery?

HTML Input Color Picker, Apply Changes In Sync With Color Picker Selection

I wanted to code work like this in below snippet, whichever element is clicked than colors are changes of that element.

In original code html is like this : <div id="clockOuterCircle"><div id="clockStyleCircle"></div></div> which can be solved by bubbling/capturing

var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)

function deed() {
  var reed2 = document.getElementById("colorClock");
  reed2.click();
  var reed3 = reed2.value;
  // reed1.addEventListener('change', function() {
  this.style.backgroundColor = reed3;
  document.getElementById("demo").innerHTML = reed3;
  //})
}
#clockStyleCircle {
  position: absolute;
  width: 16vw;
  height: 16vw;
  text-align: center;
  padding: 0%;
  top: 28.5%;
  left: 28.5%;
  border-radius: 50%;
  border: 3px solid black;
  background-color: rgb(255, 233, 35);
}

#clockOuterCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 42vw;
  height: 42vw;
  margin: auto;
  border-radius: 50%;
  border: 4px solid rgb(255, 62, 62);
  background-color: rgb(253, 133, 133);
  user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>
<input type="color" name="colorClock" id="colorClock">

Possible answer of dynamically changing color can be like this in below snippet, like using
input event separately on each element.

var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)

//function deed() {
//  var reed2 = document.getElementById("colorClock");
//  reed2.click();
//  var reed3 = reed2.value;
// reed1.addEventListener('change', function() {
// this.style.backgroundColor = reed3;
// document.getElementById("demo").innerHTML = reed3;
//})
//}

reed2 = document.getElementById("colorClock");
reed2.addEventListener('input', deed)

function deed() {
  var reed3 = reed2.value;
  reed.style.backgroundColor = reed3;
}

reed4 = document.getElementById("colorClock2");
reed4.addEventListener('input', deed1)

function deed1() {
  var reed5 = reed4.value;
  reed1.style.backgroundColor = reed5;
}
#clockStyleCircle {
  position: absolute;
  width: 16vw;
  height: 16vw;
  text-align: center;
  padding: 0%;
  top: 28.5%;
  left: 28.5%;
  border-radius: 50%;
  border: 3px solid black;
  background-color: rgb(255, 233, 35);
}

#clockOuterCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 42vw;
  height: 42vw;
  margin: auto;
  border-radius: 50%;
  border: 4px solid rgb(255, 62, 62);
  background-color: rgb(253, 133, 133);
  user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>
<input type="color" name="colorClock" id="colorClock">
<input type="color" name="colorClock" id="colorClock2">

But in above method color is not changing of clicked element instead a fixed element color is changed which is defined beforehand . So have to apply code to different elements separately, as there are many elements so wanted to apply both ways

Thanks for the help in advance.

Share Improve this question edited Sep 23, 2021 at 13:41 Yupma asked Sep 15, 2021 at 20:17 YupmaYupma 2,5342 gold badges12 silver badges35 bronze badges 3
  • You can use events to fire a function that change color or make a custom color picker. – naxsi Commented Sep 15, 2021 at 20:20
  • @naxsi yes I tried that but have to apply separately for different elements – Yupma Commented Sep 15, 2021 at 20:23
  • if u wanna change dynamically, do a custom color picker or use some library like jscolor – naxsi Commented Sep 15, 2021 at 20:33
Add a ment  | 

4 Answers 4

Reset to default 1 +50

Updated to stop bubbling with event.stopPropagation()

If I've understood you correctly, you want to launch a colour picker every time any particular element in your page is clicked which allows you to change that element's background colour.

This solution adds and then launches a colour picker when any element with the class circle is clicked, then removes it again after a colour has been selected.

The colour picker input is hidden with display:none but the dialog box is visible.

let body = document.body;
let circles = document.querySelectorAll('.circle');


circles.forEach((circle) => {

  circle.addEventListener('click', () => {
  
    let existingColourPickers = document.querySelectorAll('input.colour-picker')
    
    existingColourPickers.forEach((existingColourPicker) => {
    
      if (body.contains(existingColourPicker)) {
        body.removeChild(existingColourPicker);
      }
    
    });
        
    event.stopPropagation();
    let colourPicker = document.createElement("input");
       
    colourPicker.type = "color";
    colourPicker.className = "colour-picker";
    body.appendChild(colourPicker); 
    colourPicker.click();
    
    colourPicker.addEventListener("input", () => {
      circle.style.backgroundColor = event.target.value;
    }, false);
    
    colourPicker.addEventListener("change", () => {
      body.removeChild(colourPicker);
    }, false);
    
  });
  
});
#clockStyleCircle {
  position: absolute;
  width: 16vw;
  height: 16vw;
  text-align: center;
  padding: 0%;
  top: 28.5%;
  left: 28.5%;
  border-radius: 50%;
  border: 3px solid black;
  background-color: rgb(255, 233, 35);
  z-index:1;
}

#clockOuterCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 42vw;
  height: 42vw;
  margin: auto;
  border-radius: 50%;
  border: 4px solid rgb(255, 62, 62);
  background-color: rgb(253, 133, 133);
  user-select: none;
}

#another-circle {
  width:50px;
  height:50px;
  border-radius: 50%;
  border: 4px green solid;
  background-color:blue;
  position:absolute;
  top:20px;
  left:20px;
}
.colour-picker {
  display:none;
}
<body>
  <div id="clockOuterCircle" class="circle">
    <div id="clockStyleCircle" class="circle"></div>
  </div>
  <!-- another circle -->
  <div id="another-circle" class="circle"></div>
  <!-- ... -->
</body>

What you had was pretty close. I just separated the color picking code into a new function. Try this..

var reed = document.getElementById("clockOuterCircle");
var reed1 = document.getElementById("clockStyleCircle");
reed.addEventListener('click', deed)
reed1.addEventListener('click', deed)

async function deed() {
  var color = await getUserColor();
  this.style.backgroundColor = color;
  document.getElementById("demo").innerHTML = color;
}

function getUserColor() {
  return new Promise(done => {
    var color_picker = document.createElement('input');
    color_picker.setAttribute('type', 'color');
    color_picker.style.opacity = 0;
    document.body.appendChild(color_picker);
    color_picker.addEventListener('change', function() {
      var color = this.value;
      this.remove();
      done(color);
    });
    color_picker.click();
  });
}
#clockStyleCircle {
  position: absolute;
  width: 16vw;
  height: 16vw;
  text-align: center;
  padding: 0%;
  top: 28.5%;
  left: 28.5%;
  border-radius: 50%;
  border: 3px solid black;
  background-color: rgb(255, 233, 35);
}

#clockOuterCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 42vw;
  height: 42vw;
  margin: auto;
  border-radius: 50%;
  border: 4px solid rgb(255, 62, 62);
  background-color: rgb(253, 133, 133);
  user-select: none;
}
<div id="clockStyleCircle"></div>
<div id="clockOuterCircle"></div>
<div id="demo"></div>

Your example defines the background-color using two different methods class and style, which may produce unexpected results.

Here is an example using the most basic form of JavaScript, that does not set the background-color via class.

When you click an area, it will change to the selected color and when you select a color, the last area clicked, will change to the same color.

To keep it brief and simple, the example does not check, if the elements it operates on, are well defined.

// The last area clicked
var div_last_clicked = 0;

// Called when the document has finished loading
function myonload() {
    // Detect when an area is clicked
    let elems = document.querySelectorAll('.mydiv');
    for(let i = 0; i < elems.length; ++i) {
        let elem = elems[i];
        elem.addEventListener('click', mydiv_clicked);
    }
    // Detect when the color changes
    let ob = document.querySelector('.mycolor');
    ob.addEventListener('change', mycolor_changed);
}

// Called when an area is clicked
function mydiv_clicked(e) {
    let ob = document.querySelector('.mycolor');
    div_last_clicked = e.target;
    div_last_clicked.style = "background-color:" + ob.value;
}

// Called when the color changes
function mycolor_changed(e) {
    if(div_last_clicked)
        div_last_clicked.style = "background-color:" + e.target.value;
}
.mydiv {
    height:30px;
    width: 200px;
    border:1px solid black;
    margin-bottom:2px;
}
<body onload="myonload()">
    <input class="mycolor" type="color" value="#ff0000" />
    <p>When you click an area below, it will change to the selected color.</p>
    <p>When you change the color, the last area clicked will also change
        to the same color.</p>
    <div class="mydiv">First area</div>
    <div class="mydiv">Second area</div>
    <div class="mydiv">Third area</div>
</body>

Based on your additional info, if you want to have a single colour input on the page, you can add a data-id attribute to each of your circles, and use that as a reference for which element the colour input should update when changed:

var restyleBG = document.querySelectorAll(".restyleBackground")
var colorPicker = document.getElementById("colorClock");
var selected;

restyleBG.forEach((restyle) => {
  restyle.addEventListener('click', changeBGcolor, false)
})

function changeBGcolor(event) {
  event.stopPropagation()
  selected = document.querySelector(`[data-id="${event.srcElement.dataset.id}"]`);
  colorPicker.click();
}

colorPicker.addEventListener('input', (event) => {
  selected.style.backgroundColor = colorPicker.value;
})
#clockStyleCircle {
  position: absolute;
  width: 16vw;
  height: 16vw;
  text-align: center;
  padding: 0%;
  top: 28.5%;
  left: 28.5%;
  border-radius: 50%;
  border: 3px solid black;
  background-color: rgb(255, 233, 35);
  z-index: 1;
}

#clockOuterCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 42vw;
  height: 42vw;
  margin: auto;
  border-radius: 50%;
  border: 4px solid rgb(255, 62, 62);
  background-color: rgb(253, 133, 133);
  user-select: none;
}

#another-circle {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 4px green solid;
  background-color: blue;
  position: absolute;
  top: 20px;
  left: 20px;
}

#colorClock {
  display: none;
}
<body>
  <input type="color" name="colorClock" id="colorClock">

  <div id="clockOuterCircle" class="restyleBackground" data-id="1">
    <div id="clockStyleCircle" class="restyleBackground" data-id="2"></div>
  </div>
  <!-- another circle -->
  <div id="another-circle" class="restyleBackground" data-id="3"></div>
  <!-- ... -->
</body>

本文标签: javascriptHow to dynamically change color of clicked elements using colorpickerStack Overflow