图片的解码是在浏览器中使用JS完成的,这意味着它可以立即使用,而无需等待浏览器采用。总体而言,这似乎是一个好主意,用一些CPU时间来换取更快的下载速度通常是一个可行的折衷方案。
换出图像的used here技术是,在window.load上,遍历document.images,找到任何src属性包含以".bpg“结尾的URL的地方,并将其替换为画布。
然而,这绝对不是解决问题的唯一方法,我看到了这种技术的一些缺点,包括: a)画布和图像的布局规则不完全相同-例如,在画布上设置宽度属性意味着img和画布上的一些不同的东西,b)至少在Chrome中,缩小的图像和画布的缩放方式是不同的。
理想情况下,更好的解决方案将满足以下要求:
我想到的一些相关工具包括data:和blob: urls。
谁有使用这种“更好”技术加载BPG的工作代码示例?( Fabrice在他的示例中使用的方式并不坏,当然方法也有权衡之处,但我认为推广使用可能会更好。)
发布于 2015-02-20 08:13:12
BPG看起来确实很有前途。如果您想要在任何时间、从任何来源检测<img>元素的添加,可以使用MutationObservers。
下面假设您有一个名为doSomethingToDecode(img)的函数(抱歉,我现在不会对此提供帮助),它将img的src替换为(很可能)生成的PNG。它可以异步地做到这一点,这不是问题。此外,只要生成的替换不以".bpg“结尾,您就不需要在交换其src时停止观察图像。
当您在任何地方添加<img>后代(以及其他元素,但它忽略了这些元素)时,第一个观察者将做出反应;不幸的是,在一般情况下不可能对其进行太多优化。它必须遍历突变列表,然后遍历每个突变的新节点列表,因此会出现嵌套的for循环。但
imgObs=new MutationObserver(
function(mutations){
for(var i=0, m; m=mutations[i]; i++) if(m.addedNodes.length)
for(var j=0, img; img=m.addedNodes[j]; j++) if(img.localName=="img"){
if(img.src && /\.bpg$/.test(img.src))
doSomethingToDecode(img)
srcObs.observe(img, srcOptions)
}
}
)当您更改一个元素的src属性时,另一个观察者会做出反应,并且应该只观察<img>元素(为了获得最佳性能,它没有故障保护措施,以防您让它观察其他元素,所以不要这样做)。
srcObs=new MutationObserver(
function(mutations){
for(var i=0, m; m=mutations[i]; i++){
var img=m.target
if(img.src && /\.bpg$/.test(img.src))
doSomethingToDecode(img)
}
}
)另外,把这个放在手边,我们每次开始观察新图像时都会用到它:
var srcOptions={childList:false, attributes:true, attributeFilter:["src"]}你也可以让一个观察者对<img>元素的移除做出反应,然后停止观察它们,并释放任何与解码相关的资源源,但希望浏览器至少足够聪明,停止观察应该被垃圾收集的元素(而不是测试!)。
在加载HTML后运行此程序(不要等待整个页面都有图像和CSS等)。注意:这使用的是DOM level 0 document.images集合。非常老派,但它做的正是我们想要的,非常高效和简洁,所以为什么不见鬼呢?
因此,首先使用bpg源代码解码现有的<img>,然后观察它们的src变化:
for(var i=0, img; img=document.images[i]; i++){
if(img.src && /\.bpg$/.test(img.src))
doSomethingToDecode(img)
srcObs.observe(img, srcOptions)
}然后,这告诉第一个观察者对整个文档的<body>中的内容做出反应;不幸的是,没有tagNameFilter参数来本地过滤掉非<img> childList突变。
imgObs.observe(document.body, {subtree:true, childList:true, attributes:false})发布于 2015-02-21 05:45:09
向图像添加错误事件处理程序。在Chrome 40上,当图像丢失或浏览器不知道如何显示时会触发:
<script>
var errors = [];
function fallback(elt) {
if(errors[elt.src]) return;
// you should also extract the extension in order to test lena.bpg, lena.png, lena.jpg and not lena.bpg.png, lena.bpg.png.jpg
errors[elt.src] = true;
console.error('could not load image, falling back');
elt.src = elt.src + '.png';
// stop trying
elt.onerror= function(){};
}
</script>
<img src="test.html" onerror="fallback(this);" width=300 height=300 />优点:客户端没有内存/cpu使用率。缺点:需要在服务器上提供备用镜像。
我相信你可以在所有的img标签上声明一个全局错误监听器,所以这也适用于将来的图像。
https://stackoverflow.com/questions/27586134
复制相似问题