HTML Accessibility Tag
To improve accessiblity, we are encouraged to use semantic tag of HTML5
Why to use it?
Common semantic tags
- Layout:
header
footer
nav
main
section
article
aside
<header role="banner">
<section role="search">
- Form:
label
input
button
<label for="search">
<input type="text" >
<input type="submit" />
- Table:
<caption>
<table summury="caption">
th
- Image:
<img alt="img.png" title="This is a beautiful girl" >
aria-labelledby
- empty
alt
: necessary if the image is only for decoration use
- text:
<em>
vs<i>
<strong>
vs<b>
<abbr title="Hypertext Markup Language"> HTML <abbr>
- position:
absolution position
is better thandisplay: none
orvisibility: hidden
: to overlap all div with differentz-index
- since
display: none
orvisibility: hidden
will hide content from screenreader
- Layout:
How to improve accessibility?
use
:focus
&:hover
pseudo-class to highlight the chosen tag1
2
3
4a:hover, input:hover, button:hover, select:hover,
a:focus, input:focus, button:focus, select:focus {
font-weight: bold;
}
JavaScript in accessibility
- provide client-side form validating, rather than server-side
<video>
has control button for keyboardmouseover
==onfocus
&mouseout
==onblur
mobile accessibility
touch:
onmousedown
==ontouchstart
&&onmouseup
==ontouchstop
side menu
@media
logical operator:
and
,not
,only
,,(like 'or')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<!-- 1. media in <link> -->
<link href="mobile.css" rel="stylesheet" media="screen and (max-width: 600px)">
<!-- 2. media in <style> -->
<style media="all and (max-width: 500px)">
p {
color: blue;
background-color: yellow;
}
</style>
<!-- 3. media in <script> -->
<script>
if (window.matchMedia("(min-width: 400px)").matches) {
// the viewport is at least 400 pixels wide
} else {
// the viewport is less than 400 pixels wide
}
</script>
<!-- 4. media inside style -->
<style>
@media screen and (min-width: 30em) and (max-width: 992px) {
body { background-color: blue; }
}
@media (min-height: 680px), screen and (orientation: portrait){
body { background-color: blue; }
}
</style>
@import
syntax:
1
2@import 'custom.css';
@import url('landscape.css') screen and (orientation:landscape);
Why use React?
Credit to: https://reactjs.org/blog/2013/06/05/why-react.html
- React is not MVC, is only “V”
- Support small, reusable component
- efficient DOM update, using diff algorithm
reconcilation process
: the way React used to update real DOM, by only updating changed components node and its children- Every time
props
orstate
change leading torender()
execution, which will produce either aString
orvirtual DOM node
; - Either way, React will compare it with previous
String
orvirtual DOM node
, to determine which node in real DOM need to be updated diff/reconcilation
process only happens afterrender()
, it will compare current tree with previous tree
key
in a list of nodes: makediff
efficiently- there are cases that a node is added in front to a list, without
key
, React just compare each pair of nodes from previous tree and current tree, and re-render all the nodes in real DOM in that list; Even thought, it only needs to insert a new node to real DOM tree - Attaching a
key
to each node in a list, will help React know which node need to be re-render in real DOM tree. - Nodes with the same
key
inside a list, will be stable across different re-renders
- there are cases that a node is added in front to a list, without
React Lifecyle
Mounting phase
constructor()
getDerivedStateFromProps()
render()
componentDidMount()
Updating phase
getDerivedStateFromProps()
shouldComponentUpdate()
render()
: after either newprops
or newstate
componentDidUpdate()
Unmounting phase
componentWillUnmount()
Other API:
setState()
&forceUpdate()
setState()
: can take both object and callback function as parametersetState( (prevState, props) => updatedState )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// BAD: updated state will only take one increment
// i.e. in the end, counter=1
componentDidMount(){
this.setState({counter: this.state.counter+1})
this.setState({counter: this.state.counter+1})
this.setState({counter: this.state.counter+1})
})
// GOOD: updated state will take all increment
// i.e. in the end, counter=3
componentDidMount(){
this.setState( counter=>{counter: state.counter + 1} )
this.setState( counter=>{counter: state.counter + 1} )
this.setState( counter=>{counter: state.counter + 1} )
})
How to implement infinite scroll loading
Credit to: https://segmentfault.com/a/1190000004974824
Which event do we use?
- We assume the user will scroll down the screen, in order to load more content
- So we use the
scroll
event onwindow
orblock element
with a height set already
Three conditions for AJAX cal
container bottom - window bottom < certain value
,i.e. the container don’t have too much content to show- not in the middle of loading
- still have content to load, i.e. not the end of all the content
code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23var isLoading = false;
var isEnd = false;
var triggerDistance = 200;
function fetchData() {
var distance = container.getBoundingClientRect().bottom - window.innerHeight;
if ( !isLoading && !isEnd && distance < triggerDistance ) {
isLoading = true;
fetch(path).then(res => {
isLoading = false;
// if not end, will short-circut latter statement
// if reach end, will still check the latter one, which will set isEnd to true
res.data.length === 0 && isEnd = true;
doSomething(res.data);
});
}
}
window.addEventListener('scroll', fetchData);
The rendering order: CSS, JS, HTML
- credit to:
- General order
- JS in
<head>
will block downloading of following resource - Browser downloads and parses HTML to DOM
- when encounter
<script>
,- if not external, render engine hand control power to js engine
- if is external, render engine keep rendering, while downloads external
- JS in
CSS: profile & edit image link
Implement the requirement
consider accessibility
1 | // 1. Mouse is not over the picture |
Flex Layout
flex container:
NOTE:
float
clear
vertical-align
for the items inside flex boxwill become invaliddisplay: inline-flex
vsdisplay: flex
:- only apply to flex container, to make it display as
inline
orblock
- won’t affect flex items inside
- only apply to flex container, to make it display as
flex-direction
flex-wrap
: break new line or not when exceeding it containerflex-flow
is combinatin of first 2 items:1
2
3
4flex-direction: row;
flex-wrap: wrap;
<==>
flex-flow: row wrap;
align-items: center;
: where flex items sit on the cross axisjustify-content: space-around;
: where the flex items sit on the main axis
flex items:
flex: 1 1 20px
: three attributes:flex-grow
flex-shrink
flex-basis
order: 3
: like the smaller will be put in frontalign-self
: override its container’salign-items
layout, update position of itself
Grid Layout
Grid Container
- display:
display: grid
vsdisplay: inline-grid
: only apply on grid container - gap:
grid-row-gap
grid-column-gap
grid-gap
: set the gap between items - col num/width:
grid-template-columns
: define num of columns and their width - row num/width:
grid-template-rows
: define num of rows and their width - horizontally align:
justify-content
: center, start, end, space-evenly, space-around, space-between - vertically align:
align-content
: center, start, end, space-evenly, space-around, space-between
- display:
Grid Items
line:
grid-row-start
grid-column-end
: specify the start & end of span it coversline shorthand 1 :
grid-row
grid-column
grid-row:1 / 3
:range: [line1 line3]
grid-column: 1/span 3
: from line1, take 3 units,range: [line1 line4]
line shorthand 2 :
grid-area
=grid-row-start
+grid-column-start
+grid-row-end
+grid-column-end
grid-area: 1 / 2 / 5 / 6
: start on row-line 1 and column-line 2, and end on row-line 5 and column line 6:grid-area: 2 / 1 / span 2 / span 3
:NOTE: can assign names to grid items, cooperate with
grid-template-areas
. Used to assign space to the named item1
2
3
4
5
6
7
8
9
10
11
12
13
14https://www.w3schools.com/css/tryit.asp?filename=trycss_grid_grid-area_named1
.item1 { grid-area: header; }
.item2 { grid-area: menu; }
.item3 { grid-area: main; }
.item4 { grid-area: right; }
.item5 { grid-area: footer; }
.grid-container {
grid-template-areas:
'header header header header header header'
'menu main main main right right'
'menu footer footer footer footer footer';
}order: specified by
starting line#
andending line#
1
2
3
4
5
6.item1 { grid-area: 1 / 3 / 2 / 4; }
.item2 { grid-area: 2 / 3 / 3 / 4; }
.item3 { grid-area: 1 / 1 / 2 / 2; }
.item4 { grid-area: 1 / 2 / 2 / 3; }
.item5 { grid-area: 2 / 1 / 3 / 2; }
.item6 { grid-area: 2 / 2 / 3 / 3; }
CSS:
float
&position
&box model
float
- when container box has no height, and need to cover all it floating children:
clear: both
&overflow: hidden
- when container box has no height, and need to cover all it floating children:
box-sizing
=>content-box
/border-box
box-sizing: content-box;
actual width=width
+padding
+border
Thewidth
andheight
properties include the content, but does not include the padding, border, or margin.box-sizing: border-box;
actual width =width
=content
+padding
+border
Thewidth
andheight
properties include the content, padding, and border, but do not include the margin
cursor: pointer
cursor acts like<a>
when hoverpx
vspt
vsrem
vsem
https://kyleschaeffer.com/development/css-font-size-em-vs-px-vs-pt-vs/pt
: physical measurement, fixed when media once producedpx
: calculated relative topt
; can be adjustedrem
: related to root font-size (default: 16px)em
: related to its parents font-size (default: 16px)
resize
: indicate how this block element can be resized- horizontal: can only resized horizontally
- vertical: can only resized vertically
- both: can be resized on both directions
- none: none resizable
- initial: == none resizable
width
&height
make the aspect-ratio stay the same: adjust one, set other one
auto
tweak image while keep aspect-ratio the same
some time will overflow: can add
overflow: hidden
to its parent1
2
3
4
5
6
7
8div{
width: 100px;
height: 100px;
}
.img{
width: 100%;
height: auto;
}
white-space:
nowrap
,pre
,normal
- how to handle text’s space inside a block to be displayed
nowrap
: ignore all white-space in one line, like in<span>
normal
: make text content displayed against the block, change line based on spacepre
: take in all kind of space (include new line) displayed as they specified in html tag
overflow
: deal with inner box exceeding outer box:hidden
orscroll
text-overflow:
deal with too many words inside box, clip or ellipsisclip(default)
ellipsis(省略号)
word-break:
deal with long word, which may exceeds width of its containernormal
break-word;
: the best clipping way to show the word
max-width
vswidth
width
: set the tentative value`max-width
set the rule, to restrict the value ofwidth
some time can change the aspect-ratio
1
2
3
4.image{
width: 100%;
height: 100%;
}
CSS: block
vs inline
vs inline-block
credit to: http://dustwell.com/div-span-inline-block.html
<div>
- A “block-level element”
- can contain all other elements!
- can only be inside other block-level elements
- defines a rectangular region on the page
- tries to be as wide as possible
- begins on a “new line”, and has an “carriage return” at the end, like a
<p>
<span>
- An “inline element”
- cannot contain block-level elements!!
- can be inside any other element
- tries to be as narrow as possible
- defines a “snake” on the page
- doesn’t create any new lines.
block
vsinline
vsinline-block
block
:- has width, height, margin, padding
- force a new line after the block
inline
:- no width, no height; only respect left/right margin, left/right padding
- allow other elements to sit on the same line
inline-block
:- has width, height, margin, padding
- allow other elements to sit in a line, that’s why called
inline
CSS: how to center an element?
- https://css-tricks.com/centering-css-complete-guide/
- Horizontally
- center inline element inside block element:
text-align: center
- center block element inside another block element:
- outer block with specified width:
margin: 0 auto
- outer block with no width: inner width will spread its width to outer, so no need for
margin: 0 auto
- outer block with specified width:
- center multiple block element in a row inside another block element:
display: inline-block
display: flex
- center multiple block element in different rows inside another block element:
margin: 0 auto
- center inline element inside block element:
- Vertically for inline elements
- center single inline element inside block element:
height
==line-height
padding-top == padding-bottom
- center multiple inline elements inside block element:
display: table
&display: table-cell
+vertial-align: middle
:display: flex
&align-items: center
- ghost element:
- full-height pseudo element is placed inside the container and the text is vertically aligned with that (both are
inline-block
) - trick: contain multiple lines into a
inline-block
to be a whole inline element - adjacent with another
inline-block
withheight=100%
inline-block
elements will align on baseline, ifvertical-align
doesn’t specify any other value- if
vertical-align
specifymiddle
: browser will try to align all inline boxes in middle, rather than baseline - NOTE:
vertical-align
specify how will itself to be aligned vertically
- full-height pseudo element is placed inside the container and the text is vertically aligned with that (both are
- center single inline element inside block element:
- Vertically for block elements
- if
height
of inner block is known: useposition: abosulute
&top
&margin:0.5*height
- if
height
of inner block is not known: useposition: abosulute
top
&transform: translateY(-50%)
- Again:
display: flex
- if
- Both Horizontally & Vertically
- if
height
of inner block is known: useposition: abosulute
&top
&margin:0.5*height
- if
height
of inner block is not known: useposition: abosulute
top
&transform: translateY(-50%)
- Again:
display: flex
display: grid
- if
DOM structure
difference between
HTMLCollection
&NodeList
HTMLCollection
: a collection of element nodesNodeList
: a collection of all types of nodes: element node/ text node/ comment node- convert them to array, to extract info:
Array.prototype.slice.call(NodeList)
everything in an HTML document is a node:
- The entire document is a document node
- Every HTML element is an element node
- The text inside HTML elements are text nodes
- All comments are comment nodes
navigate across the DOM tree using attibutes: [element node, text node, comment node]
- parentNode
- childNodes [nodenumber]
- firstChild
- lastChild
- nextSibling
- previousSibling
A common error in DOM processing is to expect an element node to contain text.
<title id="demo">DOM Tutorial</title>
The element node
<title>
(in the example above) does not contain text.It contains a text node with the value “DOM Tutorial”.
The value of the text node can be accessed by the node’s innerHTML property:
1
2
3
4
5
6
7var myTitle = document.getElementById("demo").innerHTML;
// or
var myTitle = document.getElementById("demo").firstChild.nodeValue;
// or
var myTitle = document.getElementById("demo").childNodes[0].nodeValue;
DOM API:
get style & set style of an element
set style
- directly use it as attribute
elements.style.fontSize = '10px'
- NOTE: the style name must be camelCase
- directly use it as attribute
get style:
if style is set using
style
orjs
, directly get the styleif style is set using
css
withoutelement.style
keyword, we will usegetComputedStyle()
document.defaultView.getComputedStyle(ele,null).getPropertyValue("font-size")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html lang="en">
<head>
<script>
function cStyles() {
var RefDiv = document.getElementById("d1");
var txtHeight = document.getElementById("t1");
var h_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("height");
txtHeight.value = h_style;
}
</script>
<style>
#d1 {
margin-left: 10px;
background-color: rgb(173, 216, 230);
height: 20px;
max-width: 20px;
}
</style>
</head>
<body>
<div id="d1"> </div>
<form action="">
<p>
<button type="button" onclick="cStyles();">getComputedStyle</button>
height<input id="t1" type="text" value="1" />
</p>
</form>
</body>
</html>
console.trace()
can be used to trace the call stack of a certain functionaddEventListener
&removeEventListener
1
2
3
4
5// Attach an event handler to the document
document.addEventListener("mousemove", myFunction);
// Remove the event handler from the document
document.removeEventListener("mousemove", myFunction);
createAttribute()
&setAttributeNode()
1
2
3
4
5
6function myFunction() {
var h1 = document.getElementsByTagName("H1")[0];
var att = document.createAttribute("class");
att.value = "democlass";
h1.setAttributeNode(att);
}
createElement()
&intersetBefore()
&appendChild()
1
2
3
4var btn = document.createElement("BUTTON"); // Create a <button> element
var t = document.createTextNode("CLICK ME"); // Create a text node
btn.appendChild(t); // Append the text to <button>
document.body.appendChild(btn); // Append <button> to <body>
querySelector
&querySelectorAll()
querySelector()
returns the first element that matches a specified CSS selector(s)1
2
3
4
5
6
7
8
9
10// 1. select first p element whose parent is a div
function myFunction() {
var x = document.querySelector("div > p");
x.style.backgroundColor = "red";
}
// 2. select all a element has target attribute
function myFunction() {
document.querySelector("a[target]").style.border = "10px solid red";
}
querySelectorAll()
returns all elements in the document that matches a specified CSS selector(s), as a static NodeList object.1
2
3
4
5
6
7function myFunction() {
var x = document.querySelectorAll("a[target]");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.border = "10px solid red";
}
}
element.childNodes
vselement.children
element.childNodes
: returns aNodeList object
, including element nodes, text nodes, and comment nodeselement.children
: return aHTMLCollection object
- difference:
- childNodes: contain all nodes, including text nodes and comment nodes
- children: only contain element nodes.
element.firstChild
vselement.firstElementChild
- difference:
- firstChild returns the first child node as an element node, a text node or a comment node (depending on which one’s first),
- firstElementChild returns the first child node as an element node (ignores text and comment nodes).
- difference:
element.parentNode
vselement.parentElement
parentElement: returns null if the parent node is not an element node
parentNode: is probably the most popular
1
2
3
4
5document.body.parentNode; // Returns the <html> element
document.body.parentElement; // Returns the <html> element
document.documentElement.parentNode; // Returns the Document node
document.documentElement.parentElement; // Returns null (<html> does not have a parent ELEMENT node)
element.previousSibling
vselement.previousElementSibling
- previousSibling: returns the previous sibling node as an element node, a text node or a comment node
- previousElementSibling: returns the previous sibling node as an element node (ignores text and comment nodes).
DOM events
[Trick]: bind data on element as
attribute
, then usee.target.getAttribute("data-info")
common types:
onload
oninput
onchange
onfocus
onmouseover
&onmouseout
onclick
&onmousedown
&onmouseup
onkeypress
&onkeydown
&onkeyup
onresize
onscroll
event propagation: bubbling & capturing
- Event propagation is a way of defining the element order when an event occurs.
- bubbling: the inner most element’s event is handled first and then the outer: the
<p>
element’s click event is handled first, then the<div>
element’s click event. - capturing: the outer most element’s event is handled first and then the inner: the
<div>
element’s click event will be handled first, then the<p>
element’s click event.
Array-like object under the hood
- All credit to: http://2ality.com/2013/05/quirk-array-like-objects.html
- An array-like object
- only has:
index
to access to elements:a[0]
- the property
length
that tells us how many elements the object has:a.length
- does not have: array methods such as
push
,forEach
andindexOf
; have to borrow these methods - NOTE:
NodeList
has theforEach
attributeHTMLCollection
doesn’t haveforEach
attribute
- “borrow” : that why we use:
[].slice(array-like)
[].indexOf(array-like)
[].forEach(array-like)
- only has:
- Two examples of array-like objects
- result of the DOM method
document.getElementsByClassName()
(many DOM methods return array-like objects) - the special variable
arguments
.- You can determine the number of arguments via
arguments.length
- you can access a single argument, e.g. read the first argument:
arguments[0]
- You can determine the number of arguments via
- result of the DOM method
Array methods, however, have to be borrowed. You can do that, because most of those methods are generic
Three ways to convert Array-like objects to Array.
Array.prototype.slice.call(arguments)`
Array.from(arguments)
use
bind
to create a new functionslice()
function on array-like object, so we can reuse it1
2
3
4
5
6let = getIndexOfA = function(){
let myIndexOf = [].indexOf.bind(arguments);
return myIndexOf("a") // NOTE: mustn't use arguments.myIndexOf()
}
console.log( getIndexOfA("d", "d", "a","d") ) // 2
What can be put inside <head>
?
https://github.com/xiaoyu2er/HEAD
JS coding: mutate array according new indices
1 | Given an input array and another array that describes a new index for each element, mutate the input array so that each element ends up in their new index. |
<script async>
& <script defer>
- normal
<script src="script.js" >
- The HTML parsing is paused for the script to be both fetched and executed
<script async>
- The HTML parsing is not paused for the script to be fetched,
- but still be paused for js to be executed
<script defer>
- The HTML parsing is not paused for the script to be fetched,
- oppositely, the execution of js is paused util the HTML finish parsing
- same as
<script>
right before the</body>
tag
How to check data types in JS
https://webbjocke.com/javascript-check-data-types/
write a promise
Promise
1 | <!DOCTYPE html> |
AJAX
XMLHttpRequest
is browser built-in object, used to pull data in backgroundMethods:
open(method, url, async, user, psw)
: specify the request- method: the request type GET or POST
- url: the file location
- async: true (asynchronous) or false (synchronous)
- user: optional user name
- psw: optional password
setRequestHeader()
: Adds a label/value pair to the header to be sentsend(str)
: Sends the request to the server (GET
orPOST
)- if no
str
provided, send asGET
- if
str
is provided, send as the parameters forPOST
- if no
properties:
onreadystatechange
: function used to be called when state changereadyState
: Holds the status of the XMLHttpRequest.- 0: request not initialized
- 1: server connection established
- 2: request received
- 3: processing request
- 4: request finished and response is ready
status
: Returns the status-number of a request- 200: “OK”
- 403: “Forbidden”
- 404: “Not Found”
responseText
: Returns the response data as a stringresponseXML
: Returns the response data as XML data
steps
- An event occurs in a web page (the page is loaded, a button is clicked)
- An XMLHttpRequest object is created by JavaScript
- The XMLHttpRequest object sends a request to a web server
- The server processes the request
- The server sends a response back to the web page
- The response is read by JavaScript
- Proper action (like page update) is performed by JavaScript
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/* --------------- 1. GET --------------- */
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "demo_get.asp", true);
xhttp.send();
}
/* --------------- 2. POST --------------- */
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("POST", "demo_post2.asp", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("fname=Henry&lname=Ford");
}
Check if undeclared
, undefined
or null
1 | // 1. `undeclared` check |