In this article, I will talk about new products in the DOM API that we can use now or in the near future.
The publication of the article is timed to the joyful event of the beginning of the
implementation of some new DOM4 API methods in Google Chrome. Many methods and properties can be used now, some of them work through prefixes, but for each method or property I will try to give Polyfill, which implements them or discards browser prefixes.
I tried to describe the methods in accordance with the
JSDoc for Google Closure Compiler .
DOM4 Mutation methods
SpecificationElement.prototype
has a number of very interesting methods that will be familiar to jQuery lovers, but they work a little differently.
')
append(...{(Node|string)})
prepend(...{(Node|string)})
before(...{(Node|string)})
after(...{(Node|string)})
This method inserts into the current node an n-number number of nodes. Nodes are passed as function arguments (For example: node.append(otherNode1, otherNode2)
.
With this, you can pass the text instead of the node, and it is automatically converted to TextNode , as if you had called document.createTextNode(text)
.
The append
function inserts nodes at the end of its node list, prepend
— at the beginning, and before
and after
functions — before and after the current node, respectively.
remove()
The method deletes the current node from the parent.replace(...{(Node|string)})
The method replaces the current node with one or more nodes, which are specified as method parameters.
All of these methods have no return value.
Here such a pattern will allow you to pass to this method a
NodeList or an array with nodes:
element.append.apply(element, document.querySelectorAll("div"))
Two of these six methods have been added to the
document
:
append
and
prepend
.
Of all the DOM4 Mutation methods, only
remove
implemented in the latest version of Google Chrome.
Polyfill of these methods for all browsers is in my library .DOM Selector API 2: NodeRef and: scope
Specificationdocument.querySelector(string, NodeRef{(Node|NodeList|Array.<Node>)})
document.querySelectorAll(string, NodeRef{(Node|NodeList|Array.<Node>)})
document.find(string, NodeRef{(Node|NodeList|Array.<Node>)})
document.findAll(string, NodeRef{(Node|NodeList|Array.<Node>)})
Good old querySelector [All] methods acquired the second parameter, but only in the implementation for
document
. And also added new find [All] methods.
The second parameter allows you to specify the context in which we will look for nodes on the selector. For example:
document.findAll("li", [ulElement1, ulElement2])
Finds all
<li>
elements in two
ulElement1 and
ulElement2 elements .
Pseudo class
: scope allows you to do really cool things. This is another way to specify the search context - it points to the current element in which we are searching by the selector.
It allows you to search by previously non-valid selectors "> .class" or "~ tagname". Just specify
: scope at the beginning and these selectors will become valid. All power
: scope visible when
we apply it with NodeRef:
document.querySelectorAll(":scope > p", [divElement1, divElement2])
Find all the
direct children with the
p tag
divElement1 and
divElement2 ! I want to note that you can
findAll
pseudo-class
: scope for the
find
and
findAll
. For these methods, such a call is considered valid:
document.findAll("> p", [divElement1, divElement2])
WebKit currently supports the pseudo-class: scope, but it does it
wrong . The good news is that after my bug report, the wrong support
: scope will be removed . If you still need to check the real support for this pseudo-class, here is the code for this:
gist .
I now support find[All]
and : scope in the querySelectorAll
that conforms to the specification.Element.prototype.matches
SpecificationThis method was previously called
matchesSelector . It checks the node for compliance with the CSS selector.
Small polyfill with browser prefix drop: gist . More advanced option in my library .SpecificationDOM API for working with CSS element classes.
Methods:
add(...class{string})
Adds a class to element.className
remove(...class{string})
Removes a class from element.className
toggle(boolean: class{string})
Removes the class , if present, from element.className and returns false . Adds in case of its absence in element.className and returns true .contains(boolean: class{string})
Checks the class for its presence in element.className . Returns true or false, respectively.
Previously, the
add
and
remove
methods worked with only one class at a time, and recently the
ability to work with several CSS classes was
added to the standard:
document.documentElement.classList.add("test1", "test2", "test3") document.documentElement.classList.remove("test1", "test2", "test3")
Polyfill for classList
, while old specification, is in my library . A new version that will patch the old implementation will be available soon.Events Constructor
SpecificationThe new standard DOM API defines event constructors. Now we can forget about torment with
event = document.createEvent("click") event.initMouseEvent( )
And just write:
event = new Event("click")
In the constructor, we can pass any text value as
e.type
, the second parameter is the object that contains the initialization parameters
bubbles and
cancelable .
bubbles set to
false will prevent the event from floating up.
cancelable set to
false will prevent the event from being canceled via the
preventDefault
method.
By default,
bubbles and
cancelable are
false .
event = new Event("some:event", {bubbles : true, cancelable : false}) event = new Event("dbclick1") element.dispachEvent(event)
If you need to add data for the handler, you just need to add it to the
event
object:
event = new Event("click") event.button = 1
I note that in this case all the events created in this way are
ordinary events, i.e.
new Event("click")
will not create a
MouseEvent , but simply an
Event .
The second class for creating events is
CustomEvent
. The use of this class differs only in that the
detail property can be passed to the initialization object.
event = new CustomEvent("somecustom:event", {bubbles : true, cancelable : false, detail : {"some data" : 123}})
The
Event
and
CustomEvent
implemented in all modern browsers (more than a year now) except Android WebKit browsers.
Polyfill for older browsers.Also, there is a discussion for special events keyboard, Drag & Drop and mouse. But while they are not implemented by any browser.
(Note:
Opera 12.10 supports the constructor for the KeyboardEvent
, but it does not work according to the specification )HTMLLabelElement.prototype.control and HTML * Element.prototype.labels for form elements
Specification for controlThe
control property contains a link to
the form element with which the given
<label>
element is associated:
label.control.value = "123"
Recall that by specification, a single
<label>
element can have only one related form element.
Specifications for labelsThe
labels property, by contrast, contains the NodeList of
<label>
elements for the form element. NodeList because, by specification, a single
form element may have several
<label>
related elements.
console.log(input.labels.length)
Properties are implemented in most browsers.
Polyfill for older browsersHTMLOlElement.prototype.reversed
SpecificationThe
reversed property of a numbered list makes the numbering go in the opposite direction. When this is taken into account the
start property. Here are simple examples that should say more words:
<ol reversed> <li> 1</li> <li> 2</li> <li> 3</li> <li> 4</li> <li> 5</li> </ol>
It will be interpreted by the browser as:
5. List item 1
4. List item 2
3. List item 3
2. List item 4
1. List item 5
And this markup:
<ol reversed start=100> <li> 1</li> <li> 2</li> <li> 3</li> <li> 4</li> <li> 5</li> </ol>
will be interpreted by the browser as:
100. List item 1
99. List item 2
98. List item 3
97. List item 4
96. List item 5
Support for the
reversed property is in Google Chrome.
For other browsers there is Polyfill .Event.prototype.stopImmediatePropagation
SpecificationThe method works similarly to the same
method from jQuery .
In short, it not only stops the ascent of an event, but it handles the event
immediately , without executing the following handlers for this event.
Only Opera up to version 12.10 does not support this method.
Polyfill for her.IE <9 support
In IE8 there are prototypes of DOM objects, so adding support there is not difficult. I rendered polyfills for IE8 into a
separate file and connect it through
Conditional Comments .
It's harder for IE6 / 7, you need to either abandon these browsers to fully or completely implement the DOM API for them, which I did, as I
mentioned in my
DOM-shim article for all browsers including IE <8 .
The article code is posted on github . If you want to help or find a mistake, make a pull request or write to me in PM. Also write in the comments if you need to consider a topic in more detail or need more examples.