# Namespace
- Variable names need to be unique
变量名必须是唯一的 - All variables by default are placed in the global
window
namespace when defined normally with thevar
keyword unless defined inside afunction
. Functional Scope, changes some with ES6+let
andconst
默认情况下,所有变量使用var
关键字定义的变量,都放置在全局window
命名空间中,除非在function
中定义。函数作用域,在 ES6+let
和const
有一些改变 - Variables defined inside a function are scoped or name spaced to that function.
在函数内定义的变量的作用域或命名空间为该函数。 - If we mix our code with others code, we may overlap variable names
如果我们将我们的代码与其他代码混合在一起,我们可能会重叠变量名 - We want to define our own namespace
- We have a few ways we can do that.
# Self executing protecting function or Immediately-invoked Function Expressions IIFE
自我执行保护功能或立即调用的功能表达
(function(){ | |
//anything in here has its own special namespace | |
// 这里的任何东西都有自己特殊的命名空间 | |
//functions and variables are not available to the outside | |
// 函数和变量对外不可用 | |
})(); |
# The Big Plain Map/Object Literal
var myNamespace = {}; | |
myNamespace.aFunction = function(){ | |
}; | |
myNamespace.aVariable = 7; |
- Use everything from the Map/Object
使用地图 / 对象中的所有内容 - Useful for quick solution but doesn’t have private variables or methods at all
用于快速解决方案但没有私有变量或方法论
# Exporting a Map to the global Namespace
向全局命名空间输出 Map
(function(){ | |
var myNamespace = {}; | |
//Private variables | |
var name = "brian"; | |
//Public members/variables | |
myNamespace.myName = "brian"; | |
//Public Method | |
myNamespace.myFunction = function(){ | |
alert(this.myName) | |
}; | |
window.myNamespace = myNamespace; | |
})(); |
# Exporting a Map to the global Namespace with possible namespace in window already
向全局命名空间输出 Map,window 中可能已存在命名空间
(function(ns){ | |
//Private variables | |
var name = "brian"; | |
//Public members/variables | |
ns.myName = "brian"; | |
//Public Method | |
ns.myFunction = function(){ | |
alert(this.myName) | |
}; | |
window.myNamespace = ns; | |
})(window.myNamespace || {}); |
# Return a Map to the specified Namespace
将 Map 返回到指定的命名空间
var namespace = function(){ | |
var myNamespace = {}; | |
//Private variables | |
var name = "brian"; | |
//Public members/variables | |
myNamespace.myName = "brian"; | |
//Public Method | |
myNamespace.myFunction = function(){ | |
alert(this.myName) | |
}; | |
return myNamespace; | |
}(); |
# Namespace as a function parameter
命名空间作为函数参数
var namespace = {}; | |
(function(ns){ | |
//set up private data here | |
//public data | |
ns.aFunc = function(){ | |
// ... | |
}; | |
ns.aVar = 123; | |
})(namespace); |
# Wrapping with an event function
用事件函数包装
Another option would be using the window event function like
DOMContentLoaded
to act as your namespace protector.
另一种选择是使用window
事件函数,如DOMContentLoaded
作为命名空间的保护者。Since the event handler is a function, it has function scope and keeps the variables and functions local to that function.
由于事件处理程序是一个函数,它具有函数作用域,并保持该函数的局部变量和函数。
# Waiting for the DOM
等待 DOM 准备就绪
- How do you prevent your JS from running before the page is ready to be manipulated?
如何在页面准备好被操纵之前,阻止 JS 运行?- You could add and an event handler to the
window
’sload
event
你可以为window
的load
事件添加一个事件处理函数- This will fire the event handler at the end of the document loading process.
这将在文档加载过程结束时触发事件处理程序。
All objects in the document are in DOM and all images, scripts, and other assets are also loaded.
所有 DOM 中的对象文档,是指所有图像、脚本和其他资产也被加载。 - Sometimes this will take longer than you really need.
有时这会比您真正需要的时间更长。
Most of the time you really just want the DOM to be ready to be manipulated.
大多数时候你真的只是想要 DOM 准备好被操纵。 - https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
- This will fire the event handler at the end of the document loading process.
- You could add and an event handler to the
- Better option is often using the
DOMContentLoaded
event on thewindow
ordocument
object.
更好的选择通常是在窗口或文档上使用DOMContentLoaded
事件。- This event fires when the HTML document has been fully loaded and parsed. It does not wait for other assets like images and stylesheets.
当 HTML 文档完全加载和解析时触发此事件。它不等待其他内容,如图像和样式表。 - This event is often what you want vs listening for the full load event.
这个事件通常是你想要的,而不是监听满载事件。 - https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
- https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event
- This event fires when the HTML document has been fully loaded and parsed. It does not wait for other assets like images and stylesheets.
- https://gist.github.com/jsonberry/0d71007ea188785e1a3d13d2e30d58a5
window.addEventListener('load', function (evt) { | |
console.log('page is fully loaded'); | |
}); |
document.addEventListener('DOMContentLoaded', function (evt) { | |
console.log('DOM fully loaded and parsed'); | |
}); |
# DOM Element Creation and Deletion Demo
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Basic DOM creation Demo</title> | |
</head> | |
<body> | |
<button id="btn">Insert Text</button> | |
<div id="contentArea"></div> | |
<script> | |
window.addEventListener('load', function() { | |
console.log('window load'); | |
document.getElementById('btn').addEventListener('click', function(){ | |
console.log('btn clicked'); | |
let headline = document.createElement('h1'); | |
headline.id = 'main-headline'; | |
headline.setAttribute('class', 'redtext'); | |
let hcontent = document.createTextNode('Hello Basic DOM Creation Demo'); | |
headline.appendChild(hcontent); | |
document.getElementById('contentArea').appendChild(headline); | |
let container = document.createElement('div'); | |
let para = document.createElement('p'); | |
para.appendChild(document.createTextNode('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.')); | |
container.appendChild(para); | |
document.getElementById('contentArea').appendChild(container); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>DOM creation and deletion demo</title> | |
</head> | |
<body> | |
<div id="root"></div> | |
<script> | |
document.addEventListener('DOMContentLoaded', function(){ | |
console.log('DOMContentLoaded fired'); | |
let controls = document.createElement('div'); | |
controls.id = 'controlsWrapper'; | |
controls.style.backgroundColor = '#aaa'; | |
controls.style.padding = '20px'; | |
let textIn = document.createElement('input'); | |
textIn.setAttribute('type', 'text'); | |
textIn.id = 'textIn'; | |
let textLabel = document.createElement('label'); | |
textLabel.setAttribute('for', 'textIn'); | |
textLabel.appendChild(document.createTextNode('Enter Text: ')); | |
controls.appendChild(textLabel); | |
controls.appendChild(textIn); | |
let colorSelect = document.createElement('select'); | |
colorSelect.id = 'colorSelect'; | |
let optRed = document.createElement('option'); | |
optRed.setAttribute('value', '#ff0000'); | |
optRed.appendChild(document.createTextNode('Red')); | |
colorSelect.appendChild(optRed); | |
let optGreen = document.createElement('option'); | |
optGreen.setAttribute('value', '#00ff00'); | |
optGreen.appendChild(document.createTextNode('Green')); | |
colorSelect.appendChild(optGreen); | |
let optBlue = document.createElement('option'); | |
optBlue.setAttribute('value', '#0000ff'); | |
optBlue.appendChild(document.createTextNode('Blue')); | |
colorSelect.appendChild(optBlue); | |
controls.appendChild(colorSelect); | |
let saveBtn = document.createElement('button'); | |
saveBtn.id = 'saveBtn'; | |
let saveBtnText = document.createTextNode('Save'); | |
saveBtn.appendChild(saveBtnText); | |
saveBtn.addEventListener('click', saveHandler); | |
controls.appendChild(saveBtn); | |
document.getElementById('root').appendChild(controls); | |
let list = document.createElement('ul'); | |
list.id = 'list'; | |
list.style.listStyleType = 'none'; | |
list.style.padding = '0'; | |
document.getElementById('root').appendChild(list); | |
function saveHandler(){ | |
console.log('save clicked'); | |
let text = document.getElementById('textIn').value.trim(); | |
let color = document.getElementById('colorSelect').value; | |
console.log('Text: ' + text + ', Color: ' + color); | |
if (text === '') { | |
alert('Text can not be empty!'); | |
} else { | |
let item = document.createElement('li'); | |
let img = document.createElement('img'); | |
img.src = 'close.png'; | |
img.setAttribute('alt', 'Delete Item Button'); | |
img.style.width = '20px'; | |
img.style.margin = '0 10px 0 0'; | |
img.style.cursor = 'pointer'; | |
img.addEventListener('click', function(e){ | |
console.log('img clicked'); | |
console.log(e); | |
//e.target.parentNode.parentNode.removeChild(e.target.parentNode); | |
this.parentNode.parentNode.removeChild(this.parentNode); | |
}); | |
item.appendChild(img); | |
item.appendChild(document.createTextNode(text)); | |
item.style.color = color; | |
document.getElementById('list').appendChild(item); | |
document.getElementById('textIn').value = ''; | |
document.getElementById('colorSelect').selectedIndex = 0; | |
} | |
} | |
}); //end DOMContentLoaded | |
</script> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Dom Ready Demo</title> | |
<script> | |
window.addEventListener('load', function(){ | |
console.log('window load'); | |
let x = document.getElementById('closeimg').getAttribute('alt'); | |
console.log(x); | |
}); | |
window.addEventListener('DOMContentLoaded', function(){ | |
console.log('DOMContentLoaded - window'); | |
let x = document.getElementById('closeimg').getAttribute('alt'); | |
console.log(x); | |
}); | |
document.addEventListener('DOMContentLoaded', function(){ | |
console.log('DOMContentLoaded - document'); | |
let x = document.getElementById('closeimg').getAttribute('alt'); | |
console.log(x); | |
}); | |
</script> | |
</head> | |
<body> | |
<img id="closeimg" alt="close icon" src="close.png"> | |
</body> | |
</html> |
# Quiz 5
The DOM method appendChild will insert an element as a child before any other child elements.
The DOMContentLoaded event fires only on the document object.
Which event handler will fire first?
Wrapping your code in a DOMContentLoaded event handler is a way to protect the global namespace from your variables and functions.
The DOM method createElement needs to be called on the document object.