> You brought up XPath as an alternative to JQuery's
> selectors API. JQuery (and most competing selector engines) claim to
> support most if not all of CSS3.
I have compared XPath to CSS selectors. jQuery is not compiled byte
code, and so it is too slow to be of worthy consideration. You can
easily verify the difference yourself. Just compare a complex operation
navigating the DOM from one location to a different, and not necessarily
descendent, location versus using DOM methods while separately timing
each operation against a millisecond clock. The timing difference is
staggering, especially for results in a loop and queries against an
extremely large DOM. I am only concerned with native interpreters.
> Do you intend to make a contrast with XPath-style selection? I simply
> don't see any particular reusability advantages in targeting the
> preceeding header to the button being clicked with "../../h3"
This goes to the nature of modules. In a modular environment fragments
are open to reuse in an isolated capacity compared to a wider context.
Further more if I were unsure if I should expect a h3 element or h4 I
could use a union: ../../(h3|h4)[0]
If the ascendance has changed I could use this:
ancestor::div//(h3|h4)[0]
> Actually, I think having multiple classes enhances reusability.
No, because instead of being bound to some context there is a binding to
the reuse of a name, or naming convention, in addition to the mapped
context. This overlap is in conflict with the separation of structure
and behavior principle. The reuse as addressed by your example is
reuse within a single document and does not illustrate reuse outside of
a document instance.
> Obviously if we can target specific elements easily, that's the best
> approach. But that's not always feasible. In the dynamic environment
> I'm in, it's rarely feasible.
When absolutely ever other approach has failed there are still regular
expressions, which is still arguably a faster mode of targeting than
CSS selectors and certainly faster if the CSS selector is being
Interpreted by interpreted code.
> But perhaps there's some misapprehension here. I am part of a large
> team working on a very large web application with many dynamic parts.
> One team member might be involved in tweaking the look by updating the
> markup or the CSS while others are adding functionality based on
> certain class names, and occasionally ids. Although there was a
> significant up-front design effort, the design has been changing as
> additional requirements are noted. We certainly don't have the luxury
> of locking down all the markup ahead of time. Perhaps you are able to
> do so.
This is why module patterns are becoming increasingly more popular. It
is also evidence that there is benefit in separating the application
layer from the UI layer.
> So because you have no need for it in your project it can't make sense
> in any environment?
>From a business perspective, yes, correct. If I can demonstrate a case
that negates the technical requirements for a high cost alternative then
what is the benefit for continuing forward with the high cost option? I
am sure there are some edge cases where the alternative is still the
only preferable option, but then the only next logic question is why?
in software the only thing that matters is serving the business
requirements and eliminating costs. If one approach is more costly then
it is failing its business. Cost includes maintenance hours,
refactoring duration, detraction to the user base, and so forth.
> With the right abstractions on top of the former, it could be quite
> clean. It would probably not outperform plain DOM methods and
> doesn't, to my mind, gain very much. It certainly could work. But I
> rarely have had this need either. If I want nodes to be linked, I
> usually try to do this with related ids rather than assuming a
> particular DOM relationship.
Not necessarily. The DOM is slow for two reasons:
1) It is an API outside of the JavaScript interpreter
2) There is only one document object, so while there can be many
simultaneous read operations there can only be a single write operation
to a given node at a given time.
The first of those reasons is universal to any API that JavaScript must
access whether it be the regular expression engine, XPath, or even eval.
There is a performance hit for requesting access to a separate code
interpreter. Let's consider the two prior examples:
../../h3[0]
x.parentNode.parentNode.getElementsByTagName("h3")[0]
The primary difference is that the XPath expression is a single
operation. The DOM example is three operations. This means in the
prior instruction set I have to access a foreign API one for XPath, but
three times for the DOM query. The evaluation of the instructions is
not slow, but the lookup and access for each instruction comes at a
cost. This said, it could be argued that the execution of an XPath
expression should be roughly equivalent to a regular expression
operation, which is faster than DOM methods and certainly faster than a
jQuery index.
Thanks,
Austin Cheney, CISSP
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf
Of Scott Sauyet
Sent: Friday, September 09, 2011 7:08 AM
To: The JSMentors JavaScript Discussion Group
Subject: [JSMentors] Re: spaces in attribute values
Austin Cheney wrote:
> Scott Sauyet wrote:
> Most of the advanced CSS selector examples you have provided are only
> CSS level 3, which less widely supported than XPath. Therefore many of
> arguments favoring use of CSS selectors for specific targeting less
> valid.
This entire discussion as I've understood it has been scoped to
Javascript APIs. You brought up XPath as an alternative to JQuery's
selectors API. JQuery (and most competing selector engines) claim to
support most if not all of CSS3. So they're available. Are there
environments you're using JS selector APIs where CSS3 is not available
but XPath is?
>> Funny the different things that we find essential. I use multiple
>> classes all the time for styling and for JS-hooks.
>
> I don't find this style of development to be wildly reusable outside of
> its initial context, and I certainly find it to be less efficient to
> reference than unique identifiers. I say it is less reusable because
> rarely is this style of development applied entirely outside the
> reference of some instance's structure, but because the hooks are always
> reusable those context requirements are ambiguous.
Do you intend to make a contrast with XPath-style selection? I simply
don't see any particular reusability advantages in targeting the
preceeding header to the button being clicked with "../../h3" What if
it's H4 instead? What if there's an additional SPAN necessitating
another "../"?
Actually, I think having multiple classes enhances reusability.
#notes li.debug {display: none; background:url(bug.png}}
#notes li.info {background: url(info.png);
#notes li.warn {background: url(alert.png);
<ul id="notes">
<li class="info new">You added another whatsis to your order</
li>
<li class="debug new">Attempting to add a whatsis</li>
<li class="warn">The doohickey you requested is back-ordered</
li>
<li class="debug">Attempting to add a doohickey</li>
<li class="info">You added another widget to your order</li>
<li class="debug">Attempting to update your order</li>
<li class="info">Your order was successfully processed</li>
<li class="debug">Attempting to process your order</li>
</ul>
<button id="showAllNotes">Show all</button>
var addNotes = function(notes) {
// add the notes
$(#notes li.new").performYellowFade().then(removeNewClass);
}
$(document).ready(function() {
$("#showAllNotes").click(function() {
$("#notes li.debug").show();
// change the button text to "hide", and toggle some state
here.
});
});
In the above either the addNotes or the showAll functionality could
easily be lifted out and used elsewhere. But if I were using classes
like "newDebug" as well as "debug", it would be significantly harder
to do.
>
> This means I cannot
> typically reuse functionality based on reusable identifiers without also
> reusing some of the initial document instance's structure or context,
> defeats a significant amount of reuse outside the initial document.
> This said it seems the only wildly valuable application for this style
> is reuse within the context of a single document instance, but there are
> certainly other less arbitrarily binding options available. I say this
> form of development is less efficient to execute because pointers to
> unique identifiers perform a pass/fail to the first match of a single
> node opposed to searching the entirety of a document and building out a
> result set.
Obviously if we can target specific elements easily, that's the best
approach. But that's not always feasible. In the dynamic environment
I'm in, it's rarely feasible.
>> Do you work only with static HTML? I work with dynamically-generated
>> and continually modified markup. I can never count on knowing the
>> whole class value until I already know the node.
>
> Logically you are saying you cannot know the effectuality of your design
> mistake until the causality is exposed as flawed in the wild.
I can't parse this. Do you really mean "causality" (the relationship
between cause and effect)? I can *almost* make sense of it if you
mean "casualty" (something harmed or destroyed by some event).
But perhaps there's some misapprehension here. I am part of a large
team working on a very large web application with many dynamic parts.
One team member might be involved in tweaking the look by updating the
markup or the CSS while others are adding functionality based on
certain class names, and occasionally ids. Although there was a
significant up-front design effort, the design has been changing as
additional requirements are noted. We certainly don't have the luxury
of locking down all the markup ahead of time. Perhaps you are able to
do so.
>
> I fail to
> how this makes any sense. As far as dynamically-generated and
> continually modified markup I built the following over the past weekend
> and I am working on building an API to allow custom panel creation per
> target. http://prettydiff.com/jsgui/ You can see that this contains
> dynamically generated HTML that allows for custom input without using
> any class values for identifiers.
So because you have no need for it in your project it can't make sense
in any environment?
>> I'm curious how you would do that with XPath inside myfunction.
>> `this` would refer to the button which has no id or other obvious way
>> to select the h3. How do you do it?
>
> The path is: ../../h3[0]
> The DOM equivalent is:
> x.parentNode.parentNode.getElementsByTagName("h3")[0];
>
> This would work because you already know what the button uniquely is in
> the context of the DOM without a unique identifier. This is so because
> of the known event instance and the internal reference from the event
> provided by use of the 'this' keyword.
I understand that, I was looking for how you would actually use it,
which you discuss below:
> You would still need to evaluate this in JavaScript, which could be done
> with the document.evaluate method. I have not actually used this so I
> have no idea how XPath performs in the context of JavaScript, but I
> would imagine this method leaks the instruction from a JavaScript
> interpreter to a different interpreter, such as how regular expressions
> are processed. If the performance is similar to regular expressions
> then there is a minor performance hit for each time the separate
> interpreter is accessed but a net performance gain for each operation
> removed from the JavaScript interpreter, so therefore this could be
> costly in a frequently iterating JavaScript loop, but otherwise would
> result in a massive cost savings by creating a single access point to
> the DOM in a given statement opposed to the operation of DOM methods
> where each step is a point of access. I am not sure if this method is
> supported in IE9.
So you would do something like this:
var heading = document.evaluate("../../h3", this, null,
XPathResult.ANY_TYPE, null);
to avoid something like the following (using jQuery):
var heading = $(this).parent().parent().find("h3");
With the right abstractions on top of the former, it could be quite
clean. It would probably not outperform plain DOM methods and
doesn't, to my mind, gain very much. It certainly could work. But I
rarely have had this need either. If I want nodes to be linked, I
usually try to do this with related ids rather than assuming a
particular DOM relationship.
In any case, thanks. There are some interesting ideas here to chew
over.
-- Scott
--
To view archived discussions from the original JSMentors Mailman list:
http://www.mail-archive.com/[email protected]/
To search via a non-Google archive, visit here:
http://www.mail-archive.com/[email protected]/
To unsubscribe from this group, send email to
[email protected]
--
To view archived discussions from the original JSMentors Mailman list:
http://www.mail-archive.com/[email protected]/
To search via a non-Google archive, visit here:
http://www.mail-archive.com/[email protected]/
To unsubscribe from this group, send email to
[email protected]