As you know, when developing a large JS application that uses the popular jQuery library, there comes a time when the performance problem becomes acute. All efforts are thrown at the profiler's embrasure, every challenge is scrupulously examined, every functionally loaded piece of implementation is sniffed from all sides and corrected. But the trouble does not come from the direction from which 90% of developers expect it. Selectors - There's so much in this word.
Let's figure out how this magic works and why searching for DOM elements can cause a drop in application performance.

How jQuery parses a selector The library itself uses the Sizzle engine, which has a number of features, to search for elements. We will look at them. querySelectorAll() New browsers have introduced the excellent querySelectorAll() and querySelector() functions, which can search for elements using browser capabilities (in particular, those used when viewing CSS and assigning properties to elements). Works this function not in all browsers, but only in FF 3.1+, IE8+ (only in standard mode IE8), Opera 9.5+ (?) and Safari 3.1+. So Sizzle always detects the presence of this function and tries to perform any search through it. However, there are some surprises here - to successfully use querySelectorAll(), our selector must be valid.
Let me give you a simple example:
The two selectors shown are practically no different and will return the same set of elements. However, the first selector will return the result of querySelectorAll(), and the second will return the result of normal filtering by elements.
$("#my_form input")
$("#my_form input") Selector parsing and lookup If querySelectorAll() fails, Sizzle will attempt to use the normal browser functions getElementById(), getElementsByName(), getElementsByTagName() and getElementByClass(). In most cases they are enough, but (sic!) in IE< 9 getElementByClassName() поломана и использование селектора по классу приведёт к полному перебору элементов в этом браузере.
In general, Sizzle parses a selector from right to left. To illustrate this feature, here are a few examples:
$(".divs.my_class")
It will first find .my_class elements and then filter only those that have .divs in their parents. As we can see, this is a rather expensive operation, and the use of context does not solve the problem (we will talk about context below).
As I said - in most cases Sizzle will parse the selector from right to left, but not when using an element with an ID:
$("#divs .my_class")
In this case, the selector will behave as expected and the #divs element will immediately be taken for use as a context. Context The second parameter passed along with the selector to the $() function is called context. It is designed to narrow down the search for elements. However, during parsing, the context is docked at the beginning of the selector, which does not give any benefit at all. A winning combination of using context is a valid selector for querySelectorAll(), since this function can be used not only on behalf of the document, but also on the element. Then the selector with the context is figuratively transformed into the following construction:
$(".divs", document.getElementById("wrapper"));
document.getElementById("wrapper").querySelectorAll(".divs"); // if possible, use querySelectorAll()

IN in this example, if it is not possible to use querySelectorAll(), Sizzle will filter the elements by simple iteration.
One more note about the context (we’re not talking about selectors) - if you pass a jQuery object as the second parameter to the selector for the.live() function, the event will be caught on document(!), and if it’s a DOM object, then the event will only bubble up to this element . I try not to remember such subtleties, but use .delegate() .

Filters and element hierarchy To search for nested elements, you can use the following selector:
$(".root > .child")
As we know, parsing the selector and searching will start with all.child elements on the page (provided that querySelectorAll() is not available). This operation is quite expensive and we can transform the selector like this:
$(".child", $(".root")); // using context will not make searching easier
$(".root").find(".child"); // why do we need to iterate through all the elements inside .root?
$(".root").children(".child"); // the most correct option

However, if there is a need to use filters by any attributes (:visible, :eq, etc.) and the selector looks like this:
$(".some_images:visible")
then the filter will be applied last - i.e. We are again deviating from the “right to left” rule.

Results
  • If possible, use the correct selectors that match querySelectorAll()
  • Replace subordination within selectors with subqueries (.children(...), etc.)
  • Clarify the selector context
  • Filter as small a ready-made set of elements as possible
Quick selectors to you in the new year! Happy New Year to everyone!

Based on the master class

JavaScript, like CSS, has functionality that allows you to access HTML element am to transform page content. In CSS, this is achieved by writing selectors. There are several ways to organize this functionality in JavaScript, and here is one of them:

Var primaryHeadings = document.getElementsByTagName("h1");

This code extracts all h1 headers and, roughly speaking, places them in the primaryHeadings variable. If there are several headings on the page, then they will all be placed in an array.

