Sizzle Item Selection Method Using Fully Specified URLs

While working on a script, recently I came across a special nuance of how Sizzle works with the href attribute . In particular, using the attribute selector on href , Sizzle will use the actual attribute value:

 // Will not find <a href="index.html">... $('a[href="http://www.example.com/index.html"]') 

Sizzle uses .getAttribute() instead of elem.href (more precisely, elem['href'] , Sizzle does in most cases ); elem.href will provide the full URL.

To understand this a bit, I created a script to try different forms of URLs . During testing, I discovered a (obvious) "solution" that set href to be equal to itself :

 $('a').each(function(){ this.href = this.href; }); 

Which, unsurprisingly, updates the element to reflect the fully qualified URL that this.href provides. There are other ways in which I found this work (any update to the href attribute of an element), but they simply transfer the above approach to other forms or include something like .filter() (demo) :

 var matches = $('a').filter(function(){ var window_location = 'http://example.com/services.html'; return window_location == this.href; }); 

The reason I say this is because running el.href = el.href before choosing is a workaround in a way (and one, I don't think this is a great alternative). For example, checking a set of items to search for if they contain the appropriate link to the current URL (or another URL) is easier if you can:

 $links.not('[href="' + window.location.href + '"]') 

Is there a way to do this without resorting to β€œupdating” the attributes or writing additional code to control the validation? Is there a way that I forgot that does not include changing how Sizzle works ^ ?

^ Note : changing the source code would be a (bad) idea compared to just adding expression :

 $.extend($.expr[':'], { url: function(elem, i, match){ return elem.href === match[3]; } }); var $matched = $('a:url(http://test.com/index.html)'); 

http://jsfiddle.net/yt2RU/

(And as an aside, are there other attributes with similar atypical behavior in Sizzle?)

+4
source share
1 answer

I believe that I have an answer to this question ...

Use expression :

 jQuery.extend(jQuery.expr[':'], { url: function(elem, i, match){ return elem.href === match[3]; } }); var $matched = jQuery('a:url(http://test.com/index.html)'); 

http://jsfiddle.net/yt2RU/

Or, as noted in the comments, you can use $.filter() :

 var $matched = $('a').filter(function(){ if (this.href == 'http://test.com/index.html') { return true; } return false; }); 

http://jsfiddle.net/dMuyj/

And this jQuery only returns to Sizzle if querySelector() and querySelectorAll() not initially available, and both work the same as the jQuery selector mechanism (not surprisingly).

The sum is equal to you, you need either an expression or a filter if you want this type of selector, and use elem.href for comparison, not getAttribute() .

+3
source

Source: https://habr.com/ru/post/1395710/


All Articles