我有一个小网页,你可以在这里找到:http://gabrielaelona18.esy.es/
使用CMS,用户可以替换“主题颜色”。因此,无论是background-color
,border-bottom-color
还是其他什么,一个小脚本都会用十六进制代码#16a085替换每种颜色。这就是代码:
$(function(){
$('html').addClass('notransition');
function colorReplace(findHexColor, replaceWith) {
// Convert rgb color strings to hex
function rgb2hex(rgb) {
if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb;
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
// Select and run a map function on every tag
$('*').map(function(i, el) {
// Get the computed styles of each tag
var styles = window.getComputedStyle(el);
// Go through each computed style and search for "color"
Object.keys(styles).reduce(function(acc, k) {
var name = styles[k];
var value = styles.getPropertyValue(name);
if (value !== null && name.indexOf("color") >= 0) {
// Convert the rgb color to hex and compare with the target color
if (value.indexOf("rgb(") >= 0 && rgb2hex(value) === findHexColor) {
// Replace the color on this found color attribute
$(el).css(name, replaceWith);
}
}
});
});
}
// Call like this for each color attribute you want to replace
colorReplace("#16a085", "#456780");
});
问题是,它有时会起作用,但有时它却没有。 您可以访问我上面提到的网站。如果它不是蓝色,只需重新加载几次,直到你看到蓝色。
答案 0 :(得分:2)
您遇到网络(页面加载)问题。在网络标签上查看您的网站加载(Firefox)开发人员工具栏。
在那里你可以看到以下巧合:
蓝线显示文档触发事件的时间点,即加载页面的整个内容。 (Specifics here.)这称为 DOMContentLoaded 事件。 See here for further details. 如链接页面中所述:
在完全加载和解析文档时会触发DOMContentLoaded事件,而无需等待样式表[...]完成加载。
所以这意味着,如果样式表及时完成,您呈现的功能可以设法覆盖颜色。如果没有,该功能甚至找不到相应的颜色代码,因为它们还没有。很简单。
这反过来意味着您应该在函数调用之前等待样式表加载。从jQuery documentation开始,即使$(document).ready()
也可能不够,相反,您必须使用$(window).on("load", function() { ... })
确保一切准备就绪。要了解加载事件,它会在网络监视器中标记为红线。
如果出于任何原因,这对您来说不合适,您当然可以将.css文件中的颜色样式作为样式标记移动到html文档中。然后,我想,它将在DOMContentLoaded上可用。
答案 1 :(得分:1)
这对我来说似乎是个时间问题。
当我打开chrome dev-tools时,我始终看到绿屏,当我关闭它时,我看到蓝屏。
如果我在脚本顶部放置一个断点,脚本顶部有一个$(function()
,一旦加载了CSS,它将再次按预期工作。
因此,为了解决您的问题,您应该只在解析样式表时运行colorReplace("#16a085", "#456780");
。
修改强>
根据this article,简单地将样式表放在javascript上方可能会为您提供帮助。
根据HTML5,DOMContentLoaded是一个纯粹的DOM就绪事件,不考虑样式表。但是,HTML5解析算法要求浏览器推迟脚本的执行,直到加载所有以前的样式表。让我们回到测试用例#2的例子:
<link rel="stylesheet" href="http://molily.de/weblog/stylesheet.css">
<script src="http://molily.de/weblog/script.js"></script>
当HTML5解析器遇到...标记时,整个解析过程将停止。首先,浏览器获取脚本资源,因为它是一个外部脚本。其次,浏览器等待加载前面的样式表。第三,JavaScript引擎运行下载的脚本代码。最后,解析器继续解析HTML文档。
编辑2
这个答案看起来像是在我的第一次编辑中确认了解决方案: