今天在这里看到一篇文章让 IE6, 7和 8支持CSS3
以前听说过htc,但一直都没在意怎么用。搜了一下,看到一篇关于htc的老文章,我想自己虽然落伍,但对自己也是新知识,而且觉得通过htc是否能解决总是和别人不同的ie 在css上的歧义呢?
从5.5版本开始,Internet Explorer(IE)开始支持Web 行为的概念。这些行为是由后缀名为.htc的脚本文件描述的,它们定义了一套方法和属性,程序员几乎可以把这些方法和属性应用到HTML页面上的任何元素上去。Web 行为是非常伟大的因为它们允许程序员把自定义的功能“连接”到现有的元素和控件,而不是必须让用户下载二进制文件(例如ActiveX 控件)来完成这个功能。Web 行为还是推荐的扩展IE对象模型和控件集的方法。微软在它的开发者站点上的DHTML 行为库栏目里提供了几个定制的Web行为。我会在本文中讨论一个比较新的Web 行为:WebService行为。
Web 服务是通过一个开放的简单对象访问协议(SOAP)来传递参数和接收返回值,以便在Web上提供接口无关的软件服务的方法。在Internet上有许多例子和文章帮助你创建Web 服务并从传统的基于窗口表单的应用程序或者在服务器端来使用这些Web 服务,但是也可以使用WebService 行为也可以在客户浏览器上使用Web 服务。
从客户浏览器调用一个Web 服务的好处包括能够得到服务器更快的响应时间,结果是生成交互能力更强的页面并让用户用起来更高兴。与传统的将表单发回服务器然后接收一个新的页面不同的是(这个过程包括重新下载图片和其它的内容),WebService行为使用XMLHTTP在后台只发送和接收与事务处理过程相关的内容,然后这些内容又可以通过DHTML和脚本进行显示。
我所知道的目前支持Web 行为的唯一一个浏览器是IE;开发者们知道避免使用只能在IE上使用的功能。但是W3C在工作草案里有这个CSS的扩展以作为未来的标准。
如果你决定现在就使用Web 行为,你可以使用下面的JavaScript函数来检测客户端是否支持这个功能:
function canUseBehaviors() {
var ua = window.navigator.userAgent;
var msiePos = ua.indexOf('MSIE');
var msieVer = 0;
var behaviorsAvailable = false;
var iHandle = 0;
if (msiePos >= 0) {
msieMajorVer = parseInt(ua.charAt(msiePos + 5));
msieMinorVer = parseInt(ua.charAt(msiePos + 7));
if (msieMajorVer >= 5) {
if (((msieMajorVer == 5) && (msieMinorVer >= 5)) ||
(msieMajorVer > 5)) {
behaviorsAvailable = true;
}
}
}
return behaviorsAvailable;
}
使用上面的函数,你可以在运行时确定是否能够使用WebService 行为来调用Web 服务并使用IE的DHTML功能来显示结果或者是把这个表单发送给服务器让服务器来完成必要的操作,然后再次生成一个完整的页面。使用CSS语法来为一个元素添加WebService行为不会影响不支持特定CSS属性的浏览器。
微软提供了一个很好的参考,程序员可以用它更好的熟悉从客户端访问Web 服务。开发者还可以在微软的站点上找到必要的HTML 组件(*.htc)文件。
有了客户端工具包中的WebService行为,开发者们可以为Web 消费者创建更丰富更具交互性的页面,它们与使用大型主机提供的Web 服务或者基于表单窗口的应用程序的企业用户的功能是一样的。这将帮助消除冗余的代码并能通过为服务提供的特定功能提高响应时间来增强用户体验的快感。
我们都知道IE6,7并不支持CSS3的属性,IE8也不能很好的支持CSS3。但是有一个小脚本能够做到,它可以让IE支持CSS3,包括:border-radius (rounded), box-shadow ( shadow), text-shadow等……
如果你需要一个支持CSS3 的box content,你需要添加一行代码:
behavior: url(ie-css3.htc);
代码:
.box {
-moz-border-radius: 15px; /* Firefox */
-webkit-border-radius: 15px; /* Safari and Chrome */
border-radius: 15px; /* Opera 10.5+, future browsers, and now also Internet Explorer 6+ using IE-CSS3 */
-moz-box-shadow: 10px 10px 20px #000; /* Firefox */
-webkit-box-shadow: 10px 10px 20px #000; /* Safari and Chrome */
box-shadow: 10px 10px 20px #000; /* Opera 10.5+, future browsers and IE6+ using IE-CSS3 */
behavior: url(ie-css3.htc); /* This lets IE know to call the script on all elements which get the 'box' class */
}
ie-css3.htc代码:
--Do not remove this if you are using-- Original Author: Remiz Rahnas Original Author URL: http://www.htmlremix.com Published date: 2008/09/24 Changes by Nick Fetchak: - IE8 standards mode compatibility - VML elements now positioned behind original box rather than inside of it - should be less prone to breakage - Added partial support for 'box-shadow' style - Checks for VML support before doing anything - Updates VML element size and position via timer and also via window resize event - lots of other small things Published date : 2010/03/14 http://fetchak.com/ie-css3 Thanks to TheBrightLines.com (http://www.thebrightlines.com/2009/12/03/using-ies-filter-in-a-cross-browser-way) for enlightening me about the DropShadow filter <public:attach event="ondocumentready" onevent="ondocumentready('v08vnSVo78t4JfjH')" /> <script type="text/javascript"> timer_length = 200; // Milliseconds border_opacity = false; // Use opacity on borders of rounded-corner elements? Note: This causes antialiasing issues // supportsVml() borrowed from http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml-or-svg-in-a-browser function supportsVml() { if (typeof supportsVml.supported == "undefined") { var a = document.body.appendChild(document.createElement('div')); a.innerHTML = '<v:shape id="vml_flag1" adj="1" />'; var b = a.firstChild; b.style.behavior = "url(#default#VML)"; supportsVml.supported = b ? typeof b.adj == "object": true; a.parentNode.removeChild(a); } return supportsVml.supported } // findPos() borrowed from http://www.quirksmode.org/js/findpos.html function findPos(obj) { var curleft = curtop = 0; if (obj.offsetParent) { do { curleft += obj.offsetLeft; curtop += obj.offsetTop; } while (obj = obj.offsetParent); } return({ 'x': curleft, 'y': curtop }); } function createBoxShadow(element, vml_parent) { var style = element.currentStyle['iecss3-box-shadow'] || element.currentStyle['-moz-box-shadow'] || element.currentStyle['-webkit-box-shadow'] || element.currentStyle['box-shadow'] || ''; var match = style.match(/^(\d+)px (\d+)px (\d+)px/); if (!match) { return(false); } var shadow = document.createElement('v:roundrect'); shadow.userAttrs = { 'x': parseInt(RegExp.$1 || 0), 'y': parseInt(RegExp.$2 || 0), 'radius': parseInt(RegExp.$3 || 0) / 2 }; shadow.position_offset = { 'y': (0 - vml_parent.pos_ieCSS3.y - shadow.userAttrs.radius + shadow.userAttrs.y), 'x': (0 - vml_parent.pos_ieCSS3.x - shadow.userAttrs.radius + shadow.userAttrs.x) }; shadow.size_offset = { 'width': 0, 'height': 0 }; shadow.arcsize = element.arcSize +'px'; shadow.style.display = 'block'; shadow.style.position = 'absolute'; shadow.style.top = (element.pos_ieCSS3.y + shadow.position_offset.y) +'px'; shadow.style.left = (element.pos_ieCSS3.x + shadow.position_offset.x) +'px'; shadow.style.width = element.offsetWidth +'px'; shadow.style.height = element.offsetHeight +'px'; shadow.style.antialias = true; shadow.className = 'vml_box_shadow'; shadow.style.zIndex = element.zIndex - 1; shadow.style.filter = 'progid:DXImageTransform.Microsoft.Blur(pixelRadius='+ shadow.userAttrs.radius +',makeShadow=true,shadowOpacity='+ element.opacity +')'; element.parentNode.appendChild(shadow); //element.parentNode.insertBefore(shadow, element.element); // For window resizing element.vml.push(shadow); return(true); } function createBorderRect(element, vml_parent) { if (isNaN(element.borderRadius)) { return(false); } element.style.background = 'transparent'; element.style.borderColor = 'transparent'; var rect = document.createElement('v:roundrect'); rect.position_offset = { 'y': (0.5 * element.strokeWeight) - vml_parent.pos_ieCSS3.y, 'x': (0.5 * element.strokeWeight) - vml_parent.pos_ieCSS3.x }; rect.size_offset = { 'width': 0 - element.strokeWeight, 'height': 0 - element.strokeWeight }; rect.arcsize = element.arcSize +'px'; rect.strokeColor = element.strokeColor; rect.strokeWeight = element.strokeWeight +'px'; rect.stroked = element.stroked; rect.className = 'vml_border_radius'; rect.style.display = 'block'; rect.style.position = 'absolute'; rect.style.top = (element.pos_ieCSS3.y + rect.position_offset.y) +'px'; rect.style.left = (element.pos_ieCSS3.x + rect.position_offset.x) +'px'; rect.style.width = (element.offsetWidth + rect.size_offset.width) +'px'; rect.style.height = (element.offsetHeight + rect.size_offset.height) +'px'; rect.style.antialias = true; rect.style.zIndex = element.zIndex - 1; if (border_opacity && (element.opacity < 1)) { rect.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity='+ parseFloat(element.opacity * 100) +')'; } var fill = document.createElement('v:fill'); fill.color = element.fillColor; fill.src = element.fillSrc; fill.className = 'vml_border_radius_fill'; fill.type = 'tile'; fill.opacity = element.opacity; // Hack: IE6 doesn't support transparent borders, use padding to offset original element isIE6 = /msie|MSIE 6/.test(navigator.userAgent); if (isIE6 && (element.strokeWeight > 0)) { element.style.borderStyle = 'none'; element.style.paddingTop = parseInt(element.currentStyle.paddingTop || 0) + element.strokeWeight; element.style.paddingBottom = parseInt(element.currentStyle.paddingBottom || 0) + element.strokeWeight; } rect.appendChild(fill); element.parentNode.appendChild(rect); //element.parentNode.insertBefore(rect, element.element); // For window resizing element.vml.push(rect); return(true); } function createTextShadow(element, vml_parent) { if (!element.textShadow) { return(false); } var match = element.textShadow.match(/^(\d+)px (\d+)px (\d+)px (#?\w+)/); if (!match) { return(false); } //var shadow = document.createElement('span'); var shadow = element.cloneNode(true); var radius = parseInt(RegExp.$3 || 0); shadow.userAttrs = { 'x': parseInt(RegExp.$1 || 0) - (radius), 'y': parseInt(RegExp.$2 || 0) - (radius), 'radius': radius / 2, 'color': (RegExp.$4 || '#000') }; shadow.position_offset = { 'y': (0 - vml_parent.pos_ieCSS3.y + shadow.userAttrs.y), 'x': (0 - vml_parent.pos_ieCSS3.x + shadow.userAttrs.x) }; shadow.size_offset = { 'width': 0, 'height': 0 }; shadow.style.color = shadow.userAttrs.color; shadow.style.position = 'absolute'; shadow.style.top = (element.pos_ieCSS3.y + shadow.position_offset.y) +'px'; shadow.style.left = (element.pos_ieCSS3.x + shadow.position_offset.x) +'px'; shadow.style.antialias = true; shadow.style.behavior = null; shadow.className = 'ieCSS3_text_shadow'; shadow.innerHTML = element.innerHTML; // For some reason it only looks right with opacity at 75% shadow.style.filter = '\ progid:DXImageTransform.Microsoft.Alpha(Opacity=75)\ progid:DXImageTransform.Microsoft.Blur(pixelRadius='+ shadow.userAttrs.radius +',makeShadow=false,shadowOpacity=100)\ '; var clone = element.cloneNode(true); clone.position_offset = { 'y': (0 - vml_parent.pos_ieCSS3.y), 'x': (0 - vml_parent.pos_ieCSS3.x) }; clone.size_offset = { 'width': 0, 'height': 0 }; clone.style.behavior = null; clone.style.position = 'absolute'; clone.style.top = (element.pos_ieCSS3.y + clone.position_offset.y) +'px'; clone.style.left = (element.pos_ieCSS3.x + clone.position_offset.x) +'px'; clone.className = 'ieCSS3_text_shadow'; element.parentNode.appendChild(shadow); element.parentNode.appendChild(clone); element.style.visibility = 'hidden'; // For window resizing element.vml.push(clone); element.vml.push(shadow); return(true); } function ondocumentready(classID) { if (!supportsVml()) { return(false); } if (this.className.match(classID)) { return(false); } this.className = this.className.concat(' ', classID); // Add a namespace for VML (IE8 requires it) if (!document.namespaces.v) { document.namespaces.add("v", "urn:schemas-microsoft-com:vml"); } // Check to see if we've run once before on this page if (typeof(window.ieCSS3) == 'undefined') { // Create global ieCSS3 object window.ieCSS3 = { 'vmlified_elements': new Array(), 'update_timer': setInterval(updatePositionAndSize, timer_length) }; if (typeof(window.onresize) == 'function') { window.ieCSS3.previous_onresize = window.onresize; } // Attach window resize event window.onresize = updatePositionAndSize; } // These attrs are for the script and have no meaning to the browser: this.borderRadius = parseInt(this.currentStyle['iecss3-border-radius'] || this.currentStyle['-moz-border-radius'] || this.currentStyle['-webkit-border-radius'] || this.currentStyle['border-radius'] || this.currentStyle['-khtml-border-radius']); this.arcSize = Math.min(this.borderRadius / Math.min(this.offsetWidth, this.offsetHeight), 1); this.fillColor = this.currentStyle.backgroundColor; this.fillSrc = this.currentStyle.backgroundImage.replace(/^url\("(.+)"\)$/, '$1'); this.strokeColor = this.currentStyle.borderColor; this.strokeWeight = parseInt(this.currentStyle.borderWidth); this.stroked = 'true'; if (isNaN(this.strokeWeight) || (this.strokeWeight == 0)) { this.strokeWeight = 0; this.strokeColor = fillColor; this.stroked = 'false'; } this.opacity = parseFloat(this.currentStyle.opacity || 1); this.textShadow = this.currentStyle['text-shadow']; this.element.vml = new Array(); this.zIndex = parseInt(this.currentStyle.zIndex); if (isNaN(this.zIndex)) { this.zIndex = 0; } // Find which element provides position:relative for the target element (default to BODY) vml_parent = this; var limit = 100, i = 0; do { vml_parent = vml_parent.parentElement; i++; if (i >= limit) { return(false); } } while ((typeof(vml_parent) != 'undefined') && (vml_parent.currentStyle.position != 'relative') && (vml_parent.tagName != 'BODY')); vml_parent.pos_ieCSS3 = findPos(vml_parent); this.pos_ieCSS3 = findPos(this); var rv1 = createBoxShadow(this, vml_parent); var rv2 = createBorderRect(this, vml_parent); var rv3 = createTextShadow(this, vml_parent); if (rv1 || rv2 || rv3) { window.ieCSS3.vmlified_elements.push(this.element); } if (typeof(vml_parent.document.ieCSS3_stylesheet) == 'undefined') { vml_parent.document.ieCSS3_stylesheet = vml_parent.document.createStyleSheet(); vml_parent.document.ieCSS3_stylesheet.addRule("v\\:roundrect", "behavior: url(#default#VML)"); vml_parent.document.ieCSS3_stylesheet.addRule("v\\:fill", "behavior: url(#default#VML)"); // Compatibility with IE7.js vml_parent.document.ieCSS3_stylesheet.ie7 = true; } } function updatePositionAndSize() { if (typeof(window.ieCSS3.vmlified_elements) != 'object') { return(false); } for (var i in window.ieCSS3.vmlified_elements) { var el = window.ieCSS3.vmlified_elements[i]; if (typeof(el.vml) != 'object') { continue; } for (var z in el.vml) { //var parent_pos = findPos(el.vml[z].parentNode); var new_pos = findPos(el); new_pos.x = (new_pos.x + el.vml[z].position_offset.x) + 'px'; new_pos.y = (new_pos.y + el.vml[z].position_offset.y) + 'px'; if (el.vml[z].style.left != new_pos.x) { el.vml[z].style.left = new_pos.x; } if (el.vml[z].style.top != new_pos.y) { el.vml[z].style.top = new_pos.y; } var new_size = { 'width': parseInt(el.offsetWidth + el.vml[z].size_offset.width), 'height': parseInt(el.offsetHeight + el.vml[z].size_offset.height) } if (el.vml[z].offsetWidth != new_size.width) { el.vml[z].style.width = new_size.width +'px'; } if (el.vml[z].offsetHeight != new_size.height) { el.vml[z].style.height = new_size.height +'px'; } } } if (event && (event.type == 'resize') && typeof(window.ieCSS3.previous_onresize) == 'function') { window.ieCSS3.previous_onresize(); } } </script>