简体   繁体   中英

Change script src before DOM is rendered using JS

so I have a code on my website that looks like this

<div class="bonus-button">
    <script language="javascript" type="text/javascript" src="https://somedomain.de/widget/button/PSIG2ng?skin=134&t_mc=kwk&btn=rec_company"></script>
</div>

What I wanted to do is change the value of t_mc= to another one besides kwk depending on an url parameter. An example is www.somedomain.de/page?utm_source=email . When somebody enters the side using this parameter the code should look like this:

<div class="bonus-button">
        <script language="javascript" type="text/javascript" src="https://somedomain.de/widget/button/PSIG2ng?skin=174&t_mc=email&btn=rec_company"></script>
    </div>

Well it does that but still kwk is the value coming through and it doesn't stand in the source code, only in the elements tab in the chrome developer tool.

Somehow I believe I need to change it way earlier before everything is really there ... right?

 if (window.location.search.indexOf('utm_source=') > -1) { function getParameterByName(name, url) { if (!url) url = window.location.href; name = name.replace(/[\\[\\]]/g, '\\\\$&'); var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\\+/g, ' ')); } var kwksource = getParameterByName('utm_source'); var scriptsrc = document.querySelector('.bonus-button script').getAttribute('src'); var scriptsrcbottom = document.querySelector('.bonus-button-bottom script').getAttribute('src'); document.querySelector('.bonus-button script').setAttribute('src', scriptsrc.split('t_mc=kwk').join('t_mc=' + kwksource)); document.querySelector('.bonus-button-bottom script').setAttribute('src', scriptsrcbottom.split('t_mc=kwk').join('t_mc=' + kwksource)); } 
  <div class="bonus-button"> <script language="javascript" type="text/javascript" src="https://t.tellja.eu/widget/button/PSIG2ng?skin=134&t_mc=kwk&btn=rec_company"></script> </div> 

Short Answer: That is not possible.

Long Answer:

When the browser is reading the page source and encounters an <script> tag, it stops rendering the page loads and executes the script and continues rendering. That is because a script may create DOM nodes using various methods like document.write etc. (a defer attribute may change that)

So if you want create a script that should alter the url of another script tag, before that is loaded and executed, it needs to appear right before that one in the source. But in this very moment ths script is executed, the one to alter isn't parsed yet, so not part of the DOM, so accessible at all.

The other way around, if the script that modifies the url of another script tag appears right after that within the source, the preceding script is already loaded and executed, so the modification is just too late.

So the only way to change the source url of a given script is after it appears in the DOM like so:

[...document.querySelectorAll('script[src]')]
  .find(s => <some test to identify the script>)
  .setAttribute('src', 'the new value')

The will result in a reload of the script. But that doesn't redo any changes to the DOM, remove any Event Listeners etc, or in other words wont do any clean up.

All in all, the only reliable solution to this is serverside, such that script url is right from the beginning the page loads.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM