Swarup
Swarup

Reputation: 41

CreateContextualFragment not working in safari

We have a problem with a function (createContextualFragment) in safari.

We need to add some content in the body, so we use this line of code.

Code:

document.getElementsByTagName('body')[0].insertBefore(document.createRange().createContextualFragment("<div></div><script src="LINK_SOURCE"></script>"), null);

This line of code is working fine with Chrome and Firefox, but we are having some issue with createContextualFragment in Safari.

Error in Safari:

createContextualFragment — asyncronousDocumentWrite2.html:28:115NotSupportedError: DOM Exception 9: The implementation did not support the requested type of object or operation.

Upvotes: 4

Views: 1118

Answers (2)

Filip Kov&#225;č
Filip Kov&#225;č

Reputation: 194

I have found out that setting range.selectNodeContents(document.createElement('div')); fixes the issue as indirecly pointed out in this article https://grrr.tech/posts/create-dom-node-from-html-string/#range.
My example usage:

document.querySelectorAll('.container').forEach((el) => {
  const range = document.createRange();
  range.selectNodeContents(el);
  range.deleteContents();
  range.selectNodeContents(document.createElement('div')); // fix for safari
  el.appendChild(range.createContextualFragment(htmlContent));
});

Upvotes: 0

dustfinger
dustfinger

Reputation: 31

I realize that my answer is arriving a little late, but I recently ran into a similar situation.

What I found

According to https://developer.mozilla.org/en-US/docs/Web/API/Range/createContextualFragment#Browser_compatibility Range.createContextualFragment() is not supported in Safari 9.0 or 9.1. It does work fine in Safari 10 though.

What can you do?

Since Safari does not support createContextualFragment we can delegate the responsibility of creating our document fragment to jQuery. The following illustrates two options to do this depending on what version of jQuery you are using:

  1. jQuery 1.8 or newer use ParseHTML
    document.getElementsByTagName('body')[0].insertBefore($.parseHTML("<div></div><script src='http://google.ca'></script>"), null);

  2. Otherwise just let jQuery figure out what to do
    document.getElementsByTagName('body')[0].insertBefore($("<div></div> <script src='http://google.ca'></script>"), null);

Upvotes: 3

Related Questions