108 lines
2.5 KiB
JavaScript
108 lines
2.5 KiB
JavaScript
|
/**
|
||
|
* matchesSelector v1.0.3
|
||
|
* matchesSelector( element, '.selector' )
|
||
|
* MIT license
|
||
|
*/
|
||
|
|
||
|
/*jshint browser: true, strict: true, undef: true, unused: true */
|
||
|
/*global define: false, module: false */
|
||
|
|
||
|
( function( ElemProto ) {
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
var matchesMethod = ( function() {
|
||
|
// check for the standard method name first
|
||
|
if ( ElemProto.matches ) {
|
||
|
return 'matches';
|
||
|
}
|
||
|
// check un-prefixed
|
||
|
if ( ElemProto.matchesSelector ) {
|
||
|
return 'matchesSelector';
|
||
|
}
|
||
|
// check vendor prefixes
|
||
|
var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
|
||
|
|
||
|
for ( var i=0, len = prefixes.length; i < len; i++ ) {
|
||
|
var prefix = prefixes[i];
|
||
|
var method = prefix + 'MatchesSelector';
|
||
|
if ( ElemProto[ method ] ) {
|
||
|
return method;
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
// ----- match ----- //
|
||
|
|
||
|
function match( elem, selector ) {
|
||
|
return elem[ matchesMethod ]( selector );
|
||
|
}
|
||
|
|
||
|
// ----- appendToFragment ----- //
|
||
|
|
||
|
function checkParent( elem ) {
|
||
|
// not needed if already has parent
|
||
|
if ( elem.parentNode ) {
|
||
|
return;
|
||
|
}
|
||
|
var fragment = document.createDocumentFragment();
|
||
|
fragment.appendChild( elem );
|
||
|
}
|
||
|
|
||
|
// ----- query ----- //
|
||
|
|
||
|
// fall back to using QSA
|
||
|
// thx @jonathantneal https://gist.github.com/3062955
|
||
|
function query( elem, selector ) {
|
||
|
// append to fragment if no parent
|
||
|
checkParent( elem );
|
||
|
|
||
|
// match elem with all selected elems of parent
|
||
|
var elems = elem.parentNode.querySelectorAll( selector );
|
||
|
for ( var i=0, len = elems.length; i < len; i++ ) {
|
||
|
// return true if match
|
||
|
if ( elems[i] === elem ) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
// otherwise return false
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// ----- matchChild ----- //
|
||
|
|
||
|
function matchChild( elem, selector ) {
|
||
|
checkParent( elem );
|
||
|
return match( elem, selector );
|
||
|
}
|
||
|
|
||
|
// ----- matchesSelector ----- //
|
||
|
|
||
|
var matchesSelector;
|
||
|
|
||
|
if ( matchesMethod ) {
|
||
|
// IE9 supports matchesSelector, but doesn't work on orphaned elems
|
||
|
// check for that
|
||
|
var div = document.createElement('div');
|
||
|
var supportsOrphans = match( div, 'div' );
|
||
|
matchesSelector = supportsOrphans ? match : matchChild;
|
||
|
} else {
|
||
|
matchesSelector = query;
|
||
|
}
|
||
|
|
||
|
// transport
|
||
|
if ( typeof define === 'function' && define.amd ) {
|
||
|
// AMD
|
||
|
define( function() {
|
||
|
return matchesSelector;
|
||
|
});
|
||
|
} else if ( typeof exports === 'object' ) {
|
||
|
module.exports = matchesSelector;
|
||
|
}
|
||
|
else {
|
||
|
// browser global
|
||
|
window.matchesSelector = matchesSelector;
|
||
|
}
|
||
|
|
||
|
})( Element.prototype );
|