zoukankan      html  css  js  c++  java
  • matchesSelector及低版本IE中对该方法的实现

    matchesSelector用来匹配dom元素是否匹配某css selector。它为一些高级方法的实现提供了基础支持,比如事件代理,parent, closest等。

    W3C在2006年就提出了该方法草案,Firefox和Safari相继实现,比如

    <div id="wraper" class="item"></div>
    <script>
        wraper.mozMatchesSelector('div') // true 标签选择器
        wraper.mozMatchesSelector('#wraper') // true id选择器
        wraper.mozMatchesSelector('.item') // true 类选择器
    </script>
    

      

    目前除IE6-IE8,Firefox/Chrome/Safari/Opera/IE 的最新版本均已实现,但方法都带上了各自的前缀

    Chrome/Safari

    Firefox

    IE9+

    可以用特性监测来获取一个统一接口API。如下

    var matchesSelector = function() {
        var body = document.body
        return body.webkitMatchesSelector || body.msMatchesSelector || body.mozMatchesSelector || body.oMatchesSelector
    }()

    有几个细节

    1.  优先使用body.webkitMatchesSelector webkit内核占有率最高,尤其国内国产浏览器的高速引擎是webkit

    2.  这里没有优选获取body.matchesSelector,是因为该方法迄今尚未标准化

    3.  2013年2月Opera放弃Presto转向Webkit,因此把body.oMatchesSelector放在了最后以兼容老版本的Opera

    对于低版本的IE,如何实现该方法吗? 首先需要实现一个基本的CSS选择器,这里提供了一个常用选择器(id,class,tagName,attribute)的实现。

    两种情况

    1. 对于已经存在于页面里的DOM元素

    function matches(el, selector) {
    	var parent = el.parentNode
    	var match = query(selector, parent)
        var len = match.length
        if (len) {
            while (len--) {
                if (match[len] == el) {
                    return true
                }
            }
            return false
        } else {
            return false
        }
    }
    

    存在于页面的DOM元素,必定有parentNode,紧接着在父节点里查找指定的selector,如果不存在返回false,如果存在还有过滤下,如果匹配的元素和传入的el是同一个元素则返回true。

    2. 对于动态创建的元素,尚未添加到页面中

    function matches(el, selector) {
    	var tempParent = document.createElement('div')
    	tempParent.appendChild(el)
        match = query(selector, tempParent)
        tempParent.removeChild(el)
        return !!match.length
    }
    
    var pp = document.createElement('p')
    pp.id = 'pp'
    pp.className = 'pp1'
    pp.setAttribute('data-info', 'Jack')
    pp.innerHTML = 'test'
    
    matches(pp, 'p') // true
    matches(pp, '#pp') // true
    matches(pp, '.pp1') // true
    matches(pp, '[data-info=jack]') // true
    

    此时该元素师没有父元素的,这里创建了一个临时的父元素,添加子元素后再把它删掉。剩余思路同上。

    两种情况合并一起就完成了对IE9-版本浏览器的支持

    function matches(el, selector) {
    	var parent = el.parentNode
    	var match = query(selector, parent)
        var len = match.length
    
        if (parent) {
    	    if (len) {
    	        while (len--) {
    	            if (match[len] == el) {
    	                return true
    	            }
    	        }
    	        return false
    	    } else {
    	        return false
    	    }
        } else {
    		var parent = document.createElement('div')
    		parent.appendChild(el)
    	    match = query(selector, parent)
    	    parent.removeChild(el)
    	    return !!match.length 	
        }
    }
    

    最后是一个完成版本

    var matchesSelector = function() {
        var body = document.body
        var w3cMatches = body.webkitMatchesSelector || body.msMatchesSelector || body.mozMatchesSelector || body.oMatchesSelector
        
    	function matches(el, selector) {
    		return w3cMatches.call(el, selector)
    	}
    
    	function lowIEMatches(el, selector) {
    		var parent = el.parentNode
    		var match = query(selector, parent)
    	    var len = match.length
    
    	    if (parent) {
    		    if (len) {
    		        while (len--) {
    		            if (match[len] == el) {
    		                return true
    		            }
    		        }
    		        return false
    		    } else {
    		        return false
    		    }
    	    } else {
    			var parent = document.createElement('div')
    			parent.appendChild(el)
    		    match = query(selector, parent)
    		    parent.removeChild(el)
    		    return !!match.length 	
    	    }
    	}
    
    	return w3cMatches ? matches : lowIEMatches
    }()
    

      

    相关:

    http://dev.w3.org/2006/webapi/selectors-api2/#matchtesting

    https://developer.mozilla.org/zh-CN/docs/Web/API/Element.matches

    http://msdn.microsoft.com/en-us/library/ie/ff975201(v=vs.85).aspx

  • 相关阅读:
    软件系统架构演变
    PL/SQL语法
    ambari安装指南
    手把手带你使用JS-SDK自定义微信分享效果
    微信公众平台无法使用支付宝收付款的解决方案
    php创建含文件夹的zip文件
    捣鼓TinyMCE 粘贴图片并上传+Django后台
    捣鼓TinyMCE粘贴图片并上传+Flask后台
    关于Java 中Integer 和Long对象 对比的陷阱(简单却容易犯的错误)
    Java东西太多,记录一些知识点
  • 原文地址:https://www.cnblogs.com/snandy/p/3763718.html
Copyright © 2011-2022 走看看