标签归档:JavaScript

用JavaScript判断IE版本号

网上抄来的,找不到原文链接了。望告知。

// ----------------------------------------------------------
// A short snippet for detecting versions of IE in JavaScript
// without resorting to user-agent sniffing
// ----------------------------------------------------------
// If you're not in IE (or IE version is less than 5) then:
//     ie === undefined
// If you're in IE (>=5) then you can determine which version:
//     ie === 7; // IE7
// Thus, to detect IE:
//     if (ie) {}
// And to detect the version:
//     ie === 6 // IE6
//     ie > 7 // IE8, IE9 ...
//     ie < 9 // Anything less than IE9
// ----------------------------------------------------------
   
// UPDATE: Now using Live NodeList idea from @jdalton
   
var ie = (function(){ 
   
    var undef, 
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');
   
    while ( 
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', 
        all[0]
    );
   
    return v > 4 ? v : undef; 
   
}());

JavaScript解析QueryString

function PageQuery(q) {
    if (q.length > 1) this.q = q.substring(1, q.length);
    else this.q = null;
    this.keyValuePairs = new Array();
    if (q) {
        for (var i = 0; i < this.q.split("&").length; i++) {
            this.keyValuePairs[i] = this.q.split("&")[i];
        }
    }
    this.getKeyValuePairs = function () { return this.keyValuePairs; }
    this.getValue = function (s) {
        for (var j = 0; j < this.keyValuePairs.length; j++) {
            if (this.keyValuePairs[j].split("=")[0] == s)
                return this.keyValuePairs[j].split("=")[1];
        }
        return false;
    }
    this.getParameters = function () {
        var a = new Array(this.getLength());
        for (var j = 0; j < this.keyValuePairs.length; j++) {
            a[j] = this.keyValuePairs[j].split("=")[0];
        }
        return a;
    }
    this.getLength = function () { return this.keyValuePairs.length; }
}
function queryString(key) {
    var page = new PageQuery(window.location.search);
    return unescape(page.getValue(key));
}

图片旋转的小例子

<script type="text/javascript">
var c1 = document.getElementById("c1");
	ctx = c1.getContext("2d"),
	image = document.createElement("IMG");
image.onload = function() {
	c1.width = image.height;
	c1.height = image.width;
	ctx.translate(0, image.width);
	ctx.rotate(270*Math.PI/180);
	ctx.drawImage(image, 0, 0);
}
image.src = "http://img1.cache.netease.com/img09/logo/logo_v1.gif";
</script>

IE应该用滤镜实现同样的效果。

rotate()这个函数接收的是弧度值。角度乘以0.017(2π/360)可以转变为弧度。

图片转转转

<!DOCTYPE html>
<html>
<head>
	<title>Demo</title>
	<style type="text/css">
		html, body {
			margin: 0;
			padding: 0;
		}
	</style>
</head>
<body>
	<canvas id="c1"></canvas>
	<script type="text/javascript">
	var image = document.createElement("IMG");
	image.onload = function() { 
		var c1 = document.getElementById("c1"), rotate = null,		
			len = Math.sqrt(Math.pow(image.width, 2) + Math.pow(image.height, 2)),
			center = {x: len / 2, y: len / 2};
		
		//判断是否为IE
		if(/*@cc_on!@*/0) {
			(function() {
				var div = document.createElement("DIV");
				div.style.position = "relative";
				div.style.marginTop = div.style.marginLeft = len / 2 + "px";
				div.appendChild(image);
				c1.parentNode.insertBefore(div, c1);
				c1.parentNode.removeChild(c1);
				c1 = null;
				
				image.style.position = "absolute";
				//设置滤镜
				image.style.filter = "progid:DXImageTransform.Microsoft.Matrix()";				
				var filter = image.filters.item(0);	
				filter.SizingMethod = "auto expand";
				filter.FilterType = "bilinear";	
				
				rotate = function(rad){
					var costheta = Math.cos(rad),
						sintheta = Math.sin(rad);	
					filter.M11 = filter.M22 = costheta;
					filter.M12 = -(filter.M21 = sintheta);
					
					//将图片的重心调节到旋转点。
					image.style.top = (-image.offsetHeight) / 2 + 'px';
					image.style.left = (-image.offsetWidth) / 2 + 'px';	
				}
			})();
		} else {
			(function() {
				var ctx = c1.getContext("2d");						
				rotate = function(rad){			
					c1.width = c1.height = len;
					ctx.translate(center.x, center.y);		
					ctx.rotate(rad);
					
					//绘制图片,并将图片的重心调节到旋转点。
					ctx.drawImage(image, -image.width / 2, -image.height / 2);
				}
			})();
		}		
		
		//开始旋转
		(function() {
			if(rotate) {
				var angle = 0;
				setInterval(function() { 				
					var	rad = ((angle++)*Math.PI / 180) % 360;
					rotate(rad) 
				}, 10);
			}
		})();
	}
	image.src = "http://img1.cache.netease.com/img09/logo/logo_v1.gif";
	</script>
</body>
</html>

点击查看DEMO

mouseenter和mouseleave

摘自jQuery的一段代码:

var withinElement = function(event) {
	// Check if mouse(over|out) are still within the same parent element
	var parent = event.relatedTarget;
	// Traverse up the tree
	while ( parent && parent != this )
		try { parent = parent.parentNode; }
		catch(e) { parent = this; }
	
	if( parent != this ){
		// set the correct event type
		event.type = event.data;
		// handle event if we actually just moused on to a non sub-element
		jQuery.event.handle.apply( this, arguments );
	}
};

附带event.relatedTarget的实现方法:

// Add relatedTarget, if necessary
if ( !event.relatedTarget && event.fromElement )
	event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;

