1

I am building a browser extension and I have a function inside of <script> tags that modifies the DOM that I need to inject into the <head> of any given webpage. The entire function is a string("<script>function content blah blah</script>"). I was using jquery to achieve this:

$('head').prepend(modFunction);

and this works fine. I would like to remove jQuery for a few reasons but when I try to create a <script> element to inject into the <head> with vanilla javascript everything fails. I have tried two methods so far:

1.

  var headSelector = document.querySelector('head');
  var el = document.createElement('div');
  el.innerHTML = modFunction;
  modFunction = el.firstChild;
  headSelector.insertBefore(modFunction, headSelector.firstChild);

2.document.head.insertAdjacentHTML('afterbegin', modFunction);

Both javascript attempts inject a <script> tag with the correct function into the <head>, however, neither executes the function. Not sure why jQuery is working and the vanilla javascript doesn't. Any help would be greatly appreciated. Thanks

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
samuelstarbuck
  • 373
  • 1
  • 5
  • 13
  • If you're inserting the script dynamically, where you insert it is irrelevant really.. You might be better off sticking to the body. – DividedByZero Jul 14 '16 at 00:39
  • 1
    From the source code above it looks like you're trying to insert a `div` not a `script` tag.. – NewToJS Jul 14 '16 at 00:40
  • `document.getElementsByTagName('script')[0].parentNode.insertBefore(document.createElement('script'), document.getElementsByTagName('script')[0]);` This will only work if you have an existing script tag in place, I'd assume you would since you would want this to run on load of the page – NewToJS Jul 14 '16 at 00:45
  • Possible duplicate of [Building a Chrome Extension - Inject code in a page using a Content script](http://stackoverflow.com/questions/9515704/building-a-chrome-extension-inject-code-in-a-page-using-a-content-script) – Haibara Ai Jul 14 '16 at 00:58

2 Answers2

5

You have a few mistakes.

  1. If your modFunction is a string that contains <script> tag before and after it, your code won't work, because changing innerHTML of div will not execute added scripts.

  2. Using insertAdjacentHTML function is unneccesary, because modFunction is now object of type Text, which will insert [object Text] string before your script.

  3. Instead, use appendChild function to insert properly new script element into head.

Although @Jantho1990 said that it is better to load script from file instead, many browsers use cache, so if you change your script source, it wont be always visible in browsers.

var scriptSource = '//YourScriptSource.....';
var scriptElem = document.createElement('script');
scriptElem.text = scriptSource;
document.head.appendChild(scriptElem);
  • 1
    @duskwuff. No, it absolutely works. Try executing it before downvoting. –  Jul 14 '16 at 00:52
-2

SoftwareEngineer171's answer works (see text in https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script), but I would like to point out a couple of things:

  1. You shouldn't be injecting <div> elements into the <head>. It's invalid HTML and a bad practice in general.

  2. Generally, it is preferable to store your JavaScript on your server as a file and use the src attribute to get that file onto the page. Not only is that more secure, it also saves you a lot of work when you need to go back and update the code.

I would recommend the following solution:

yourJavaScriptFile.js

    function content blah blah

Inline:

    <script type="text/javascript" src="yourJavaScriptFile.js"></script>
Jantho1990
  • 75
  • 3