I'm trying to set up an intersection observer that looks for elements on my page that have a data-original-bg and assigns that as the background image url style, so the images are postloaded.

I've written a function in my React component and loaded it in ComponentDid Mount but i'm getting the error 'cannot assign to rvalue that is not a reference' - on the line
return target.hasAttribute('data-original-bg') ? target.getAttribute('style') += 'background-image:' + backgroundImage : target.getAttribute('style') += 'background-image:' + backgroundImage

My functions:

  componentDidMount () {
    this.setIndex = window.setInterval(() => {
      this.setupObserver()
    }, 3000)
  }

  setupObserver () {
    var nodes = document.querySelectorAll('img[data-original],div[data-original-bg]')
    window.io = new IntersectionObserver(function (items) {
      for (var i = 0; i < items.length; i++) {
        var item = items[i]
        var target = item.target
        if (target.hasAttribute('src')) {
          window.io.unobserve(target)
          continue
        }
        if (!item.intersectionRatio) continue
        return target.hasAttribute('data-original-bg') ? target.getAttribute('style') += 'background-image:' + backgroundImage : target.getAttribute('style') += 'background-image:' + backgroundImage
        if (target.hasAttribute('data-original')) target.setAttribute('src', target.getAttribute('data-original'))
        window.io.unobserve(target)
      }
    })
    for (var i = 0; i < nodes.length; i++) { window.io.observe(nodes[i]) }
  }

2 Answers

1
Oluwafemi Sule On Best Solutions

The following line is an attempt to assign to a value and not a reference.

return target.hasAttribute('data-original-bg') ? 
    target.getAttribute('style') += 'background-image:' + backgroundImage 
    : target.getAttribute('style') += 'background-image:' + backgroundImage

This (target.getAttribute('style') += 'background-image:' + backgroundImage) can be distilled to an assignment expression as:

2 += 3

This makes is clear that it isn't doing what you think it does.

I suggest to break that line up and perform the style update for the target in steps.

if target.hasAttribute('data-original-bg') {
    const newStyle = [
      target.getAttribute('style'),
      `background-image: ${backgroundImage}`, 
    ].join(';')
    target.setAttribute('style', newStyle)
}
return; 
1
jo_va On

Your are assigning to the return value of getAttribute which is an rvalue and not a lvalue. Also it is not a good idea to do an assigment in the branches of a ternary expression, and both branches of your ternary do the same thing.

return target.hasAttribute('data-original-bg')
    ? target.getAttribute('style') += 'background-image:' + backgroundImage
    : target.getAttribute('style') += 'background-image:' + backgroundImage

You probably want to do this instead:

if (target.hasAttribute('data-original-bg')) {
    target.style.backgroundImage = backgroundImage;
}
return;