There are many cross-browser pits in operating DOM for js. It took me nearly a week to sort out these pits. I will sort out the pits according to the examples.
The working mode of DOM is to load the static content of documents first and refresh them dynamically. Dynamic refresh does not affect the static content of documents.
PS: All DOM objects in IE are implemented as COM objects, which means that DOM in IE may be different from other browsers.
Node interface
Characteristics/methods | Type/return type | Explain |
---|---|---|
nodeName | String | The name of the node; defined according to the type of node |
nodeValue | String | The value of a node; defined according to the type of node |
nodeType | Number | One of the type constants of nodes |
ownerDocument | Document | Returns the root element of an element |
firstChild | Node | Point to the first node in the childNodes list |
lastChild | Node | Point to the last node in the child Nodes list |
childNodes | NodeList | List of all subnodes |
previousSibling | Node | Returns the previous sibling node of the selected node, or null if it does not exist |
nextSibling | Node | Returns the next sibling node of the selected node, or null if it does not exist |
hasChildNodes() | Boolean | If the current element node has child nodes, return true or false |
attributes | NamedNodeMap | Returns the Named NodeMap containing the properties of the selected node |
appendChild(node) | node | Add node to the end of child Nodes |
removeChild(node) | node | Delete node from childNodes |
replaceChild(newnode, oldnode) | Node | Replace oldnode in childNodes with newnode |
insertBefore | Node | Insert new child nodes before existing ones |
First Child is equivalent to childNodes[0]; last Child is equivalent to childNodes[box.childNodes.length]. - 1].
NoeType returns the type of node
Element node returns 1 Attribute node returns 2 - Text node returns 3
Inner HTML and nodeValue
For text nodes, the nodeValue attribute contains text. For attribute nodes, the nodeValue attribute contains attribute values. The nodeValue attribute is not available for document nodes and element nodes.
The difference between the two
box.childNodes[0].nodeValue = '<strong>abc</strong>';//The results are as follows:<strong>abc</strong>
abcbox.innerHTML = '<strong>abc</strong>';//The results were as follows:abc
The nodeName attribute obtains the node name
For element nodes, the tag name is returned, such as < a herf > < a > the tag name is returned as "a" For attribute nodes, the name of the attribute is returned, such as class="test" returns the test. -- Returns the content of the text for the text node
tagName
document.getElementByTagName(tagName): Returns an array containing references to these nodes
The getElementsByTagName() method returns an object array, HTMLCollection(NodeList), which holds a list of nodes with all the same element names.
document.getElementsByTagName('*');//Get all the elements
PS: IE browsers use wildcards to treat the specification declaration of the original html of the document as the first element node.
document.getElementsByTagName('li');//Get all li elements and return an array
document.getElementsByTagName('li')[0];//Get the first li element, HTMLLIElement
document.getElementsByTagName('li').item(0);//Get the first li element, HTMLLIElement
document.getElementsByTagName('li').length;//Get the number of all li elements
Absolute references to nodes:
Returns the root node of the document: document.documentElement Returns the live tag node in the current document: document.activeElement Return the source node that the mouse moved out: event.fromElement Return the source node that the mouse moved in: event.toElement Returns the source node of the activation event: event.srcElement
Relative references to nodes: (Let the current node be a node)
Return to the parent node: node.parentNode || node.parentElement (IE) Returns a collection of child nodes (including text nodes and label nodes): node.childNodes Returns the set of child label nodes: node.children Returns a collection of sub-text nodes: node.textNodes Returns the first child node: node.firstChild Returns the last child node: node.lastChild Return to the next node of the same affiliation: node.nextSibling Returns the same node: node.previousSibling
Node information
Does it contain a node: node.contains() Is there a child node.hasChildNodes()
Create a new node
CreateDocument Fragment () - Create Document Fragment Node createElement(tagname) - Create an element with a tagName createTextNode(text) - Create text nodes that contain text text
Get the location of the mouse click event
document.onclick = mouseClick;
function mouseClick(ev){
ev = ev || window.event;//Windows.event is used for IE compatibility
var x = 0; var y = 0;
if(ev.pageX){
x = ev.pageX;
y = ev.pageY;
}else if(ev.clientX){
var offsetX = 0 , offsetY = 0;
if(document.documentElement.scrollLeft){
offsetX = document.documentElement.scrollLeft;
offsetY = document.documentElement.scrollTop;
}else if(document.body){
offsetX = document.body.scrollLeft;
offsetY = document.body.scrollTop;
}
x = ev.clientX + offsetX;
y = ev.clientY + offsetY;
}
alert("The location of your click is x="+ x + " y=" + y);
}
The attributes described below are very supportive of chrome and Safari.
Question 1: Firefox, Chrome, Safari and IE9 all use pageX and pageY attributes of non-standard events to get the mouse position of web pages. Page X/Y gets the distance between the trigger point and the upper left corner of the document area. Page is the reference point and does not change with slider movement.
Question 2: In IE, event objects have x, y attributes (x coordinates and Y coordinates of the location of the event) but not in Firefox. In Firefox, the equivalent of event.x is event.pageX. event.clientX is subtly different from event. pageX (when the entire page has scrollbars), but most of the time it is equivalent.
offsetX:IE is unique and chrome supports it. Compared with the position of the element triggering the event, the mouse uses the upper-left corner of the content area of the element box model as the reference point. If there is a boder, there may be a negative value.
Question 3:
scrollTop is the distance from scrollbar to scrollbar, and all browsers support document.documentElement.
Other references: http://segmentfault.com/a/119...
Reference table
(+for support, -for non-support):
offsetX/offsetY: W3C- IE+ Firefox- Opera+ Safari+ chrome+
x/y: W3C- IE+ Firefox- Opera+ Safari+ chrome+
layerX/layerY: W3C- IE- Firefox+ Opera- Safari+ chrome+
pageX/pageY: W3C- IE- Firefox+ Opera+ Safari+ chrome+
clientX/clientY: W3C+ IE+ Firefox+ Opera+ Safari+ chrome+
screenX/screenY: W3C+ IE+ Firefox+ Opera+ Safari+ chrome+
Check DEMO below:
You will find that offsetX is undefined under Firefox, and it will display normally in chrome and IE.
https://jsfiddle.net/f4am208m...
Differences between offsetLeft and style.left
1.style.left returns a string, such as 10px. offsetLeft returns values, such as 10. 2. Style. ft is readable and written, offsetLeft is read-only. 3. The value of style. left needs to be defined in advance (the definition in the stylesheet is invalid, only the value defined in html can be fetched), otherwise the value is empty.
GetComputed Style and current Style
getComputedStyle() takes two parameters: to get the element of the calculation style and a pseudo-element, if no pseudo-element is needed, it can be null. However, getComputedStyle is not supported in IE, which provides the current Style attribute.
GetComputed Style (obj, false) supports w3c (FF12, chrome 14, safari): In the new version of FF, only the first parameter, namely the operation object, and the second parameter, writing "false", is also a common way of writing, in order to be compatible with the old version of Firefox browser.
Disadvantage: Normal in standard browsers, but not supported in IE6/7/8
window.onload=function(){
var oBtn=document.getElementById('btn');
var oDiv=document.getElementById('div1');
oBtn.onclick=function(){
//alert(oDiv.style.width); // Written in the stylesheet can not be read, can only be written in the line
//alert(getComputedStyle(oDiv).width); // Not Recognized for Standard Browsers IE6, 7, 8
//Alert (oDiv. current Style. width); // For IE browsers, standard browsers are not recognized
if(oDiv.currentStyle){
alert(oDiv.currentStyle.width);
}else{
alert(getComputedStyle(oDiv).width);
}
};
};
Cancel form submission
<script type="text/javascript">
function listenEvent(eventObj,event,eventHandler){
if(eventObj.addEventListener){
eventObj.addEventListener(event,eventHandler,false);
}else if(eventObj.attachEvent){
event = "on" + event;
eventObj.attachEvent(event,eventHandler);
}else{
eventObj["on" + event] = eventHandler;
}
}
function cancelEvent(event){
if(event.preventDefault){
event.preventDefault();//w3c
}else{
event.returnValue = true;//IE
}
}
window.onload = function () {
var form = document.forms["picker"];
listenEvent(form,"submit",validateFields);
};
function validateFields(evt){
evt = evt ? evt : window.event;
...
if(invalid){
cancelEvent(evt);
}
}
</script>
Determine the size of the browser window
For mainstream browsers, such as IE9, Firefox, Chrome and Safari, window object properties called innerWidth and innerHeight are supported, which return to the viewport area of the window, minus the size of any scrollbar. IE does not support innerWidth and innerHeight
<script type="text/javascript">
function size(){
var w = 0, h=0;
if(!window.innerWidth){
w = (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth);
h = (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight);
}else{
w = window.innerWidth;
h = window.innerHeight;
}
return {width:w,height:h};
}
console.log(size());//Object { width: 1366, height: 633 }
</script>
Practical JavaScript solutions (covering all browsers):
var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var h=window.innerHeight || document.documentElement.clientHeight|| document.body.clientHeight;
For IE 6, 7 and 8, the following solutions are proposed:
document.documentElement.clientHeight
document.documentElement.clientWidth
perhaps
document.body.clientHeight
document.body.clientWidth
The body attribute of the Document object corresponds to the < body > tag of the HTML document. The documentElement attribute of the Document object represents the root node of the HTML document.
attributes attribute
attributes property returns the set of attribute nodes of the node.
document.getElementById('box').attributes//NamedNodeMap
document.getElementById('box').attributes.length;//Number of attribute nodes returned
document.getElementById('box').attributes[0]; //Attr, returns the last attribute node
document.getElementById('box').attributes[0].nodeType; //2. Node type
document.getElementById('box').attributes[0].nodeValue; //Attribute value
document.getElementById('box').attributes['id']; //Attr, returns a node with an id attribute
document.getElementById('box').attributes.getNamedItem('id'); //Attr
setAttribute and getAttribute
In IE, we don't know the class attribute, so we need to change it to the class Name attribute. Similarly, in Firefox, we don't know the class Name attribute. Firefox only knows the class attribute, so we usually do the following:
element.setAttribute(class, value); //for firefox
element.setAttribute(className, value); //for IE
IE: Custom attributes can be obtained by using the method of obtaining regular attributes, or by using getAttribute().
Firefox: You can only use getAttribute() to get custom attributes.
Solution: Unified access to custom attributes through getAttribute()
document.getElementById('box').getAttribute('id');//Get the id value of the element
document.getElementById('box').id;//Get the id value of the element
document.getElementById('box').getAttribute('mydiv');//Get custom attribute values for elements
document.getElementById('box').mydiv//Getting custom attribute values for elements, IE does not support non-
document.getElementById('box').getAttribute('class');//Getting the class value of the element is not supported by IE
document.getElementById('box').getAttribute('className');//Non-IE does not support
PS: In IE7 and lower versions of IE browsers, setting class and style attributes using setAttribute() method is ineffective. Although IE8 solves this bug, it is not recommended to use it.
removeAttribute() method
removeAttribute()Can be removed HTML Attributes.
document.getElementById('box').removeAttribute('style');//Remove Attribute
PS: IE6 and lower versions do not support the removeAttribute() method.
Cross-browser Event object
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
#drop{
width: 300px;
height: 200px;
background-color: #ff0000;
padding: 5px;
border: 2px solid #000000;
}
#item{
width: 100px;
height: 100px;
background-color: #ffff00;
padding: 5px;
margin: 20px;
border: 1px dashed black;
}
*[draggable = true]{
-moz-user-select: none;
-webkit-user-select: none;
cursor: move;
}
</style>
</head>
<body>
<div>
<p>It is incompatible to drag small golden squares into large red squares. IE7 And the following browsers, compatible with mainstream browsers!</p>
</div>
<div id="item" draggable="true"></div>
<div id="drop"></div>
<script type="text/javascript">
function listenEvent(target,type,handler){
if(target.addEventListener){//w3c
target.addEventListener(type,handler,false);
}else if(target.attachEvent){//IE
type = "on" + type;
target.attachEvent(type,handler);//IE
}else{
target["on" + type] = handler;
}
}
//Cancel event
function cancelEvent(e){
if(e.preventDefault){
e.preventDefault();//w3c
}else{
e.returnValue = false;//IE
}
}
//Cancel delivery
function cancelPropagation(e){
if(e.stopPropagation){
e.stopPropagation();//w3c
}else{
e.cancelBubble = true;//IE
}
}
window.onload = function () {
var target = document.getElementById('drop');
listenEvent(target,'dragenter',cancelEvent);
listenEvent(target,"dragover",dragOver);
listenEvent(target,'drop', function (evt) {
cancelPropagation(evt);
evt = evt || window.event;
evt.dataTransfer.dropEffect = 'copy';
var id = evt.dataTransfer.getData('Text');
target.appendChild(document.getElementById(id));
});
var item = document.getElementById('item');
item.setAttribute("draggable",'true');
listenEvent(item,'dragstart', function (evt) {
evt = evt || window.event;
evt.dataTransfer.effectAllowed = 'copy';
evt.dataTransfer.setData('Text',item.id);
});
};
function dragOver(evt){
if(evt.preventDefault) evt.preventDefault();
evt = evt || window.event;
evt.dataTransfer.dropEffect = 'copy';
return false;
}
</script>
</body>
</html>
dataTransfer object
| Attribute | Description|
| ------------- |:-------------:|
| dropEffect | Sets or gets the type of drag operation and the type of cursor to display|
| effectAllowed | Sets or gets data transfer operations that can be applied to the source elements of the object|
| Method | Description|
| ------------- |:-------------:|
| clearData | Delete one or more data formats from the clipboard through a dataTransfer or clipboard Data object|
| getData | Get data in a specified format from the clipboard through a dataTransfer or clipboard Data object
| setData | Give data to a dataTransfer or clipboard Data object in a specified format
HTML5 drag-and-drop browser support
Internet Explorer 9, Firefox, Opera 12, Chrome, and Safari 5. Support drag-and-drop
To make the element draggable, set the draggable property to true:
<img draggable="true" />
| Event | Description|
| ------------- |:-------------:|
| dragstart | dragstart event starts|
| drag | on drag operation|
| dragenter | drag onto the target to determine whether the target accepts placement
| dragover | drags onto the target to determine feedback to the user
| drop | placement occurs
| dragleave | drag away from the target
| dragend | dragend
Some browser compatibility of the above code:
1.For compatibility IE,We will`window.event`Assign to `evt`,Other browsers will receive it correctly`event`Object assignment`evt`.
2.w3c Use addEventListener To add event listeners to event elements, and IE Then use attachEvent. addEventListener For the current object bubbled up by the event, and attachEvent yes window
3.For event types, IE Need to add`on + type`Properties, while other browsers do not
4.For preventing default event behavior of elements, the following are w3c and IE Practice:
e.preventDefault();//w3c
e.returnValue = false;//IE
5.For cancelling event propagation, w3c and IE There are also different treatment mechanisms:
e.stopPropagation();//w3c
e.cancelBubble = true;//IE
Acquisition of target objects across browsers
//Acquisition of target objects across browsers
function getTarget(ev){
if(ev.target){//w3c
return ev.target;
}else if(window.event.srcElement){//IE
return window.event.srcElement;
}
}
w3c and IE also have different ways of getting trigger objects:
event.target;//w3c
event.srcElement;//IE
We can use trinomial operators to accommodate them:
obj = event.srcElement ? event.srcElement : event.target;
The problem of innerText
innerText works well in IE, but not in FireFox.
<p id="element"></p>
<script type="text/javascript">
if(navigator.appName.indexOf("Explorer") >-1){
document.getElementById('element').innerText = "my text";
} else{
document.getElementById('element').textContent = "my text";
}
</script>
Getting and setting innerText across browsers
//Getting innerText across browsers
function getInnerText(element){
return (typeof element.textContent == 'string') ? element.textContent : element.innerText;
}
//Setting innerText across browsers
function setInnerText(element,text){
if(typeof element.textContent == 'string'){
element.textContent = text;
}else{
element.innerText = text;
}
}
Use of oninput,onpropertychange,onchange
The onchange trigger event must satisfy two conditions:
a) Current object attributes change and are triggered by keyboard or mouse events (script triggers are invalid) b) the current object loses focus (onblur);
If onpropertychange changes the current object property, it will trigger events, but it is IE-specific.
oninput is a non-IE browser version of onpropertychange, which supports browsers such as firefox and opera. However, when it is bound to an object, not all attribute changes of the object can trigger events, it only works when the value of the object changes.
Accessing the XMLHTTPRequest object
<script type="text/javascript">
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();//Non IE
}else if(window.ActiveXObject){
xhr = new ActiveXObject("Microsoft.XMLHttp");//IE
}
</script>
Ban Selection of Web Content
Questions: FF needs to be banned by CSS and IE by JS Solution: IE: obj.onselectstart = function() {return false;} FF: -moz-user-select:none;
Three non-bubbling incidents
All browsers'focus/blur events are not bubbling. Fortunately, most browsers support focusin / focus out events, but hateful firefox doesn't even support this.
IE6, 7, 8 submit events do not bubble. change events under IE6, 7, 8 will not be triggered until blur.
The Evil Wheel Event
The support of roller events can be described as a mess, with the following rules:
IE6-11 chrome mousewheel wheelDetla lower-120 upper 120 firefox DOMMouseScroll detail 3 up-3 firefox wheel detlaY lower 3 up-3 IE9-11 wheel deltaY lower 40 upper-40 chrome wheel deltaY up to-100 below 100
For mouse wheel events, IE supports mousewheel and Firefox supports DOMMouseScroll.
To determine whether the mouse wheel is up or down, IE uses the wheelDelta attribute and Firefox uses the detail attribute.
Event Delegation Method
//Event Delegation Method
IE: document.body.onload = inject; //Function inject()It has been implemented before that.
FF: document.body.onload = inject();
HTML5 browser support
Source address: http://fmbip.com/litmus/
Query operation
Queries refer to finding a set of elements through some characteristic strings, or judging whether the elements satisfy the strings.
1. IE6/7 does not distinguish id from nam When using getElementById and getElementsByName under IE6/7, elements with the same id or name as the given value are returned at the same time. Since name is usually agreed by the back end, we should ensure that id does not duplicate name when we write JS. 2. IE6/7 does not support getElements ByClassName and querySelector All These two functions have been supported since IE8, so under IE6/7, only getElementByTagName is actually available. 3. IE6/7 does not support getElements ByTagName ('*') returning non-element nodes Either you don't need *, or you can write a function to filter it. 4. Query Selector All is not friendly to property selectors under IE8 Almost all browsers have problems with predefined attributes, try to use custom attributes or do not use attribute selectors. 5. QueySelectorAll does not support pseudo-classes under IE8 Sometimes pseudo-classes are very useful, IE8 does not support them, jquery provides: first,: last,: even,: odd,: eq,: nth,: lt,: gt are not pseudo-classes, we should not use them at any time. 6. IE9 matches function cannot handle elements that are not on the DOM tree As long as the element is not in the dom tree, it will return false. It is impossible to leave the element in the body and delete it after matching. Of course, we can also write the matching function ourselves to avoid backflow.
Reference:
http://w3help.org/zh-cn/kb/,