What does the $() function do in the following example?
function test(){
var b=$('btn1');
eval(b);
}
The $() method is not part of the JavaScript language. It is often defined in JavaScript frameworks such as jQuery and Prototype, as a DOM selector.
It is interesting to note that up to until December 2009, the ECMAScript specification used to state:
The dollar sign ($) and the underscore
(_) are permitted anywhere in an
identifier. The dollar sign is
intended for use only in mechanically
generated code. (Source)
However this "dollar sign for mechanically generated code" hint was removed from the current ECMAScript specification (ECMA 262 - 5th Edition / December 2009).
Nevertheless, the original question was probably referring to the popular DOM selectors in jQuery, Prototype, et al. Here are a few jQuery examples:
$('*'); /* This selector is a wild card method and will select all
elements in a document. */
$('#id'); /* This selector selects an element with the given ID. */
$('.class'); /* The class selector will gather all elements in the
document with the given class name. */
$('element'); /* This selector will collect all elements in a document with
the given tag name i.e. table, ul, li, a etc. */
You may want to check the following article for more examples:
jQuery selectors and examples
That's not part of ECMAScript (JavaScript). It's just a function defined by some library of yours. Usually jQuery or PrototypeJS.
I think you're dealing with a framework here.
Most frameworks include $ functions to generate custom objects from a selector or dom object.
Answering to your question, this function return the DOM object with the specified ID.
For example, if you have on your HTML:
<div id="thisIsMyDivId">This is some content</div>
You can get the DIV element using:
var myDiv = $('thisIsMyDivId');
The idea of this function is to replace the necessity of use document.getElementById to do this.
And......repeating what everyone here already did...It is not a native JS function, it is implemented on some Frameworks (Prototype and jQuery AFAIK).
Its not JS built in function, its Prototype
http://www.prototypejs.org/api/utility/dollar-dollar
$ sign is not part of javascript it is a part of a javascript framework probably jQuery
More details have a look at this article
The provided answers are simply not true.
In this picture (taken on a Chrome about:blank tab), you can clearly see there is no jQuery. And given that the document is blank, there is no PrototypeJS as well. Contrary to all other answers, this is a native JavaScript function that can be used on any website.
The following picture shows the function definition.
ƒ $(selector, [startNode]) { [Command Line API] }
If this isn't convincing enough, here's the function definition from jQuery:
ƒ (a,b) {return new n.fn.init(a,b)}
Here is the function in PrototypeJS.
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push($(arguments[i]));
return elements;
}
if (Object.isString(element))
element = document.getElementById(element);
return Element.extend(element);
}
I would disagree that this code is optimised appropriately, I would most certainly write it this way
function $(element) {
if (arguments.length > 1) {
let elements = [];
for (let i in arguments) elements.push($(arguments[i]));
return elements;
//or simply `return arguments;` without the loop and extra variable
}
return Object.isString(element) && (e = document.getElementById(element)), Element.extend(element)
}
Related
What's the easiest way to find Dom elements with a css selector, without using a library?
function select( selector ) {
return [ /* some magic here please :) */ ]
};
select('body')[0] // body;
select('.foo' ) // [div,td,div,a]
select('a[rel=ajax]') // [a,a,a,a]
This question is purely academical. I'm interested in learning how this is implemented and what the 'snags' are. What would the expected behavior of this function be? ( return array, or return first Dom element, etc ).
In addition to the custom hacks, in recent browsers you can use the native methods defined in the W3C Selectors API Level 1, namely document.querySelector() and document.querySelectorAll():
var cells = document.querySelectorAll("#score > tbody > tr > td:nth-of-type(2)");
These days, doing this kind of stuff without a library is madness. However, I assume you want to learn how this stuff works. I would suggest you look into the source of jQuery or one of the other javascript libraries.
With that in mind, the selector function has to include a lot of if/else/else if or switch case statements in order to handle all the different selectors. Example:
function select( selector ) {
if(selector.indexOf('.') > 0) //this might be a css class
return document.getElementsByClassName(selector);
else if(selector.indexOf('#') > 0) // this might be an id
return document.getElementById(selector);
else //this might be a tag name
return document.getElementsByTagName(selector);
//this is not taking all the different cases into account, but you get the idea.
};
Creating a selector engine is no easy task. I would suggest learning from what already exists:
Sizzle (Created by Resig, used in jQuery)
Peppy (Created by James Donaghue)
Sly (Created by Harald Kirschner)
Here is a nice snippet i've used some times. Its really small and neat. It has support for the all common css selectors.
http://www.openjs.com/scripts/dom/css_selector/
No there's no built in way. Essentially, if you decide to go without jQuery, you'll be replicating a buggy version of it in your code.
I am doing some experimentation with GSAP library and i found one pen by Jonathan
http://codepen.io/jonathan/pen/qxsfc
which is pretty much i needed. i forked that pen and made my own and now i am trying to convert the same in vanilla js but the first step it self is not working.
i have converted the anonymous function to a named one and called on window.onload and its working. but now i have to replace all the $ calls of jquery selector to native selectors and its not working
the moment i change
var animContainer = $('.animContainer'),
to var animContainer = document.querySelector('.animContainer'),
my pen is
`http://codepen.io/osricmacon/pen/HAnrt`
any more suggestion on how to go about converting jquery to vanilla js
querySelector stops at the first element it finds, and returns a reference to that one element (or null if it doesn't find it). A closer analogue to jQuery's $() is querySelectorAll, which looks for all matching elements and returns a NodeList (which will be empty if none were found).
Separately from that, the key thing about jQuery is that it's set-based, whereas the DOM API is not. That's probably going to be the biggest thing for you to deal with when converting the one to the other.
For example, in jQuery, this sets the HTML of all div elements to "hey":
$("div").html("hey");
The equivalent using the DOM API might look like this:
var list = document.querySelectorAll("div"); // Or .getElementsByTagName
var i;
for (i = 0; i < list.length; ++i) {
list[i].innerHTML = "hey";
}
A common approach to making that less verbose is to reuse Array's forEach function (which is ES5, but can be shimmed for older browsers), like this:
// You'd probably do this once and reuse it
var forEach = Array.prototype.forEach;
// Where you want to use it:
forEach.call(document.querySelectorAll("div"), function(div) {
div.innerHTML = "hey";
});
Or, of course, to have a toolbelt of utility functions that do that under the covers. Which is, of course, exactly what jQuery is.
Finally, in many cases jQuery reuses the same functions as both setters and getters. The html function, for instance, sets the HTML of the elements in the jQuery set when you give it an argument, but gets the HTML of the first element of the set if you don't:
$("div").html("hey"); // Sets the HTML of all divs
console.log($("div").html()); // Gets the HTML of the *first* div
Note the assymetry: Setting applies to all elements in the set, but getting applies only to the first element in the set (ignoring any others). This is true of all of the functions that do dual duty (html, css, val, attr, prop, ...).
For reference, here's an article on Creating a Custom Filter Selector with jQuery.
Introduction:
For those not familiar with jQuery's Custom Filter Selectors, here's a quick primer on what they are:
If you need a reusable filter, you can extend jQuery’s selector expressions by adding your own functions to the jQuery.expr[':'] object.
The function will be run on each element in the current collection and should return true or false (much like filter). Three bits of information are passed to this function:
The element in question
The index of this element among the entire collection
A match array returned from a regular expression match that contains important information for the more complex expressions.
Once you've extended jQuery.expr[':'], you can use it as a filter in your jQuery selector, much like you would use any of the built-in ones (:first, :last, :eq() etc.)
Here's an example where we'll filter for elements that have more than one class assigned to them:
jQuery.expr[':'].hasMultipleClasses = function(elem, index, match) {
return elem.className.split(' ').length > 1;
};
$('div:hasMultipleClasses');
Here's the fiddle: http://jsfiddle.net/acTeJ/
In the example above, we have not used the match array being passed in to our function. Let's try a more complex example. Here we'll create a filter to match elements that have a higher tabindex than the number specified:
jQuery.expr[':'].tabindexAbove = function(elem, index, match) {
return +elem.getAttribute('tabindex') > match[3];
};
$('input:tabindexAbove(4)');
Here's the fiddle: http://jsfiddle.net/YCsCm/
The reason this works is because the match array is the actual array returned from the regex that was used to parse the selector. So in our example, match would be the following array:
[":tabIndexAbove(4)", "tabIndexAbove", "", "4"]
As you can see, we can get to the value inside the parentheses by using match[3].
The Question:
In jQuery 1.8, the match array is no longer being passed in to the filter function. Since we have no access to the info being passed in, the tabindexAbove filter does not work anymore (the only difference between this fiddle and the one above, is that this uses a later version of jQuery).
So, here are several points I'd like clarified:
Is this expected behavior? Is it documented anywhere?
Does this have anything to do with the fact that Sizzle has been updated (even though it clearly states that "the old API for Sizzle was not changed in this rewrite". Maybe this is what they mean by "the removal of the now unnecessary Sizzle.filter")?
Now that we have no access to the match array, is there any other way to get to the info being passed in to the filter (in our case, 4)?
I never found any documentation in the jQuery Docs about the custom filter selectors, so I don't know where to start looking for information about this.
jQuery has added a utility for creating custom pseudos in Sizzle. It's a little more verbose, but it's much more readable than using match[3]. It also has the advantage of being more performant as you can avoid repeating tedious calculations every time an element is tested. The answer that has already been accepted is a good answer, but let me add a note to say that you can use $.expr.createPseudo instead of setting the sizzleFilter property yourself, which will save a little space.
jQuery.expr[':'].tabIndexAbove = $.expr.createPseudo(function( tabindex ) {
return function(elem) {
return +elem.getAttribute('tabindex') > tabindex;
}
});
$('input:tabIndexAbove(4)').css('background', 'teal');
jsfiddle: http://jsfiddle.net/timmywil/YCsCm/7/
This is all documented on Sizzle's github:
https://github.com/jquery/sizzle/wiki/Sizzle-Documentation
By looking at the jQuery 1.8 beta2 source and the "Extensibility" section of The New Sizzle, you have to set fn.sizzleFilter to true in order to get the pseudo argument and the context. If not, you'll just get all the elements in the arguments.
Here is the code that does the same thing as your example. Use the selector parameter passed in the function to get the pseudo argument.
Here is the working example on jsfiddle.
As mentioned in the blog post above, you can even pre-compile and cache the your selector.
var sizzle = jQuery.find;
var tabIndexAbove = function( selector, context, isXml ) {
return function( elem ) {
return elem.getAttribute("tabindex") > selector;
};
};
/*
fn.sizzleFilter is set to true to indicate that tabIndexAbove
is a function that will return a function for use by the compiler
and should be passed the pseudo argument, the context, and
whether or not the current context is xml. If this property is
not set, adding pseudos works similar to past versions of Sizzle
*/
tabIndexAbove.sizzleFilter = true;
sizzle.selectors.pseudos.tabIndexAbove = tabIndexAbove;
$('input:tabIndexAbove(4)').css('background', 'teal');
Just a note, if you're looking at the source, jQuery slightly changed the structure that the public-facing interface points to.
In jQuery 1.7.2:
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
In jQuery 1.8b2:
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
I've come across the dollar sign function over the internets and decided to use it for a javascript toggle menu. However, the "$" symbol makes my code fail.
This is what I'm trying to use:
function $() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
}
function toggle(obj) {
var el = $(obj);
el.style.display = (el.style.display != 'none' ? 'none' : '' );
}
The $ from "function $(){" seems to break the code. How do you declare this function?
If I replace $ with "anything", it works, but not as a dollar function...
The dollar sign is not a standard Javascript function, but is part of a third party library.
There are two well-known libraries which use the dollar sign in this way.
The older one is called Prototype, but the one which is currently in vogue, and most likely to be the one you've seen in use is JQuery.
Both these libraries would be used by adding a <script> tag to your HTML page, to include the library code, after which you can use their functionality.
Most of the functionality of both these libraries is contained within their respective $() functions. In the case of JQuery, you can also refer to the $() function as jQuery() to prevent namespace clashes, in the event that you wanted to use both of them.
I suggest reading up on JQuery before continuing -- JQuery is very powerful, and adds a lot of functionality, but the coding style for writing JQuery code can be quite different from regular Javascript, and can take a bit of getting used to. And that's quite apart from learning the API and finding out what it can do.
To actually answer your question -- which is how to declare $ as a function name, I suggest having a look at the JQuery source code to see how they do it. However, I managed to produce a working $() function first time I tried, like this:
var $ = function() {alert('dollar works for me');}
$();
But to be honest, I wouldn't do that. If you really want to use the $() function in the way it's being used in other sites, you need to use JQuery. It does a whole lot more than just wrapping document.getElementById().
By the way, JQuery and Prototype are not the only similar libraries out there. If you're interested in this sort of thing, you may also want to look into MooTools, YUI, and a few others.
Hope that helps.
The $ sign is a notation for various javascript frameworks (prototype/jQuery). Since replacing it with "anything else" works, you most likely have a clash between that inline function and the framework you are using.
In itself, the notation and function is correct, as the following example shows.
Open a new tab/window and enter this on the address bar:
javascript:eval("function $() { alert('hi'); } $();");
I am looking at some javascript code and it has this in a function:
$$('.CssClass').each(function(x) { .... } )
I get that the intent is to apply the anonymous function to each element with a class of CssClass, but I can't work what the $$ refers to ... and can't google for $$!
Update: thanks for the hints. The javascript comes from the iPhone look-alike library: jPint which includes the prototypejs library, and does define $$ as:
function $$() {
return Selector.findChildElements(document, $A(arguments));
}
Probably this prototype function:
$$(cssRule...) -> [HTMLElement...]
Takes an arbitrary number of CSS
selectors (strings) and returns a
document-order array of extended DOM
elements that match any of them.
http://www.prototypejs.org/api/utility#method-$$
$ is an ordinary symbol character, thus "$", "$$", "$$$" are ordinary variables.
the meaning of $ depends upon the libraries that are in use; in jQuery the $-function creates a jquery object from a css selector, e.g. $("DIV") is a collection of all DIVs in the current document.
Are you looking at a library such as mootools by chance? This is used as a short-hand to certain types of objects by accessing the DOM. They do things like $('myElement') to access page elements for example.
$ is a valid function name in javascript. So something defines a function $$ that takes a string looking for some class called .CssClass and returns a object where you call each on.
I know that jQuery defines a function called $ at least that does similar things.
Any chance you are looking at a MooTools script?
http://www.consideropen.com/blog/2008/08/30-days-of-mootools-12-tutorials-day-2-selectors/ (now owned by a domain grabber)
"The $$ lets you quickly select multiple elements and places them into an array (a type of list that lets you manipulate, retrieve, and reorder the list in all sorts of ways). You can select elements by name (such as div, a, img) or an ID, and you can even mix and match."
Most likely a shorthand function name that handles the DOM accessing of the specified arguments, whether tag name or object id.
As per above, you're likely in MooTools or jQuery.
In the browser's console, it is another way to write querySelectorAll().
Simply selects all the elements on the web page that you need and puts them in an array.
Practical examples:
Select all the elements and set an outline guide for debugging layouts [source]:
$$('*').map((A,B)=>A.style.outline=`1px solid hsl(${B*B},99%,50%`)
Print the image addresses for all the images on a webpage [source]
$$('img').forEach(img => console.log(img.src))