jQuery颜色替换工作有时,有时不工作

时间:2017-04-13 09:51:33

标签: javascript jquery html css dom

我有一个小网页,你可以在这里找到:http://gabrielaelona18.esy.es/

使用CMS,用户可以替换“主题颜色”。因此,无论是background-colorborder-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");
});

问题是,它有时会起作用,但有时它却没有。 您可以访问我上面提到的网站。如果它不是蓝色,只需重新加载几次,直到你看到蓝色。

2 个答案:

答案 0 :(得分:2)

您遇到网络(页面加载)问题。在网络标签上查看您的网站加载(Firefox)开发人员工具栏。

在那里你可以看到以下巧合:

enter image description here enter image description here

蓝线显示文档触发事件的时间点,即加载页面的整个内容。 (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

这个答案看起来像是在我的第一次编辑中确认了解决方案:

is-document-ready-also-css-ready