Ответ 1
BPG выглядит многообещающим. Если вы хотите в любое время обнаружить добавление элементов <img>
, из любого источника, вы можете использовать MutationObservers.
Если вы не знаете о них, они асинхронны, регистрируют подмножество всех мутаций DOM в документе и позволяют обратному вызову обрабатывать эти мутации одновременно, а не синхронно, как с DOM Events. Поэтому, если вы создаете или изменяете источник большого количества изображений в script, наблюдатель будет ждать завершения вашего script, а затем обрабатывать все новые изображения за один раз (отсюда и циклы в обратных вызовах).
Следующее предполагает, что у вас есть функция с именем doSomethingToDecode(img)
(извините, что я не собираюсь помогать с этим сейчас), которая заменяет src
img (с вероятностью) сгенерированным PNG. Он может сделать это асинхронно, это не проблема. Кроме того, вам не нужно останавливать просмотр изображения при замене его src
, пока сгенерированное замещение не заканчивается на ".bpg".
Этот первый наблюдатель будет реагировать, когда вы добавляете <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 уровня 0 document.images
. Очень старая школа, но она делает именно то, что мы хотим очень эффективно и лаконично, так почему, черт возьми, не?
Итак, сначала вы декодируете существующий <img>
с источниками bpg и наблюдаете за ними для 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
, чтобы изначально отфильтровывать мутации not ^ t20 > childList.
imgObs.observe(document.body, {subtree:true, childList:true, attributes:false})