Var ou812 = document.getElementById("eddie");

This code selects the element with id = “eddie”.

Var guitars = document.getElementsByClassName("axes");

We can also select elements by the name of their classes.

Let's add some Sizzle

Various JavaScript frameworks provide their own options for creating selectors. One of the most successful was Sizzle, which later became jQuery. Unlike its descendant, Sizzle could only work with and manipulate the DOM. If you don't need all the other jQuery functionality, you can still download Sizzle as a separate library today.

With the development of these libraries, the writing of selectors has been significantly reduced and transformed:

$("#dave").css()

This code extracts an html element with id=”dave” and allows you to work with its css styles.

Sizzle is not the only JavaScript manipulation library html code. There are also other options, for example rangy. However, in my opinion, all of the above is outdated before what awaits you further in this article.

Next level of JavaScript

Many developers started using jQuery so often that they didn’t even notice the dramatic changes in JavaScript itself.

The “JavaScript Selector API” is an official part of the HTML5 specification and can also be used when writing XHTML pages. The new syntax is very simple:

Document.querySelector("#eddie")

This code is absolutely equivalent to document.getElementById("eddie"). Not impressive? What about this:

Document.querySelector("#eddie h1 + p")

The new functionality allows you to manipulate the DOM using complex CSS expressions.

The querySelector method retrieves only the first element it encounters. To retrieve all you need to use querySelectorAll:

Var hiFrets = document.querySelectorAll("table#frets tr:nth-child(3)")

This code retrieves every third row from the table with id="frets".

A few very important points

There are several limitations that you should be aware of if you use the querySelector / All method:

Not all browsers support new functionality. If it is important for you that the code works on IE6-7, then it is better to use libraries that can manipulate the DOM: Sizzle or jQuery.

Selectors must be written very carefully, otherwise browsers will not understand them, and the above methods will return null. In general, be very careful, especially when using CSS3 selectors.

Unlike getElementsByTagName, the querySelectorAll method returns a static list of retrieved elements as they appear on the page in this moment time. This means that when making any dynamic changes to the code (adding, removing elements via JavaScript), you will need to use the querySelectorAll method again.

Try new functionality to get rid of the need to download various kinds of libraries.

Last update: 11/1/2015

To work with the DOM structure in JavaScript, the document object is used, which is defined in the global window object. The document object provides a number of properties and methods for managing page elements.

Search for elements

The following methods are used to search for elements on a page:

    getElementById(value) : selects the element whose id attribute is value

    getElementsByTagName(value) : selects all elements whose tag is value

    getElementsByClassName(value) : selects all elements that have class value

    querySelector(value) : selects the first element that matches the css selector value

    querySelectorAll(value) : selects all elements that match the css selector value

For example, let's find an element by id:

Block Header var headerElement = document.getElementById("header"); document.write("Header text: " + headerElement.innerText);

Using the call document.getElementById("header") we find the element with id="header". And using the innerText property you can get the text of the found element.

Search by specific tag:

Heading

First paragraph

Second paragraph

