title: chrome storage onChanged listener not firing
body: <p>I'm making a Chrome extension that takes description text from a search result and stores it in chrome storage. I use <code>chrome.storage.local.set</code> to change the value inside chrome storage in <code>background-js</code>. Then, I access it in <code>content.js</code>. My extension is working when I remove <code>onChanged.addListener()</code>, but I'd like it to only fire when the value has changed inside chrome storage.</p>
  
  <p>content.js</p>
  
  <pre><code>chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){
      if (request.message=="browserAction"){
          var link = $('h3.r')
          link.click(function(){
              var d = this.nextSibling
              var description = $(d).find('span.st').text()
              var index = description.lastIndexOf("-")
              if (index&gt;=0){
                  var description = description.slice(index+2,description.length-1)
              }
              alert(description)
              chrome.runtime.sendMessage({"message":"linkClicked","description":description})
          })      
      }
  })
  chrome.storage.onChanged.addListener(function(changes,areaName){
  chrome.storage.local.get("keyName",function(items) {//initialize the application
              console.log(items.keyName)
              var p = document.getElementsByTagName('p')
              for (n=0;n&lt;p.length;n++){
                  console.log(p[n].textContent)
                  if (p[n].textContent.includes(items.keyName)){
                      console.log('found a match at paragraph' + p[n])
                      var newStr = p[n].textContent.replace(items.keyName,"&lt;span style='background-color:yellow'&gt;" + items.keyName + "&lt;/span&gt;")
                      p[n].innerHTML=newStr
                      $('html, body').animate({
                      scrollTop: $('p:eq('+n+')').offset().top + 'px'
                      }, 'fast')          
                      return
                  }
                  else{console.log('no match found')}
              }
  
  })  
  })
  </code></pre>
  
  <p>background-js</p>
  
  <pre><code>chrome.browserAction.onClicked.addListener(function(tab){
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
          var activeTab = tabs[0];
          chrome.tabs.sendMessage(activeTab.id,{"message":"browserAction"})
        });
  })
  chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){ //Listener Not Firing
      if (request.message=="linkClicked"){
          var d = request.description
          console.log(d)
          if (d.indexOf('.')&gt;=0){ //this will always evaluate to true and execute, leaving empty string ||||
              var d = d.slice(0,d.indexOf('.')) //get a snippet of text
          }
      }
      console.log(d)
      chrome.storage.local.set({"keyName": d},function(){console.log('mah critics stored')});
  })
  </code></pre>
  
  <p>manifest.json</p>
  
  <pre><code>{
      "manifest_version":2,
      "name":"extension",
      "version":"0.1",
      "content_scripts":[
          {
              "matches": ["&lt;all_urls&gt;"],
              "js":["content.js","jquery-3.1.1.min.js"]
          }],
      "browser_action":{
                  "default_icon":"icon.png"
              }
          ,
      "background":{
          "scripts":["background.js"]
      },
      "permissions":[
          "storage",
          "tabs"
      ]
  
  }
  </code></pre>