问题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
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属性表示是否满足
参考文献:
Retina graphics for your website