/    Sign up×
Community /Pin to ProfileBookmark

Complex CSS selector into JS

Hello,

I have this complex CSS selector that I use to identify a specific tag:

[CODE]body>table:nth-of-type(3)>tbody>tr:last-child>td>table:first-of-type>tbody>tr:last-child>td:first-child[/CODE]

How could I select the same tag using Javascript? ?
If you have links to material that could help me understand how that works in JS, I would appreciate also.
Thanks!

to post a comment
JavaScript

15 Comments(s)

Copy linkTweet thisAlerts:
@Declan1991Apr 10.2009 — If you have the HTML it would be handy, because sometimes what is simple is CSS selectors is difficult in JavaScript and vice versa. Also, if it's just that one specific tag, I'd strongly suggest you put an id on it, and access it by that id in CSS and JavaScript. It's both much faster and much easier to maintain. Complex selectors based on the precise state of the DOM tree are notoriously difficult to maintain.
Copy linkTweet thisAlerts:
@calandeauthorApr 10.2009 — Hi, thanks. Yes, the selector can be found on this page: www.record.pt

Actually I have no control over the source code (it's not my web site). I am trying to create a user script. I can't add an ID in the source code. Do you know how I could select this tag using Javascript? Thanks.
Copy linkTweet thisAlerts:
@KorApr 10.2009 — <i>
</i>body&gt;table:nth-of-type(3)&gt;tbody&gt;tr:last-child&gt;td&gt;table:first-of-type&gt;tbody&gt;tr:last-child&gt;td:first-child

Let's think. If I am not wrong, that will refer: In the third TABLE, the last TR, in the unique TD, in the first nested TABLE, the last TR, the first TD.

But in javascript is more easy to count the elements by their tag name, sequential, nomatter their childNode relationship. If I am not wrong, your red colored table:

body>table:nth-of-type(3)>tbody>tr:last-child>td>[COLOR="Red"]table:first-of-type[/COLOR]>tbody>tr:last-child>td:first-child

is the 4-th TABLE element, [I]counted sequential[/I] from top to bottom, so that you may refer straight that table. Thus:
<i>
</i>var myrows=document.getElementsByTagName('table')[3].getElementsByTagName('tr');
var mycell=myrows[myrows.length-1].getElementsByTagName('td')[0];

You may also count straight the cells. Or use any other suitable combination you want...
Copy linkTweet thisAlerts:
@dmboydApr 10.2009 — You could also use XPath if the browser supports it:
var xpathExpr = '//body/table[position()=3]/tbody/tr[position()=last()]/td/table[position()=1]/tbody/tr[position()=last()]/td[position()=1]';
var cellIterator = document.evaluate(xpathExpr, document, null, XPathResult.ANY_TYPE, null);
var myCells = new Array(), currentCell = cellIterator.iterateNext();
while (currentCell) {
myCells.push(currentCell);
currentCell = cellIterator.iterateNext();
}


Then you can just loop through the myCells array. Each array item would be a reference to the DOM nodes collected, which in this case would be an array of table cells.

If IE could make use of the .NET framework, it might be possible with IE as well as Firefox, Opera, Chrome, Safari and other browsers that don't use IE's engine, but it is too much trouble to even consider trying since IE apparently refuses to evaluate XPath expressions on HTML documents (since the page's media type specifies that is exactly what it is), forcing us to load the document a second time by creating a new ActiveXObject for the DOMDocument and loading it through JScript that way...

In other words, this won't work in IE; only Firefox and a number of other browsers have the tools to get the job done right.
Copy linkTweet thisAlerts:
@calandeauthorApr 10.2009 — Thanks, guys. I see. How can I differenciate a DIV from another one that has align="left" for instance? Is there a way to identify such a DIV in Javascript? Is it also possible to combine several criteria such as: A DIV that has align="left" and that is 10px wide?
Copy linkTweet thisAlerts:
@dmboydApr 10.2009 — The XPath solution I posted could also work for DIV[@align="left"]:
var xpathExpr = '//div[@align="left"]';
var xpathIter = document.evaluate(xpathExpr, document, null, XPathResult.ANY_TYPE, null);
var myDiv, currentDiv = xpathIter.iterateNext();
while (currentDiv) {
if (currentDiv.clientWidth == 10) {
myDiv = currentDiv;
break;
}
currentDiv = xpathIter.iterateNext();
}
// Do something with 'myDiv'.


Unfortunately, I don't know of any other way except using getElementsByTagName('div') and going through every single one until you encounter one that has an attribute named 'align' with a value of 'left'. Then you would still need to check to see if it is 10 pixels wide.
Copy linkTweet thisAlerts:
@Jeff_MottApr 10.2009 — Hi calande,

Others here have tried manually reducing the selector to DOM methods. And if one of those solutions works and needs only a couple lines, then great. But if those attempts don't work quite right, then you should consider using a library like jQuery. jQuery lets you select elements using selectors just like what you have.

&lt;script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;

$(document).ready(function(){

<i> </i>$("body&gt;table:eq(2)&gt;tbody&gt;tr:last-child&gt;td&gt;table:first-of-type&gt;tbody&gt;tr:last-child&gt;td:first-child").eq(0).[i]someJQueryMethod()[/i];

<i> </i>// or

<i> </i>var domNode = $("body&gt;table:eq(2)&gt;tbody&gt;tr:last-child&gt;td&gt;table:first-of-type&gt;tbody&gt;tr:last-child&gt;td:first-child")[0];

});

&lt;/script&gt;


You can read the [url=http://docs.jquery.com/Main_Page]jQuery docs[/url] to learn more.
Copy linkTweet thisAlerts:
@Jeff_MottApr 10.2009 — Also, with jQuery, you can easily find a DIV based on your criteria.

$("div[align='left']").filter(function(){ return $(this).width() == 10 });
Copy linkTweet thisAlerts:
@Declan1991Apr 10.2009 — jQuery will do it, but be aware that jQuery is just that someone else has written JavaScript so that you can use CSS selectors. It's my personal preference to use JavaScript selectors to select elements in JavaScript, because as Kor demonstrated, you can skip a number of steps that are necessary in CSS.

jQuery will do the job alright, but don't be fooled, it'll take just as long in the browser (if not longer), as the code that Kor has shown you. The only difference is that you are using CSS logic to select the element (instead of the logic of the DOM selectors that are available), and that you only have to write one line. That's the plus of using any library to do the selecting for you, and jQuery is just one of a multitude of libraries.
Copy linkTweet thisAlerts:
@Jeff_MottApr 10.2009 — jQuery will do the job alright, but don't be fooled, it'll take just as long in the browser (if not longer), as the code that Kor has shown you.[/quote]

As it happens, nobody said it would execute faster. It's meant only to make the developer's job easier.
Copy linkTweet thisAlerts:
@KorApr 10.2009 — Any javascript framework, as JQuery, uses nothing but javascript language in its core. Behind what you may think it is a single line of code there are the same straight and trusty javascript code lines hidden in the framework's library. Usually much too many. Feel free to use the genuine (clear javascript) or the prefab (the framework). It is up to your wish: do it professional, or do it quickly?
Copy linkTweet thisAlerts:
@dmboydApr 10.2009 — Much of the code is probably browser-specific too (though in some browsers' cases, it isn't necessarily the JS library's fault). Not to rehash a previous point, but JavaScript libraries like that tend to be slower than the "native code" that is built into the browser's JS engine.

I'll admit that I'm not really a fan of utility libraries, even in the preprocessed and compiled worldw of C and C++ where libraries can have a much greater benefit. I can always implement something quick and dirty to get the job done on the target platform rather than letting a library check if feature X is available and executing the resulting code if it is, otherwise check for feature Y in compiler Z, etc., all of which is happening at run/execution time... It's still faster than JavaScript, but it is useless code that is compiled into the application.

My point is that JavaScript libraries tend to focus on more than one browser, such as IE 6 (which is severely outdated and should be dead already) all the way up to newer browsers like Firefox 3.x, Opera 9.x and others. Why mess with a library when you can write something straightforward for your target platform(s)? My target with the XPath code was pretty much anything that can deal with XPath via JavaScript as documented and maintained by Mozilla. That includes any browser with a Gecko 1.9 back-end and JavaScript support, Opera 9, any browser built using a reasonably recent version of Webkit like Safari and Chrome... As I said, that's pretty much anything except IE and anything that uses its Trident engine (Maxthon, MyIE, etc.)

Those are just my thoughts... Use what you like, but I prefer coding for browsers instead of coding for mummies with make-up and piles of dust.
Copy linkTweet thisAlerts:
@Jeff_MottApr 10.2009 — My target with the XPath code was pretty much anything ... except IE[/quote]

Unfortunately that means your code won't work for 65-85&#37; of users (depending on where you get your stats). I don't think any client would ever be okay with that, nor should any developer.
Copy linkTweet thisAlerts:
@dmboydApr 10.2009 — Unfortunately that means your code won't work for 65-85% of users (depending on where you get your stats). I don't think any client would ever be okay with that, nor should any developer.[/quote]
You're right about that. I definitely wouldn't be okay with that if it was meant to provide core functionality to a page I created, which I wouldn't do in the first place since it's a bad practice. However, it's for a user script, like the Greasemonkey add-on for Firefox might use. Yes, there is [url=http://www.gm4ie.com/]Greasemonkey for IE[/url], but not all original Greasemonkey scripts will work with that IE add-on, right? The same is true of the script I provided.

In an effort to go back to being on-topic, I'll simply say that the suggestion to use jQuery is excellent, especially since it'll do what the OP wanted, not to mention the bonus of allowing the same familiar selection syntax.
Copy linkTweet thisAlerts:
@calandeauthorApr 11.2009 — Thank you guys, I'll look into it. I have also this to read today: http://www.howtocreate.co.uk/tutorials/javascript/dombasics

?
×

Success!

Help @calande spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.20,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...