5

I am fairly new to jQuery and understand the basics, but I am having issues targeting certain pieces of the page so I need to fill in some gaps in knowledge.

I do understand $(this).attr('href') would get the attribute of href within the currently focused/clicked element.

But what if it’s written like this $($(this).attr('href'));?

It’s code I have in a script I didn’t write, and I’m not sure if that’s just an error or intentional.

I have a feeling this is pretty basic but how to search for $($())? And when I search for $($(this).attr('href')) all I get is documentation on the original clause which I already understand.

Is it just a typo or a separate use case?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
weekapaug
  • 332
  • 1
  • 4
  • 15
  • 1
    Possible duplicate of [Is there an easy way to convert jquery code to javascript?](https://stackoverflow.com/questions/978799/is-there-an-easy-way-to-convert-jquery-code-to-javascript) – A. Meshu Apr 07 '18 at 14:27
  • 4
    `$($(this).attr("href"))` gets the "href" attribute value and then passes that back to the jQuery function. It's just a function call; there's nothing magic about it. Why the code does that is impossible to say without seeing more of it and the HTML markup it was designed to work with. – Pointy Apr 07 '18 at 14:28
  • Right I'm not looking to analyze my code just a general explanation of why you would need to double wrap it vs. the standard way of writing it. – weekapaug Apr 07 '18 at 14:29
  • 1
    It depends on what `$(this).attr('href')` is. All that is certain is that it’s a string (or `undefined`), so it’s `$(` _some string_ `)`. Edit: Crazy Train’s comment below is very likely: it could indeed be a fragment identifier `#foo` which serves as a selector for ID `foo`. – Sebastian Simon Apr 07 '18 at 14:32
  • 7
    The `href` of the element is probably something like `#foo`, which is the same syntax as we use to select by ID. So it's basically saying, *"Fetch the element with the ID that is the same as this `href`'s hash"* –  Apr 07 '18 at 14:32
  • In native JS, you could do: `document.querySelector(this.hash)`, assuming `this` is an `` element. –  Apr 07 '18 at 14:34
  • If you want to create jquery object then you can wrap your content into **$()**, i.e. **$("hello")**, This is useful if you want to use some jquery function on that object – Alpesh Jikadra Apr 07 '18 at 14:34
  • It is indeed fetching an id, which makes sense as I review it. So its kind of like a "search for this variable" rather than "show me this variable?" – weekapaug Apr 07 '18 at 14:35
  • 1
    It's searching for an element in the DOM tree. Passing a *selector string* to the `$` function always performs a query on the DOM. –  Apr 07 '18 at 14:36
  • Crazy Trains comment turned on the light bulb first but how to accept comment as answer? – weekapaug Apr 07 '18 at 14:40
  • Yeah, go ahead and select Tristan's. I chose not to post down there this time. –  Apr 07 '18 at 14:45
  • Is voting up an answer as the OP the same as accepting? – weekapaug Apr 07 '18 at 14:47
  • @weekapaug: No, you click the checkmark to accept an answer. (You last accepted an answer to a question in October, so you may have forgotten.) – BoltClock Apr 07 '18 at 14:48

1 Answers1

6

As you said, $(this).attr('href') returns the matched element's href. That's a string. The string is then passed to $, which doesn't know it's a href so treats it as it does any other string: it parses it, decides if it looks like HTML or a selector, then returns the resulting jQuery instance.

Presumably, this is in some context where the href happens to also be either a valid selector or valid HTML. As was mentioned in comments, a likely candidate is a string like #something, which as a href links to the scroll position of the element with ID something, and as a selector tells jQuery to select the same element.

twhb
  • 4,294
  • 2
  • 20
  • 23
  • Thank you for this extra clarification it does help and you are spot on with the context that its being used! – weekapaug Apr 07 '18 at 14:43
  • If this is the intended result, it seems to me like there's probably a plausible injection attack somewhere in there. Certainly if this is the general way this site is written, then there's a good chance that it's exploitable somehow or other. – Spudley Apr 07 '18 at 14:45
  • @Spudley: I think `href`s are automatically sanitized for HTML. If I do `document.querySelector("a[href]").hash = ""` and then `document.querySelector("a[href]").hash"`, I get `"#%3Cfoo%3E"` –  Apr 07 '18 at 14:46
  • 2
    @Crazy Train: Spudley means sanitized for the purposes of the outer $() call. Depending on what the script does, unintended inputs may either do nothing, or something bad. – BoltClock Apr 07 '18 at 14:47
  • @BoltClock: Ah, using `attr()` is indeed unsafe. Using `.prop()` would be better, or better yet, accessing the property directly. –  Apr 07 '18 at 14:51
  • @Crazy Train: No, neither of those methods will help. They will all return the attribute value as is. So for an element with `href="html > body > .foo"`, however nonsensical of a URL that is, `$(...)` would return the element matched by `html > body > .foo`, despite the fact that no fragment identifier/ID selector is present in the value. – BoltClock Apr 07 '18 at 14:52
  • @Crazy Train: Even legitimate fragment identifiers don't always translate directly to valid ID selectors without being first escaped. [Here's an example.](https://stackoverflow.com/questions/35980786/why-is-id-a-bad-selector-in-css-jquery-yet-it-works-in-an-html-anchor/35981104#35981104) – BoltClock Apr 07 '18 at 14:54
  • @BoltClock thanks for pointing out the potential for vulnerability. In this case, it is just narrowing down to an anchor tag, so in this case its safe, but good to remind that href values might end being bad if you're not careful! – weekapaug Apr 07 '18 at 14:55
  • @BoltClock: I understand that not all fragment identifiers are valid selectors, but that doesn't mean it's an injection vulnerability. When I access the property instead of the attribute, it gives me a sanitized version of the original. So if the original was `#html > body`, it gives me `#html%20%3E%20body` –  Apr 07 '18 at 14:56
  • @Crazy Train: Ah, yes, you're right. In this case the href property is special-cased and will always return a fully qualified, URL-encoded, address. – BoltClock Apr 07 '18 at 14:59