前端有很多方法可以将网站设置成完全灰色,可以通过调CSS样式,可以加滤镜,可以通过js控制样式等。然而,对不那么熟悉前端的后台开发或维护人员,只能从网上找办法,东拼西凑。尝试很多次,最麻烦的是IE浏览器网页死活不变灰色。下面以我解决过的一个生产问题为例,彻底解决了手工替换彩色图标、图片的尴尬且耗时的问题,支持IE浏览器。
在html中引入css样式(不支持IE显示置灰)
对于一开始没有考虑到默哀日置灰的网站,只要在每个h5网页代码中引入css样式,或者在已经引入到所有网页的公共css里面修改代码也可以。我是新建了一个css文件turngray.css,代码如下:
1 2 3 4 5 6 7 8 9 | html{ filter: gray !important; filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1); filter: grayscale(100%); -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); -o-filter: grayscale(100%); } |
说明:除了IE浏览器,我试过,这段代码对360安全浏览器、谷歌浏览器、火狐浏览器等大多数浏览器都起作用。按F12,可以看到实际起作用的是 -webkit-filter: grayscale(100%);这行代码。
接下来是在需要变灰的网页代码文件中引入css
1 | <link rel="stylesheet" type="text/css" href="../assets/css/turngray.css" /> |
(相对路径根据实际项目目录来定,此处仅仅举例)
在html引入js(支持IE)
主要是解决IE浏览器中页面死活不变灰的情况。我在网上找到grayscale.js。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | /* * -- grayscale.js -- * Copyright (C) James Padolsey (http://cn.baiwanzhan.com) * */ var grayscale = (function(){ var config = { colorProps: ['color','backgroundColor','borderBottomColor','borderTopColor','borderLeftColor','borderRightColor','backgroundImage'], externalImageHandler : { /* Grayscaling externally hosted images does not work - Use these functions to handle those images as you so desire */ /* Out of convenience these functions are also used for browsers like Chrome that do not support CanvasContext.getImageData */ init : function(el, src) { if (el.nodeName.toLowerCase() === 'img') { // Is IMG element... } else { // Is background-image element: // Default - remove background images data(el).backgroundImageSRC = src; el.style.backgroundImage = ''; } }, reset : function(el) { if (el.nodeName.toLowerCase() === 'img') { // Is IMG element... } else { // Is background-image element: el.style.backgroundImage = 'url(' + (data(el).backgroundImageSRC || '') + ')'; } } } }, log = function(){ try { window.console.log.apply(console, arguments); } catch(e) {}; }, isExternal = function(url) { // Checks whether URL is external: 'CanvasContext.getImageData' // only works if the image is on the current domain. return (new RegExp('https?://(?!' + window.location.hostname + ')')).test(url); }, data = (function(){ var cache = [0], expando = 'data' + (+new Date()); return function(elem) { var cacheIndex = elem[expando], nextCacheIndex = cache.length; if(!cacheIndex) { cacheIndex = elem[expando] = nextCacheIndex; cache[cacheIndex] = {}; } return cache[cacheIndex]; }; })(), desatIMG = function(img, prepare, realEl) { // realEl is only set when img is temp (for BG images) var canvas = document.createElement('canvas'), context = canvas.getContext('2d'), height = img.naturalHeight || img.offsetHeight || img.height, width = img.naturalWidth || img.offsetWidth || img.width, imgData; canvas.height = height; canvas.width = width; context.drawImage(img, 0, 0); try { imgData = context.getImageData(0, 0, width, height); } catch(e) {} if (prepare) { desatIMG.preparing = true; // Slowly recurse through pixels for prep, // :: only occurs on grayscale.prepare() var y = 0; (function(){ if (!desatIMG.preparing) { return; } if (y === height) { // Finished! context.putImageData(imgData, 0, 0, 0, 0, width, height); realEl ? (data(realEl).BGdataURL = canvas.toDataURL()) : (data(img).dataURL = canvas.toDataURL()) } for (var x = 0; x < width; x++) { var i = (y * width + x) * 4; // Apply Monoschrome level across all channels: imgData.data[i] = imgData.data[i+1] = imgData.data[i+2] = RGBtoGRAYSCALE(imgData.data[i], imgData.data[i+1], imgData.data[i+2]); } y++; setTimeout(arguments.callee, 0); })(); return; } else { // If desatIMG was called without 'prepare' flag // then cancel recursion and proceed with force! (below) desatIMG.preparing = false; } for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var i = (y * width + x) * 4; // Apply Monoschrome level across all channels: imgData.data[i] = imgData.data[i+1] = imgData.data[i+2] = RGBtoGRAYSCALE(imgData.data[i], imgData.data[i+1], imgData.data[i+2]); } } context.putImageData(imgData, 0, 0, 0, 0, width, height); return canvas; }, getStyle = function(el, prop) { var style = document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(el, null)[prop] : el.currentStyle[prop]; // If format is #FFFFFF: (convert to RGB) if (style && /^#[A-F0-9]/i.test(style)) { var hex = style.match(/[A-F0-9]{2}/ig); style = 'rgb(' + parseInt(hex[0], 16) + ',' + parseInt(hex[1], 16) + ',' + parseInt(hex[2], 16) + ')'; } return style; }, RGBtoGRAYSCALE = function(r,g,b) { // Returns single monochrome figure: return parseInt( (0.2125 * r) + (0.7154 * g) + (0.0721 * b), 10 ); }, getAllNodes = function(context) { var all = Array.prototype.slice.call(context.getElementsByTagName('*')); all.unshift(context); return all; }; var init = function(context) { // Handle if a DOM collection is passed instead of a single el: if (context && context[0] && context.length && context[0].nodeName) { // Is a DOM collection: var allContexts = Array.prototype.slice.call(context), cIndex = -1, cLen = allContexts.length; while (++cIndex<cLen) { init.call(this, allContexts[cIndex]); } return; } context = context || document.documentElement; if (!document.createElement('canvas').getContext) { context.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)'; context.style.zoom = 1; return; } var all = getAllNodes(context), i = -1, len = all.length; while (++i<len) { var cur = all[i]; if (cur.nodeName.toLowerCase() === 'img') { var src = cur.getAttribute('src'); if(!src) { continue; } if (isExternal(src)) { config.externalImageHandler.init(cur, src); } else { data(cur).realSRC = src; try { // Within try statement just encase there's no support.... cur.src = data(cur).dataURL || desatIMG(cur).toDataURL(); } catch(e) { config.externalImageHandler.init(cur, src); } } } else { for (var pIndex = 0, pLen = config.colorProps.length; pIndex < pLen; pIndex++) { var prop = config.colorProps[pIndex], style = getStyle(cur, prop); if (!style) {continue;} if (cur.style[prop]) { data(cur)[prop] = style; } // RGB color: if (style.substring(0,4) === 'rgb(') { var monoRGB = RGBtoGRAYSCALE.apply(null, style.match(/\d+/g)); cur.style[prop] = style = 'rgb(' + monoRGB + ',' + monoRGB + ',' + monoRGB + ')'; continue; } // Background Image: if (style.indexOf('url(') > -1) { var urlPatt = /\(['"]?(.+?)['"]?\)/, url = style.match(urlPatt)[1]; if (isExternal(url)) { config.externalImageHandler.init(cur, url); data(cur).externalBG = true; continue; } // data(cur).BGdataURL refers to caches URL (from preparation) try { var imgSRC = data(cur).BGdataURL || (function(){ var temp = document.createElement('img'); temp.src = url; return desatIMG(temp).toDataURL(); })(); cur.style[prop] = style.replace(urlPatt, function(_, url){ return '(' + imgSRC + ')'; }); } catch(e) { config.externalImageHandler.init(cur, url); } } } } } }; init.reset = function(context) { // Handle if a DOM collection is passed instead of a single el: if (context && context[0] && context.length && context[0].nodeName) { // Is a DOM collection: var allContexts = Array.prototype.slice.call(context), cIndex = -1, cLen = allContexts.length; while (++cIndex<cLen) { init.reset.call(this, allContexts[cIndex]); } return; } context = context || document.documentElement; if (!document.createElement('canvas').getContext) { context.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=0)'; return; } var all = getAllNodes(context), i = -1, len = all.length; while (++i<len) { var cur = all[i]; if (cur.nodeName.toLowerCase() === 'img') { var src = cur.getAttribute('src'); if (isExternal(src)) { config.externalImageHandler.reset(cur, src); } cur.src = data(cur).realSRC || src; } else { for (var pIndex = 0, pLen = config.colorProps.length; pIndex < pLen; pIndex++) { if (data(cur).externalBG) { config.externalImageHandler.reset(cur); } var prop = config.colorProps[pIndex]; cur.style[prop] = data(cur)[prop] || ''; } } } }; init.prepare = function(context) { // Handle if a DOM collection is passed instead of a single el: if (context && context[0] && context.length && context[0].nodeName) { // Is a DOM collection: var allContexts = Array.prototype.slice.call(context), cIndex = -1, cLen = allContexts.length; while (++cIndex<cLen) { init.prepare.call(null, allContexts[cIndex]); } return; } // Slowly recurses through all elements // so as not to lock up on the user. context = context || document.documentElement; if (!document.createElement('canvas').getContext) { return; } var all = getAllNodes(context), i = -1, len = all.length; while (++i<len) { var cur = all[i]; if (data(cur).skip) { return; } if (cur.nodeName.toLowerCase() === 'img') { if (cur.getAttribute('src') && !isExternal(cur.src)) { desatIMG(cur, true); } } else { var style = getStyle(cur, 'backgroundImage'); if (style.indexOf('url(') > -1) { var urlPatt = /\(['"]?(.+?)['"]?\)/, url = style.match(urlPatt)[1]; if (!isExternal(url)) { var temp = document.createElement('img'); temp.src = url; desatIMG(temp, true, cur); } } } } }; return init; })(); |
这有grayscale.js的前提下,我新建了turngray_IE.js。代码如下:
1 2 3 | window.onload=function(){ grayscale(document.body); } |
在需要变灰的网页代码和之间引入grayscale.js和turngray_IE.js
1 2 | <script type="text/javascript" src="../assets/js/grayscale.js" ></script> <script type="text/javascript" src="../assets/js/turngray_IE.js" ></script> |
验证是否有效果
省略。涉及到隐私,暂不展示。我试过,无论在手机端还是PC端,无论是Android 、IOS、还是Windows的终端都OK,都有网站置灰的效果。
不足之处
在IE浏览器,window.onload比较消耗客户端浏览器资源,所以加载稍微迟缓。但一般看不出来。
(声明:本人非前端开发人员,仅仅是解决问题。不喜勿喷)
补充-在网站发布系统操作更方便
思路:在一对多网站发布系统中,写一个文件管理功能,可以增加css和js文件以及修改代码,并将本地目录,即发布系统所在服务器网站母版目录,同步到所有ihs服务器或者其他类型的服务器。这样就不用登录每台网站服务器,每个文件去引入css和js了。节省了工作量。具体是在每个html引入以下3行:
然后把turngray.css、grayscale.js、turngray_IE.js放到对应的目录。(相对路径根据实际项目目录来定,此处仅仅举例)
再就是将改动的文件全部同步到各个网站服务器
注:一对多是自定义说法,表示一个发布系统多个网站服务器