0

I have a function that's supposed to copy window.location.origin to the clipboard for the user to paste:

  <OptionButton
    onClick={() => this.copyLink(`${window.location.origin}/calc/${apiId}/${formatScenarioName(database.api.scenarioName || database.inputs.scenarioName)}`)}
  >
    Copy Link
  </OptionButton>



  copyLink(value) {
    const tempInput = document.createElement('input')
    tempInput.style = 'position: absolute; left: -1000px; top: -1000px'
    tempInput.value = value
    document.body.appendChild(tempInput)
    tempInput.select()
    document.execCommand('copy')
    document.body.removeChild(tempInput)
    message.success('Link copied to clipboard!')
  }

While this works on any other browser, this fails on IE11. I've tried incorporating react router, but the requirement is to have the full link rather than just the params. However a workaround I've also tried is plainly adding window.location.href, but that's not very dynamic.

Is there a polyfill for this on IE11? Or a workaround to this?

nyphur
  • 2,404
  • 2
  • 24
  • 48

2 Answers2

0

This rang a little bell when I've searched for a polyfill in the past.

Something I use throughout my code base, so you might need small adaptations to fit in React most likely:

/**
  * Polyfill for window.location
  * @inner {string} origin fix IE11 on windows 10 issue
  * @inner {string} hash fix # inconsistency
  * @return {Object<Location>} window.location
  * @see https://connect.microsoft.com/IE/feedback/details/1763802/location-origin-is-undefined-in-ie-11-on-windows-10-but-works-on-windows-7
  * @see https://stackoverflow.com/questions/1822598/getting-url-hash-location-and-using-it-in-jquery
  */
    location: (function (loc) {
        return loc.origin
            ? loc
            : (function () {
                var origin =
                    loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port : ''),
                    hash = loc.hash.replace('#', '');

                try {
                    Object.defineProperty(loc, {
                        origin: {
                            value: origin,
                            enumerable: true
                        },
                        hash: {
                            value: '#' + hash,
                            enumerable: true
                        }
                    });
                } catch (e) {
                    loc.origin = origin;
                    loc.hash = hash;
                }

                return loc;
            })();
    })(window.location),
Tim Vermaelen
  • 6,869
  • 1
  • 25
  • 39
0

Your error is coming from the style assignment.

tempInput.style = 'position: absolute; left: -1000px; top: -1000px'

In 'strict' mode you shouldn't be able to write multiple values to style using css text format. Most browsers don't enforce this, but IE 11 does.

I suspect your console reports this as:

SCRIPT5045 Assignment to read-only properties is not allowed in strict mode

If you were manipulating an element that already had styles, you might want to set each property separately, but there is a way to just completely replace any existing styles. Because you are setting this on a temporary element you can use cssText:

tempInput.style.cssText = 'position: absolute; left: -1000px; top: -1000px'

That should be compatible across browsers.

For further reference see ElementCSSInlineStyle.style