为什么执行类似以下内容的
var videoBg;
videoBg = $('<video autoplay>');
videoBg.attr({
'src': 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
'height': 360,
'width': 640
});
导致视频在插入页面的DOM之前播放?
用户不应该注意到元素,除非它们位于DOM中的某个位置,这不是一个想法吗?
可见物体与可听物体之间的区别是什么?
答案 0 :(得分:1)
对我有意义。它被创建你只是没有呈现它。解决方法是
var videoBg;
videoBg = $('<video>');
videoBg.attr({
'src': 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
'height': 360,
'width': 640
});
$('body').append(videoBg);
videoBg.attr('autoplay', true)
编辑进一步深入了解事情,这里是Chrome时间轴的屏幕截图:
这是调用堆栈:
jQuery.extend.buildFragment @ jquery-2.1.1.js
第5089行 jQuery.parseHTML @ jquery-2.1.1.js
第8810行 jQuery.fn.init @ jquery-2.1.1.js
第2735行 jQuery @ jquery-2.1.1.js
第76行 (anonymous function) @ test.html
第28行 jQuery.Callbacks.fire @ jquery-2.1.1.js
第3073行 jQuery.Callbacks.self.fireWith @ jquery-2.1.1.js
第3185行 jQuery.extend.ready @ jquery-2.1.1.js
第3391行 completed @ jquery-2.1.1.js
第3407行 值得注意的是:
(anonymous function) @ test.html
第28行是:
videoBg = $('<video autoplay>');
更重要的是,jQuery.extend.buildFragment @ jquery-2.1.1.js
第5089行,是此块的一部分:
// Convert html into DOM nodes
} else {
tmp = tmp || fragment.appendChild( context.createElement("div") );
// Deserialize a standard representation
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
wrap = wrapMap[ tag ] || wrapMap._default;
tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
// Descend through wrappers to the right content
j = wrap[ 0 ];
while ( j-- ) {
tmp = tmp.lastChild;
}
// Support: QtWebKit
// jQuery.merge because push.apply(_, arraylike) throws
jQuery.merge( nodes, tmp.childNodes );
// Remember the top-level container
tmp = fragment.firstChild;
// Fixes #12346
// Support: Webkit, IE
tmp.textContent = "";
}
注意第tmp = tmp || fragment.appendChild( context.createElement("div") );
行
在其他地方,它指出var fragment = document.createDocumentFragment()
将我们引导至documentation on createDocumentFragment(),其中声明:
DocumentFragments是DOM节点。它们永远不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段由其所有子代替。
由于文档片段在内存中而不是主DOM树的一部分,因此将子项附加到它不会导致页面重排(计算元素的位置和几何)。因此,使用文档片段通常会带来更好的性能。
答案 1 :(得分:1)
与audio
,canvas
和其他人一样,在JavaScript中创建的<video>
元素仍然被动地发挥作用,即使它们不在渲染的DOM中。
否则
videoBg = $("<video>");
创建元素。它存在,它是功能性的。但是,它还不是你网页DOM中的某个东西。
它只是在DOM树中没有可以使其可渲染的连接。
如果您不希望autoplay
开始自动播放,请不要使用video
。而是以编程方式开始播放:
var videoBg;
videoBg = $("<video>");
videoBg.attr({
src: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
height: 360,
width: 640
});
// When you're ready...
videoBg[0].load(); // Start loading `src`
videoBg[0].play(); // And play
我注意到你添加了你的问题:
可见物体与可听物体之间的区别是什么?
从概念上讲,并没有什么不同。 <{1}}元素被浏览器视为需要以可视方式呈现的内容。
你的body
元素仍在那里并且正在播放,除了它没有连接任何会导致实际帧在你的显示器上呈现的事实。
事实上,如果您在JavaScript中创建video
并且实际上从未将其放在video
下的某个DOM树中,您仍然可以“获取”可视数据,例如,绘制body
框架到可见DOM中的video
:
canvas
对于ctx.drawImage(videoElm, 0, 0);
元素,如果不将其添加到可见DOM,它将不会呈现控件,搜索栏等。
然而,在大多数情况下,它仍会播放扬声器(因为浏览器会将声音连接到扬声器,而不管显示器上可见DOM中的audio
元素是什么)。
在很多方面,如果audio
元素没有附加到您的可见DOM,则大致相当于仅将<video>
应用于body
。