问题1:document的elementFromPoint方法
这个方法可以根据坐标的点来获取元素,不过是获取最上层的元素,而且浏览器兼容也是需要考虑的,因为不同的浏览器传入的参数有可能是clientx,也有可能是pagex。下面的代码就可以实现这个功能。
function init() {
document.onclick = getElement;
writeroot = document.getElementById('offsetTree');
// for iPhone
var all = document.getElementsByTagName('*')
for (var i=0;i<all.length;i++) {
all[i].onclick = getElement;
all[i].onclick = null;
}
}
function getElement(e) {
var evt = e || window.event;
try {
var el = document.elementFromPoint(evt.clientX,evt.clientY);
} catch (e) {
alert('elementFromPoint not supported by this browser');
return;
}
writeroot.value = el.nodeName;
}
init();
至于浏览器兼容的解决方法可以参见
document.elementFromPoint
问题2:document的document.scrollingElement获取浏览器滚动的距离
chrome浏览器中不管是怪异模式还是标准模式下都是通过document.body.scrollTop,而其他浏览器下标准模式下通过document.documentElement来完成的。因此在webkit浏览中我们可以通过如下属性获取:
var rootElement = document.scrollingElement || docuemnt.body;
具体可以参考Chrome 中的 document.scrollingElement
问题3:document.getClientRects属性
document.getElementById("span").onclick = function() {
var objRectList = this.getClientRects(), i = 0, length = objRectList.length;
var string = "有" + length + "个矩形\r\n";
for (var i=0; i<length; i+=1) {
string = string + "第"+ (i+1) +"个矩形: top:" + objRectList[i].top + ", right:" + objRectList[i].right + ", bottom:" + objRectList[i].bottom + ", left:" + objRectList[i].left + "\r\n";
}
alert(string);
};
返回元素的数个矩形区域,返回的结果是个对象列表,具有数组特性。这里的矩形选区只针对inline box,因此,只针对a, span, em这类标签元素。IE6, IE7还有一个问题,就是按照定义,如果是block水平标签内的文字,不过文字有多少行,返回的都是这个block水平的标签区域。但是,IE6, IE7却不走寻常路,反而“正常模样”地返回行数等。例如上面的demo页面,如果把span标签换成p标签,则其他所有浏览器返回的列表个数是1,就IE6,IE7返回的是文字行数相等的矩形区域。CSSOM视图模式(CSSOM View Module)相关整理。参考这个文章也可以学习colorDepth和pixelDepth相关知识。
问题4:一些元素常见的属性
检测webkit内核:
window.webkitURL
检测表单是否满足要求
document.forms["myform"].addEventListener('invalid', function() {
//Optional response here.
}, false);
document.forms["myform"].addEventListener('submit', function() {
document.forms["myform"].reportValidity();//返回true如果输入满足要求,否则返回false。返回false的时候触发valid事件,但是在chrome40+才行
}, false);
问题4:图像的naturalWidth和naturalHeight属性
在HTML 5中,新增加了两个用来判断图片的宽度和高度的属性,分别为.naturalWidth 和naturalHeight属性,例子如下:
var rw = myimage.naturalWidth; // 真实图片宽度
var rh = myimage.naturalHeight; //真是图片高度
但有个前提是,必须在图片完全下载到客户端浏览器才能判断,,目前在ie 9,Firefox, Chrome, Safari 和Opera都是可以使用的,如果是不支持的版本浏览器,那可以用传统方法判断,如下:
var myimage = document.getElementById("myimage");
if (typeof myimage.naturalWidth == "undefined") {
// IE 6/7/8
var i = new Image();
i.src = myimage.src;
var rw = i.width;
var rh = i.height;
}
else {
// HTML5 browsers
var rw = myimage.naturalWidth;
var rh = myimage.naturalHeight;
}
在retina.js中,如果是修改img的src,为了防止由于图片大小的变化而导致占据的空间发生变化,在设置src之前我们首先保证了了img图片占据的空间没有变化:
function forceOriginalDimensions(image) {
if (!image.hasAttribute('data-no-resize')) {
//让图片不改变原来所占据的空间!
if (image.offsetWidth === 0 && image.offsetHeight === 0) {
image.setAttribute('width', image.naturalWidth);
image.setAttribute('height', image.naturalHeight);
} else {
image.setAttribute('width', image.offsetWidth);
image.setAttribute('height', image.offsetHeight);
}
}
return image;
}
问题5:影子元素方法createShadowRoot
var host = document.querySelector('.widget');
var root = host.createShadowRoot();
root.textContent = '我在你的 div 里!';
通过这种方式可以实现创建影子DOM,具体关于shadow DOM概念请自行google
问题6:parentElement属性获取父级Element元素
/**
* Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
* @param {EventTarget|Element} targetElement
* (1)为targetElement添加一个fastClickScrollParent属性,表示当前元素所在的滚动父元素
* (2)为targetElement添加一个fastClickScrollParent属性的同时,为我们的fastClickScrollParent属性又添加一个fastClickLastScrollTop属性
* 该属性表示滚动父元素当前已经滚动的scrollTop距离
*/
FastClick.prototype.updateScrollParent = function(targetElement) {
var scrollParent, parentElement;
//获取fastClickScrollParent属性
scrollParent = targetElement.fastClickScrollParent;
// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
// target element was moved to another parent.
//用于判断一个指定的元素是否在一个scrollable layer中,如果目标元素移动到另外一个父元素时候又需要重新检查
if (!scrollParent || !scrollParent.contains(targetElement)) {
parentElement = targetElement;
do {
//如果scrollHeight>offsetHeight表示元素在垂直方向上存在滚动
if (parentElement.scrollHeight > parentElement.offsetHeight) {
scrollParent = parentElement;
targetElement.fastClickScrollParent = parentElement;
break;
}
//更新parentElement元素
parentElement = parentElement.parentElement;
} while (parentElement);
}
// Always update the scroll top tracker if possible.
//获取到了滚动的父元素后,我们要更新scrollParent的fastClickLastScrollTop属性
if (scrollParent) {
scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
}
};
问题7:firstElementChild来为head元素添加meta属性
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {//获取head
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
问题8:Node.prototype.addEventListener属性
if (!Event.prototype.stopImmediatePropagation) {
layer.removeEventListener = function(type, callback, capture) {
var rmv = Node.prototype.removeEventListener;
//获取Node元素上的prototype的removeEventListener方法
if (type === 'click') {
//callback的hijacked属性,默认是callback
rmv.call(layer, type, callback.hijacked || callback, capture);
} else {
rmv.call(layer, type, callback, capture);
}
};
//如果是click事件,那么我们获取hijacked属性,因为这个方法是用于取消冒泡的!添加事件监听的时候我们直接进行设置了
//如果不是click事件,那么我们直接回调方法就可以了,如果是click事件那么我们监听到以后停止冒泡
layer.addEventListener = function(type, callback, capture) {
var adv = Node.prototype.addEventListener;
if (type === 'click') {
//留意这里 callback.hijacked 中会判断 event.propagationStopped 是否为真来确保(安卓的onMouse事件)只执行一次
//在onMouse事件里会给 event.propagationStopped 赋值 true
adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
if (!event.propagationStopped) {
callback(event);
}
}), capture);
} else {
adv.call(layer, type, callback, capture);
}
};
}
// If a handler is already declared in the element's onclick attribute, it will be fired before
// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
// adding it as listener.
//用户自己定义的方法onclick也要添加进去,否则在点击的时候会在FastClick之前触发
if (typeof layer.onclick === 'function') {
// Android browser on at least 3.2 requires a new reference to the function in layer.onclick
// - the old one won't work if passed to addEventListener directly.
oldOnClick = layer.onclick;
layer.addEventListener('click', function(event) {
oldOnClick(event);
}, false);
layer.onclick = null;
}
}
可以通过Node.prototype直接获取原型上的方法
问题9:window.matchMedia方法
window.matchMedia("(min-width:400px)")//返回值有一个matches属性表示是否满足
参考文献: