原生javascript替代jQuery选择器写法:http://caibaojian.com/toutiao/5264?wb
为了达到平稳退化,向后兼容,标记分离的思想,每次写js代码时做的第一件事应该是必要的测试和检查工作:
在js文件里首先添加以下代码进行检查:
window.onload = function(){
if(!document.getElementsByTagName) return false;
if(!document.getElementById) return false;
if(!document.getElementsByClassName) return false;
if(!document.getElementById("selector")) return false;
if(!document.getElementsByTagName("tag")) return false;
if(!document.getElementsByClassName("selector")) return false;
};
通用封装函数:
var $ = function(id){
return typeOf id=="string"?document.getElementById(id):id;
}
var EventUtil = {
addHandler: function(element, type, handler) { // 该方法接受3个参数:要操作的元素,事件名称和事件处理程序函数
if (element.addEventListener) { //检查传入的元素是否存在DOM2级方法
element.addEventListener(type, handler, false); // 若存在,则使用该方法
} else if (element.addEvent) { // 如果存在的是IE的方法
element.attachEvent("on" + type, handler); //则使用IE的方法,注意,这里的事件类型必须加上"on"前缀。
} else { // 最后一种可能是使用DOM0级
element["on" + type] = hander;
}
},
removeHandler: function(element, type, handler) { // 该方法是删除之前添加的事件处理程序
if (element.removeEventListener) { //检查传入的元素是否存在DOM2级方法
element.removeEventListener(type, handler, false); // 若存在,则使用该方法
} else if (element.detachEvent) { // 如果存在的是IE的方法
element.detachEvent("on" + type, handler); //则使用IE的方法,注意,这里的事件类型必须加上"on"前缀。
} else { // 最后一种可能是使用DOM0及方法(在现代浏览器中,应该不会执行这里的代码)
element["on" + type] = null;
}
}
};
//调用方式:
var btn =document.getElementById("btn");
var hander= function(){
alert("clicked");
};
EventUtil.addHandler(btn,"click",hander);
EventUtil.removeHandler(btn,"click",hander); //移除之前添加的事件处理程序
对于很多函数需要页面加载即运行,window.onload封装方法如下:
function addLoadEvent(func){
var oldonload = window.onload;
if(typeof window.onload != "function"){
window.onload = func;
}
else{
window.onload = function(){
oldonload();
func();
}
}
}
addLoadEvent(firstFunction);
addLoadEvent(secondFunction);
//浏览器可视区域窗口大小,兼容不同浏览器
var w= document.documentElement.clientWidth || document.body.clientWidth;
var h= document.documentElement.clientHeight || document.body.clientHeight;
//整体文档窗口大小,兼容不同浏览器
var w=document.documentElement.scrollWidth || document.body.scrollWidth;
var h=document.documentElement.scrollHeight || document.body.scrollHeight;
return false 就相当于终止符,return true 就相当于执行符。
3、noscript标签可被用于可识别 script标签但无法支持其中的脚本的浏览器。如果浏览器支持脚本,那么它不会显示出 noscript 标签中的文本。
4、在动态设置样式时,只要有可能,最好选用CSS,最简单的就是选择最容易实现的方法。
13、//因为elemet.style只能获取内联样式,而element.currentStyle.width是IE浏览器专有属性,getComputedStyle(element, null).width是火狐和Chrome浏览器的特有属性,所以为了兼容,获取内外样式方法如下(不可取复合样式,如background,border,而是应该写成backgroundColor,borderWidth):
function getStyle(obj,name) {
if(obj.currentStyle) {
return obj.currentStyle[name];
}
else
{
return getComputedStyle(obj,null)[name];
}
}
14、function getClass(parent, className) { //第一个参数表示是className是所属那个dom标签下,这样为了提高检索效率
//如果是火狐则调用火狐的getElementsByClassName 内置函数
if (document.getElementsByClassName) {
return document.getElementsByClassName(className);
}
else {
var nodes = parent.getElementsByTagName("*"),
ret = []; //创建一个数组,用于存储类为className的元素
for (i = 0; i < nodes.length; i++) { //遍历子集,判断类名,压入数组
if (nodes[i].className === className)) {
ret.push(nodes[i]);
}
}
return ret;
}
}
15、//js中空格也作为一个文本节点,此函数是为了删除空格准确寻找子节点
function cleanWhitespace(element){
for(var i=0; i<element.childNodes.length; i++){
var node = element.childNodes[i];
if(node.nodeType == 3 && !/S/.test(node.nodeValue)){
node.parentNode.removeChild(node);
}
}
}
16、/*自定义insertAfter函数*/
function insertAfter(newElement,targetElement){
var parent = targetElement.parentNode;
if(parent.lastChild == newElement)
{
parent.appendChild(newElement);
}
else
{
parent.insertBefore(newElement,targetElement.nextSibling);
}
}
17、有些时候你发现调用childNodes属于没有获得你期望的值。比如:
<a href="javascript:;" onclick="getValue(this);">
<span>apple</span>
</a>
function getValue(obj){
var text = obj.children[0].innerHTML;
alert(text);
}
我们希望获得的text属性值为“apple”,但实际上的值是undefined,也就是说获取失败。
原因:childNodes属性返回值包含了元素节点和文本节点,此例中obj.children[0]返回的实际是空格。
解决方案:
1)去掉<span>和<a>之间的空格。
2)改用obj.children[0].innerHTML。children属性只返回元素节点。
18.//寻找下一个元素节点,而不是下一个节点,兼容不同浏览器
function getNextElement(node){
if(node.nodeType == 1)
{
return node;
}
if(node.nextSibling)
{
return getNextElement(node.nextSibling);
}
return null;
}
19、js可以通过insertRow()来进行插入行,通过insertCell()方法来插入单元格。
20、cssText的巧妙用法(兼容不同浏览器):http://www.cnblogs.com/rguanghui/archive/2013/02/26/cssText.html
21.//在for循环中的不正确函数调用
var li = document.getElementsByTagName("li");
var n = li.length;
for (var i=0;i<n;i++) {
li[i].onclick = function() {
alert("你点击的是第" + i + "li"); //i始终为n
};
}
//解决方案
var li = document.getElementsByTagName("li");
var n = li.length;
for (var i=0;i<n;i++){
bar(li[i],i);
}
function bar(x,y){
x.onclick = function(){
alert("你点击的是第" + y +"li");
};
}
22.//js滚轮事件,兼容不同浏览器
var wheel = function (e) {
e = e || window.event;
if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if (e.wheelDelta > 0) { //当滑轮向上滚动时
alert("滑轮向上滚动");
}
if (e.wheelDelta < 0) { //当滑轮向下滚动时
alert("滑轮向下滚动");
}
} else if (e.detail) { //Firefox滑轮事件
if (e.detail> 0) { //当滑轮向上滚动时
alert("滑轮向上滚动");
}
if (e.detail< 0) { //当滑轮向下滚动时
alert("滑轮向下滚动");
}
}
};
//给页面绑定滑轮滚动事件
if (document.addEventListener) {//firefox
document.addEventListener('DOMMouseScroll', wheel, false);
}
//滚动滑轮触发scrollFunc方法 //ie 谷歌
window.onmousewheel = document.onmousewheel = wheel;
23.iframe自适应高度:http://www.html5cn.org/article-7272-1.html http://caibaojian.com/iframe-adjust-content-height.html
24.js实现自适应宽度的瀑布流:http://www.html5cn.org/article-4652-1.html http://bbs.html5cn.org/thread-149650-1-1.html
三种方式实现瀑布流布局:http://www.w3cfuns.com/notes/27624/397dc45aeb17e2da9e0351a3ae973b64.html
25.js实现图片预加载:http://www.cnblogs.com/siqi/p/3304662.html
26.用Array.prototype.join代替原有的基本的字符连接的写法:
var items = [];
ajaxResult.items.forEach(function(item) {
// 构建字符串
items.push('<li>', item.text, '</li>');
});
// 通过innerHTML设置列表内容
document.querySelector('ul').innerHTML = items.join('');
26.DOM优化:https://segmentfault.com/a/1190000008267184
27.如何用JS操纵伪元素:http://nicejade.github.io/2016/10/24/how-to-operate-pseudo_element-using-js.html?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com
28.高性能滚动 scroll 及页面渲染优化:http://web.jobbole.com/86158/
29.轻巧的 JavaScript 动画库:http://anime-js.com/
30.一般认为,使用超时调用来模拟间歇调用的是一种最佳模式。在开发环境下,很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动。而像前面示例中那样使用超时调用,则完全可以避免这一点。所以,最好不要使用间歇调用。