简体   繁体   English

使用JS渲染DOM之前更改脚本src

[英]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. 我想要做的是改变的价值t_mc=到除了一个又一个kwk取决于一个URL参数。 An example is www.somedomain.de/page?utm_source=email . 例如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. 做到了,但是kwk仍然是传递的值,它不存在于源代码中,仅存在于chrome开发人员工具的elements标签中。

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. 当浏览器正在阅读页面源代码并遇到<script>标记时,它将停止呈现页面加载并执行脚本并继续呈现。 That is because a script may create DOM nodes using various methods like document.write etc. (a defer attribute may change that) 那是因为脚本可以使用诸如document.write等的各种方法来创建DOM节点( defer属性可能会改变它)

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. 因此,如果要创建一个脚本,该脚本应该更改另一个脚本标记的URL,那么在加载和执行该脚本标记之前,该脚本需要在源代码中的该脚本标记之前出现。 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. 但是在此脚本执行的那一刻,要更改的脚本尚未解析,因此不是DOM的一部分,因此完全可以访问。

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. 反之,如果修改另一个脚本标记的url的脚本紧随其后出现在源代码中,则说明先前的脚本已经加载并执行,因此修改为时已晚。

So the only way to change the source url of a given script is after it appears in the DOM like so: 因此,更改给定脚本的源URL的唯一方法是在DOM中出现如下所示:

[...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. 但这并不会重做对DOM的任何更改,也不会删除任何事件监听器等,换句话说,也不会做任何清理。

All in all, the only reliable solution to this is serverside, such that script url is right from the beginning the page loads. 总而言之,唯一可靠的解决方案是在服务器端,这样脚本URL就从页面加载开始就正确了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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