var pElements = document.getElementsByTagName("p"); for (var i = 0; i< pElements.length; i++) { document.write("Текст параграфа: " + pElements[i].innerText + "
"); }

Using the call document.getElementsByTagName("p") we find all paragraph elements. This call returns an array of found elements. Therefore, to get individual elements array, you need to loop through them.

If we need to get only the first element, then we can access the first element of the found collection of objects:

Var pElement = document.getElementsByTagName("p"); document.write("Paragraph text: " + pElement.innerText);

Getting an element by class:

Article title

First paragraph

Second paragraph

var articleDiv = document.getElementsByClassName("article"); console.log(articleDiv); var textElems = document.getElementsByClassName("text"); for (var i = 0; i< textElems.length; i++) { console.log(textElems[i]); }

Selection by css selector:

Abstract of the article

First paragraph

Second paragraph

var elem = document.querySelector(".annotation p"); document.write("Selector text: " + elem.innerText);

The expression document.querySelector(".annotation p") finds the element that matches the selector.annotation p . If there are several elements on the page that match the selector, the method will select the first one. As a result, the browser will display:

Article abstract First paragraph Second paragraph Selector text: Article abstract

To get all the elements for a selector, you can use the document.querySelectorAll method in a similar way, which returns an array of the elements found:

Abstract of the article

First paragraph

Second paragraph

var elems = document.querySelectorAll(".text p"); for (var i = 0; i< elems.length; i++) { document.write("Текст селектора " + i + ": " + elems[i].innerText + "
"); }

Browser output:

Article abstract First paragraph Second paragraph Selector text 0: First paragraph Selector text 1: Second paragraph

The JavaScript method document.querySelector() returns the first element in the document (an Element object) that matches the specified selector, or group of selectors. If no matches are found, null is returned.

I draw your attention to what is not allowed using CSS pseudo-elements as the value of the selector to find elements, in which case the return value will always be null .

If you need a list of all elements that match a specified selector or selectors, then use the querySelectorAll() method to do this.

The .querySelector() method is also defined on the Element object, for this reason it can be called on any element, not just the document object. The element on which it is called will be used as the root element for the search.

Browser support JavaScript syntax: document .querySelector( selectors) selectors- String Specification Selectors API Level 1 Parameter values Parameter Description
selectors The argument must match a valid selector string containing one or more selectors. When specifying multiple selectors, you must separate the values ​​with commas. In this case, the first element found from the given selectors will be selected.
If for some reason you use characters in selector names that are not part of the standard syntax CSS, then when searching such characters must be escaped using the backslash character ( "\" ). Because the backslash is also a special character ( escape) V JavaScript, then when entering a literal string it must be escaped twice. Required parameter.
Exceptions Usage example Using the JavaScript method document.querySelector() Click me First block Second block Third block function myFunc() ( let firstBlock = document .querySelector(".block "), // select an element with class block first = document .querySelector( ".first, .block "), // find the first element from the given selectors second = document .querySelector("div:nth-of-type(2) "), // select each div element that is the second child of its parent element third = document .querySelector("div:last-of-type "); // find each div element that is the last element of its parent element firstBlock.style.background = "black"; // change the background color of the element first.style.color = "red"; second.style.color = "green"; // change the text color of the element third.style.color = "blue"; // change the text color of the element)

In this example, using the onclick event attribute, when a button (HTML element) is clicked, we call the myFunc() function, which, using JavaScript The document .querySelector() method selects the following elements:

  • First element with the block class in the document and set black background color of the found element.
  • First element from the given selectors (element with class first , element with class block ) and set the text color of the found element to red. In this case it will be selected first the found element from the given selectors.
  • The element that is second child element of its parent element and set to the found element green text color.
  • The element that is the last of the elements of its parent element and is set to the found element blue text color.

The result of our example.

A task that very often faces novice JavaScript developers is selecting an element on a web page by its id attribute.

Let's say we have code on the page.

Block content.

How can you select an element with id="elem" and perform a series of actions with it?

There are several options to solve the problem. Let's look at them now.

Option 1. Use Javascript method getElementById.

There is a way to access an element by its id using “pure” javascript code, without using any third-party libraries. This method is to use the ggetElementById(“element_id”) method. Thus, we access the element we need by its id.

Let's see how this works with a simple example.

Block content. alert(document.getElementById("elem").innerHTML);

Please note that these lines of code (script) are located below the element itself. This required condition the work of this script, because Javascript code executed as the page loads. If we place the code above, we will access an element on the page that has not yet loaded, i.e. it will not yet be in the code at the time the script is executed. There are ways to avoid this, but it is beyond the scope of this article.

As a result, if everything works correctly, we will get a pop-up window. This window will display the text that is inside the div block.

Let's now see how we can solve this problem in another way.

Option 2. Using the Jquery library.

The second option for selecting an element by its id is to use the Jquery library. In practice, in modern scripts, this method is most often used. It is much more convenient and easier to remember.

In order to refer to an element by its id, you need to use the following construction:

$("#elem")

Here elem is the name contained in the id attribute.

Because We will use a third-party Javascript library called Jquery, then this library must first be included.

It is added in the section, one of the ways this can be done is to add the following line of code:

In order for the library to be loaded there must be an Internet connection.

Block content. alert($("#elem").html());

The script itself, as in the previous example, should be located below the code of the element with which you want to interact.

Thus, we have discussed two ways of how you can select an element on a web page by its id attribute and interact with it. Choose the method that suits you and put it into practice.