IE6中select元素z-index的bug

通常的情况下,IE6中的select元素永远是在最上面的,即使覆盖在它上面的元素的z-index再大也不起作用。比如说有个id为div1的元素绝对定位在select元素的上面。这里假设div1的z-index比select的大,但在IE6里看上去还是select在上面,div1并不能覆盖住它。为了解决这个问题,只能在div1和select中间插入一个和div1的位置以及大小一样的iframe来达到覆盖select的效果。

网上有个叫bgiframe的jQuery插件可以达到这个效果。拿上面的例子来说,它动态的在div1里插入一个透明的iframe,iframe的尺寸是用IE特有的CSS expression计算的,这么做的好处在于iframe随时都可以保持和div1同样大小,缺点是CSS expression太占资源了,可能会导致浏览器假死,如果覆盖在select上的元素的尺寸在运行时不会改变的话,就没必要用CSS expression。所以把bgiframe的代码改了一下。

改过之后的代码,记录一下:

(function($){
  $.fn.bgIframe = $.fn.bgiframe = function(s) {
    if ($.browser.msie && /6.0/.test(navigator.userAgent)) {
      s = $.extend({
        top    : 'auto',
        left    : 'auto',
        width   : 'auto',
        height  : 'auto',
        src     : 'javascript:false;'
      }, s || {});
      var prop = function(n) {
        return n&&n.constructor==Number?n+'px':n;
      };
      return this.each(function() {
        if ( $('> iframe.bgiframe', this).length == 0 ) {
          var iframe = $('<iframe frameborder="0" tabindex="-1"></iframe>')
          .addClass("bgiframe")
          .css({
            display: 'block',
            position: 'absolute',
            zIndex: '-1',
            opacity: 0,
            top: s.top === 'auto'?
              ((this.clientTop || 0)*-1 + 'px'): prop(s.top),
            left: s.left === 'auto'?
              ((this.clientLeft || 0)*-1 + 'px'): prop(s.left),
            width: s.width === 'auto'?
              (this.offsetWidth + 'px'): prop(s.width),
            height: s.height === 'auto'?
              (this.offsetHeight + 'px'): prop(s.height)
          })
          .insertBefore(this.firstChild);
        }
      });
    }
    return this;
  };
})(jQuery);

relatedTarget, fromElement, toElement

记录一下。原文:http://www.quirksmode.org/js/events_mouse.html#relatedtarget

W3C在mouseover和mouseout事件中添加了relatedTarget属性。在mouseover事件中,它表示鼠标来自哪个元素,在mouseout事件中,它指向鼠标去往的那个元素。

而Microsoft添加了两个属性:

  • fromElement在mouseover事件中表示鼠标来自哪个元素。
  • toElement在mouseout事件中指向鼠标去往的那个元素。

跨浏览器的脚本

如果你想知道鼠标来自哪个元素在mouseover事件中,你可以这样写:

function doSomething(e) {
	if (!e) var e = window.event;
	var relTarg = e.relatedTarget || e.fromElement;
}

如果你想知道鼠标去往哪个元素在mouseout事件中,你可以这样写:

function doSomething(e) {
	if (!e) var e = window.event;
	var relTarg = e.relatedTarget || e.toElement;
}

elem.style.left与elem.offsetLeft的区别

elem.style.left是元素的最左边(包括元素的margin-left)到offsetParent左边padding(包括左边padding)的距离。

用公式简单的表示一下两者的关系:elem.offsetLeft = elem.style.left + elem.style.marginLeft

在IE8下:
elem.offsetLeft = elem.style.left + elem.style.marginLeft + elem.offsetParent.borderLeftWidth

在IE7下:
elem.offsetLeft = elem.style.left + elem.style.marginLeft + elem.offsetParent.borderLeftWidth + elem.offsetParent.marginLeftWidth

在IE6下:
elem.offsetLeft = elem.style.left + elem.style.marginLeft + elem.offsetParent.paddingLeftWidth + elem.offsetParent.borderLeftWidth + elem.offsetParent.marginLeftWidth

记录一下,如何取得元素的”计算出的样式”。

function getCurrentStyle(elem, style) {
	return window.getComputedStyle
			? window.getComputedStyle(elem, null)[style]
			: elem.currentStyle[style];
}

预览本地图片的二三事

到目前为止,只有IE和FF可以预览本地图片。IE下可以直接浏览本地图片,通过input[type=file]的value属性就可以取到本地图片的路径。而在FF下,有getAsDataURL的方法可以生成图片的DataURL,然后赋值给img标签。

IE下的演示:

document.getElementById("upload").onchange = function() {
	document.getElementById("image").src = this.value;
}

FF下的演示:

document.getElementById("upload").onchange = function() {			
	document.getElementById("image").src = this.files[0].getAsDataURL();
}

滚动页面到某个元素

MSDN上搬过来的,记录一下。

Syntax

object.scrollIntoView( [bAlignToTop])

Parameters

bAlignToTop Optional. Boolean that specifies one of the following values:
true
Default. Scrolls the object so that top of the object is visible at the top of the window.
false
Scrolls the object so that the bottom of the object is visible at the bottom of the window.

Return Value

No return value.

Remarks

The scrollIntoView method is useful for immediately showing the user the result of some action without requiring the user to manually scroll through the document to find the result.
Depending on the size of the given object and the current window, this method might not be able to put the item at the very top or very bottom, but will position the object as close to the requested position as possible.

Example

This example uses the scrollIntoView method to underline the content of the document’s fifth paragraph and scroll it into view at the top of the window.

var coll = document.all.tags("P");
if (coll.length >= 5) {
  coll(4).style.textDecoration = "underline";
  coll(4).scrollIntoView(true);
}