Tre*_*ham 28 html javascript javascript-events
这是一个奇怪的用例,但我有我的理由:
我希望能够写作
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
Run Code Online (Sandbox Code Playgroud)
在我的标记中,并使用代码first.js,防止或延迟执行second.js.这可能在任何浏览器中都可以吗?如果first.js内联的内容怎么办?(如果有帮助,则假设第二个脚本标记具有id属性.)
由于我得到了几个错过我所得到的答案,我应该澄清一下:
first.js.任何需要更改页面原始HTML的内容second.js都是不可接受的.second.js通过Ajax以及使用执行它eval.这很容易.困难的部分是阻止立即执行second.js.second.js.因此,您不能仅second.js使用no-op函数替换每个调用的全局函数.(另外,这几乎肯定会导致错误.)如果你知道一个解决方案适用于某些浏览器但不适用于其他浏览器,我很乐意听到它.
示例:为了使这更具体,让我们说代码
<script type="text/javascript">
function func() {
window.meaningOfLife = 42;
window.loadSecond();
};
setTimeout(func, 10);
</script>
Run Code Online (Sandbox Code Playgroud)
在两个script包含之前,second.js包含该行
if (window.meaningOfLife !== 42) {throw new Error();}
Run Code Online (Sandbox Code Playgroud)
first.js应该能够通过延迟second.js执行直到window.loadSecond运行来防止此错误.(假设执行的window.loadSecond也是first.js.)它是不是不准碰window.meaningOfLife.
更新:Alohci的答案符合这些要求,但仅限于第二个脚本标记在第一个脚本标记之后立即出现的情况,其间只有空格.如果有人可以扩展他的黑客以避免这种要求,而不会引入其他不必要的后果,那将是惊人的......
Alo*_*hci 30
根据您的具体要求设置,这实际上非常简单,应该完全跨浏览器工作.但是,它确实需要first.js紧跟在second.js之前,除了空格之外没有任何东西.
首先,我们假设HTML看起来像这样:
<!DOCTYPE html>
<html>
<head>
<title>Test Case</title>
<meta charset="UTF-8" />
<script type="text/javascript">
function func() {
window.meaningOfLife = 42;
window.loadSecond();
};
</script>
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
</head>
<body>
<p>Lorem ipsum dolor sit amet ...</p>
<a href="javascript:func()">Run Func()</a>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我删除了setTimeout,因为这会导致func()在start.js运行之前运行导致"loadSecond未定义"错误.相反,我提供了一个锚点来点击运行func().
其次,让我们假设second.js看起来像这样:
document.body.appendChild(document.createTextNode("second.js has run. "));
if (window.meaningOfLife !== 42) {throw new Error();}
Run Code Online (Sandbox Code Playgroud)
在这里,我刚刚添加了一行来将一些文本追加到文档正文中,以便在second.js实际运行时更容易看到.
然后first.js的解决方案是这样的:
function loadSecond()
{
var runSecond = document.createElement("script");
runSecond.setAttribute("src", "second.js");
document.body.appendChild(runSecond);
}
document.write("<script type='application/x-suppress'>");
Run Code Online (Sandbox Code Playgroud)
当func()运行时,loadSecond函数就是运行second.js.
解决方案的关键是document.write线.它将<script type='application/x-suppress'>在first.js的close脚本标记和second.js的打开脚本标记之间注入HTML .
解析器将看到此并启动一个新的脚本元素.由于type属性的值不是浏览器识别为JavaScript的值,因此不会尝试运行其内容.(因此,您可以在此处使用无限数量的类型属性值,但必须包含类型属性,因为在缺少的情况下,浏览器将假定脚本的内容是JavaScript.)
然后,second.js脚本的开始标记将被解析为新脚本元素的文本内容,而不会被执行.最后,第二个.js脚本的结束标记将被重新用于关闭新的脚本元素,这意味着HTML的其余部分被正确解析.
您可以在http://www.alohci.net/static/jsprevent/jsprevent.htm查看工作版本
以下文章介绍了如何阻止(第 3 方)脚本从脚本加载/执行(包括页面标题中的标签和动态添加的标签)。
\n\n要处理页面上的现有标签:
\n\n<script type="text/javascript" type="javascript/blocked" src="second.js"></script>,然后在 MutationObserver 回调中备份并稍后重新添加。处理动态添加的标签
\n\n这些人还提供了一个Yett库,其中包含文章中描述的方法。
\n在first.js,设置var shouldILoad = true
然后,以second.js这种方式加载:
<script>
if (shouldILoad) {
(function() {
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = ('second.js');
var s = document.getElementById('myscript');
s.parentNode.insertBefore(myscript, s);
})();
}
</script>
Run Code Online (Sandbox Code Playgroud)
(其中'myscript'是您要插入新Script元素之前的某个元素的ID)
据我所知,你不能。如果标记看起来像
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
Run Code Online (Sandbox Code Playgroud)
您无法从内访问第二个脚本元素first.js,因为在第一个脚本运行时它尚未添加到 DOM(即使您将 分配id给第二个元素也不会)。代码second.js是放在内联还是放在外部文件中都没有关系。
我唯一不明白的是你的第二点。首先你说你不能控制文档的标记,但是你说可以second.js动态加载(使用 AJAX)。
| 归档时间: |
|
| 查看次数: |
18179 次 |
| 最近记录: |