要使用vml,我们首先要开辟一个命名空间。以前动态创建比较麻烦
document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml', #default#vml);
ie8出现后,微软一口气升级了ie6,ie7。创建方法更简单。
document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');
它们的作用相当于把html标签搞成下面这个样子:
接着就是在样式中调用对应的css hehavior。静态代码应该是这个样子:
网上风传ie8对vml支持不友好,要放弃vml云云,主要原因在于“vml\:*”这个选择器被ie8认为不合法(反面证明ie在努力修正其 css bug)。由此,人们被迫利用v\:line, v\:rect, v\:roundrect, v\:oval这样子的联合选择器来调用相关的css hehavior。不过只要是合法选择器就可以调用css hehavior,因此这里用联合选择器实在太累赘了。我想换类选择器是否更合适点呢?试验一下,是无问题的。但仅仅是这样是渲染不出来的,由于ie8已 经重写了内核,因此此bug不是haslayout可以解决的。官方给出答案是使用display:inline-block,这样就可以强逼它继续渲染了。后来我又发现display:block也有此功效,但考虑到内联元素的问题,还是用官方的补丁吧 。至此,开辟命名空与与渲染vml元素的问题就告一段落。
再来看如何动态创建vml元素,由于是非标准,我们就用非标准的createelement方式来创建它。我们需要拼接一个字符串,作为createelement 的参数,它应该包含命名空间与类名。
var createvml = function (tagname) {
return doc.createelement('');
};
随便做了一个小工具,看看后果如何:
复制代码 代码如下:
function(){
if(!window.vml){
window.vml = {};
document.createstylesheet().addrule(.vml, behavior:url(#default#vml);display:inline-block;);
if (!document.namespaces.vml && !+\v1){
document.namespaces.add(vml, urn:schemas-microsoft-com:vml);
}
}
var vml = window.vml = function(name){
return vml.fn.create(name || rect);
}
vml.fn = vml.prototype = {
create : function(name){
this.node = document.createelement('');
return this;
},
appendto: function(parent){
if(typeof this.node !== undefined && parent.nodetype == 1){
parent.appendchild(this.node);
}
return this;
},
attr : function(bag){
for(var i in bag){
if(bag.hasownproperty(i)){
this.node.setattribute(i,bag[i])
}
}
return this;
},
css: function(bag){
var str = ;
for(var i in bag){
if(bag.hasownproperty(i))
str += i == opacity ? (filter:alpha(opacity=+ bag[i] * 100+);):(i+:+bag[i]+;)
}
this.node.style.csstext = str;
return this;
}
}
})()
最后附上三种创建vml元素的方法:
复制代码 代码如下:
var vmlelement = document.createelement('');
var vmlelement = document.createelement('xmlns=urn:schemas-microsoft.com:vml class=vml>')
var vmlelement = document.createelement('vml:' + tagname );
vmlelement.classname = vml;//最后必须把命名空间当作类名加上
//最后必须把命名空间当作类名加上