微信X5内核浏览器不支持-webkit-filter

一:前言

在制作7月份市民卡微信超值抢的活动中,偶遇微信浏览器跟pc端的webkit浏览器的一个区别,由于这次的实现方案跟5月份的有些区别,所以才暴露了这个问题。页面结构布局如图:

74451438853872.png
二:DOM结构

页面很简单,主图就是上面两张,另外的就是一些规范的兑换流程界面,与我们本次主题无关,当用户抢了券之后,就可以进到我的卡券里面查看已经抢到的券,继续点击兑换,就能跳转到相关商品详情页面进行优惠券的使用消费,最后这张券就变成了已兑换的灰色样式;此处的重心就是变灰,优惠券单张的DOM结构如下:

<section>
       <div>
               <div>
                 <img src="images/test.png"> <!--上传图片大小:436*220-->
                 <article>
                  <aside>我是标题</ aside >
                   <ul>
                        <li><span>现价:¥9.9</span><i>¥13.9</i></li>
                        <li>有效期至:2015/08/18</li>
                   </ul>
                 </article>
               </div>
               <div>
                     <a class="get01"></a>
                     <a class="detail"></a>
               </div>
       </div>
    <div></div>
</section>
复制代码

三:实现方案探索

根据这个文档结构,我脑海中最快浮现的是两种方式去变灰:1、直接把section整个容器使用filter滤镜变灰,因为filter不仅仅是用在img元素上,也可以在div中生效;2、给section添加上一个灰色的class,然后调整下面的每一个子元素,通过新增父容器约束样式,来实现整个子内容重新渲染。

方案1:

section.gray{
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
    -o-filter: grayscale(100%);  
    filter: grayscale(100%);
    filter: gray;
 }
复制代码

方案2:

//这里引用的图片都是用作图软件制作好的灰色图标,边框也用样式变成灰色
section.gray .item{border:1px solid #aaa;}
section.gray a.get01:before{
content:'已抢完';line-height:82px;padding-left:13px;
}
section.gray a.dui01:before{
content:'已兑换';line-height:82px;padding-left:13px;
}
section.gray  a:last-child{background: url(../images/detail_.png) 12px center no-repeat;background-size:52px 21px;}
section.gray .div{width:6px;height:112px;background: url(../images/i_.png) center center no-repeat;background-size:5.5px 112px;position:absolute;left:215px;top:0px}
section.gray  .left img{filter: gray;}
.cover{width:218px;height:112px;border:1px solid #aaa;background:#000;position:absolute;left:0;top:0;opacity:1;border-radius:6px;display:none}
section.gray .cover{display:block}
复制代码

方案1一看就是最简洁的,而且我放到chrome和QQ浏览器跑了一下,都完全OK,顺利变成灰色,但是当开发人员把页面调整完毕,部署到测试环境,通过测试公众号在微信访问的时候,测试人员发现图片根本没有变灰,通过查阅相关资料得知,腾讯的微信浏览器(x5)虽然是基于webkit内核引擎,但出于引擎在移动端的优化,有一些pc端的功能还未完全支持,就比如这个-webkit-filter、 flexbox 等等,查看其它X5兼容性问题请点击:微信浏览器X5内核css问题汇总,无奈只能绕开-webkit-filter方式,采用方案2,方案2有一个比较累赘的地方就是我们每一张彩色图片都要做一张灰色图片,这是枯燥的图片处理工作,应该避免。

由于对后台图片处理不是太了解,于是先尝试从前端角度去变灰,鉴于刚刚的css3已经失败了,开始着手js方法,首先想到的就是html5 canvas元素,然后马上查看了一下x5内核,确定它是支持画布的。开工!

四:准备工作

a. 如何往Canvas对象绘制一个DOM img

var img = document.getElementById("source");
tempContext.drawImage(img, 0, 0, width,height);//这里的width是把img的宽度缩放到多少绘制进去,高度同理,而不是画布的高和宽,因为画布已经是固定大小的,就像ps软件里面的画布跟图像一样,画布是背景,图像是我们当前绘制上去的可见对象。
复制代码

b.如何拿到Canvas对象的像素数据

var canvas = document.getElementById("canvas ");
var context = canvas. .getContext("2d");
var canvasData = context.getImageData(0, 0, canvas.width, canvas.height); //这里就表示拿到整块画布的数据,因为我们把宽跟高都传入了画布的尺寸
var imgData = canvasData.data;
复制代码

c. 灰色调:获取一个像素点RGB值r, g,b,然后再对RGB分别调整,重新赋值。

var gray = .299 * r + .587 * g + .114 * b;
复制代码

五:代码整合

    window.onload = function () {
	    $('section.gray').each(function(){
		var canvas = $(this).find('canvas').get(0);
		var image = $(this).find('img').get(0);
        // 将图片的高宽赋值给画布
        canvas.width = image.width;
        canvas.height = image.height;
        // 获得二维渲染上下文
        if (canvas.getContext) {//为了安全起见,先判断浏览器是否支持canvas
            var context = canvas.getContext("2d");
            context.drawImage(image, 0, 0,217,110);//将得到的image图像绘制在canvas对象中
            var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);//返回ImageData对象
           // alert(canvasData.width.toString());
           // alert(canvasData.height.toString());
            // 填充灰色【读取像素值和实现灰度计算】
            for (var x = 0; x < canvasData.width; x++) {
                for (var y = 0; y < canvasData.height; y++) {
                    // Index of the pixel in the array
                    var idx = (x + y * canvasData.width) * 4;
                    var r = canvasData.data[idx + 0];
                    var g = canvasData.data[idx + 1];
                    var b = canvasData.data[idx + 2];
                    // 灰度的计算
                    var gray = .299 * r + .587 * g + .114 * b;
                    // assign gray scale value
                    canvasData.data[idx + 0] = gray; // Red channel
                    canvasData.data[idx + 1] = gray; // Green channel
                    canvasData.data[idx + 2] = gray; // Blue channel
                    canvasData.data[idx + 3] = 255; // Alpha channel
                }
            }
            context.putImageData(canvasData, 0, 0); // 处理完成的数据重新载入到canvas二维对象中
        } else {
            alert("your browser does not support canvas!");
        }		
		
		}); 
    }
复制代码

六:小结

微信端的网页做到现在,多少会有些感概,个人觉得有几个css3的优秀布局都没有在微信的X5内核浏览器中实现,除了上面描述的图片变灰属性,还有一个是flex。它是css3强大的弹性盒模型,多列和多行布局非常方便。由于不支持flex,很多可以几行代码解决的布局,使用了繁琐的table结构,或者使用了div+js的结构,js是对dom的二次渲染,即消耗性能,又会有微妙的延时。总的来说还是希望微信内核在未来的版本更新中,在不影响性能的情况下,越来越接近pc的webkit,让每个前端参与微信交互时能够更加高效,跨平台,享受开发过程。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享