Observed Attributes
Tags: webcomponents, javascript
Published: 2022-12-28 22:55:43


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6de0vtjsmo47zntgtad.png)
  
We created a ColorSpan Web Component defined <a href="#colorspan">here</a>; which allows us to change the background color based on setting an attribute.  The default background color is yellow.

The HTML markup for the image above was:

```html
<h2>
  The NFC North
</h2>
<a href="https://www.vikings.com/">
  <color-span bgc="Purple" >
    Vikings
  </color-span>
</a>, 
<a href="#">
  <color-span>
    Green Bay
  </color-span>
</a>
, and others...

```
 

For the Vikings markup, we added this attribute:
<code>&lt;color-span bgc="Purple"&gt;</code>

"bgc"=BackGroundColor
###Observed Attributes###
How did we get "bgc" to be defined as an attribute? The rule is to use a static getter method named: <code>observedAttributes</code>, like this:

```
static get observedAttributes() {
    return ["bgc"];
}
```
This method returns an array of strings which define allowable attributes. In this case, just one string is returned <code>["bgc"]</code>.

```html
<color-span bgc="Purple">
 Vikings
</color-span>

```

###The Attribute Changed CallBack###

Because of the defined static getter function <code>observedAttributes()</code>, the WebComponent interface will call the <code>attributeChangedCallback</code> function when an attribute changes.

``` js
attributeChangedCallback(name, oldValue, newValue) {  
  this.SetStyle(name,newValue);
}

```
###SetStyle Function###

```js
SetStyle(name, color){
  //Defaults to Yellow
  let backgroundColor = "Yellow"; 
  if(color=="Purple"){
    backgroundColor="#C5B4E3";
  }
  this.style.textContent = `
  span:hover { text-decoration: underline; color:red; }            
  :host(.footer) { color : #555; }
  :host { background-color:${backgroundColor}; padding: 2px 5px; }
`;
}
```

<h3 id="colorspan">The Color Span WebComponent</h3>

```js
//A Webcomponent based on a span with built ability to change background color
class ColorSpan extends HTMLElement {
  span = null;
  style = null;

  constructor() {
    super();

    this.span = document.createElement("span");
    this.span.textContent = this.textContent;
    this.style = document.createElement("style");
    this.SetStyle();

    let shadowRoot = this.attachShadow({ mode: "open" });
    this.shadowRoot.appendChild(this.style);
    shadowRoot.appendChild(this.span);
  }
  SetStyle(name, color) {
    let backgroundColor = "Yellow";
    if (color == "Purple") {
      backgroundColor = "#C5B4E3";
    }
    this.style.textContent = `
  span:hover { text-decoration: underline; color:red; }            
  :host(.footer) { color : #555; }
  :host { background-color:${backgroundColor}; padding: 2px 5px; }
`;
  }
  static get observedAttributes() {
    return ["bgc", "color"];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this.SetStyle(name, newValue);
  }
}

// Define the new element
customElements.define("color-span", ColorSpan);

```
###The HTML Head###
The script tag brings in the component from the main.js file with the defer attribute.

```html
  <head>
    <meta charset="utf-8">
    <title>Host selectors</title>
    <script src="main.js" defer></script>
    <link rel="stylesheet" href="styles.css">
  </head>
```
###Warning###
Most purists would say this is a violation of concerns. And they would be right. We already have Styles, so why do this?  The answer is to learn how a Web Component callback works.