Dom与jQuery区别比较
2018-01-22 本文已影响0人
前端工程狮_jam
DOM是文档对象模型(Document Object Model,简称DOM),jQuery是一个JavaScript 库,极大地简化了JavaScript编程。注意dom对象与jquery对象,如果需要详情了解可以参考w3c网址和jQuery官网。
- 自定义getElementsByClassName方法
// 自定义getElementsByClassName方法
function getElementsByClassName(node, className){
if(node.getElementsByClassName){
//使用现有方法 getElementsByClassName只会获取父级下的所有子类符合条件的,而不是从当前级别开始查找
return node.getElementsByClassName(className);
}else{
var results = new Array();
var elems = document.getElementsByTagName("*");
for(var i=0; i<elems.length; i++){
if(elems[i].className.indexOf(className) != -1){
results[results.length] = elems[i];
}
}
return results;
}
}
var dom = document.getElementById("test");
var selector = getElementsByClassName(dom, 'box');
- window.onload的处理机制与用法,以及与$(document).ready(function(){})的区别
//window.onload 网页加载完毕后会触发一个onload事件,每个事件处理函数只能绑定一条指定
window.onload = firstFunc;
window.onload = secondFunc; //只会触发第二个
//解决方案一
window.onload = function(){ firstFunc(); secondFunc();} //创建匿名函数容纳两个函数
//解决方案二
function addLoadEvent(func){
var oldOnLoad = window.onload;
if(typeof oldOnLoad != "function"){
window.onload = func;
}else{
window.onload = function(){
oldOnLoad();
func();
}
}
}
function firstFunc(){
console.log('111111111');
}
function secondFunc(){
console.log('222222222');
}
addLoadEvent(firstFunc);
addLoadEvent(secondFunc);
//效果类似window.onload,window.onload是必须等待网页中所有的内容加载完比后(包括图片)才能执行。document.ready是网页中所有DOM结构绘制完毕就执行,可能DOM元素所关联的东西并没有加载完(例如图片)。也就是说$(document).ready要比window.onload先执行。
$(document).ready(function(){})//可以简写为 $(function(){}),可以重复绑定多个初始化
$(document).ready(function(){
console.log("Hello World!");
$(this).addClass("highlight").children("a").show().end().siblings().removeClass("highlight").children("a").hide();
});
- 节点属性和节点方法
<style type="text/css">
.container{
font-size: 20px;
}
</style>
<div id="test" class="container" style="font-size: 30px;">
<div id="box" class="box"></div>
<p id="text">text</p>
</div>
// nodeType 节点类型,1是标签节点 2属性节点 3是文本节点
// nodeValue 节点值,主要是针对文本节点的值,类似jq的text
// nodeName 节点名称,返回的字符串是全大写,例如 DIV/IMG等
// childNodes 孩子节点数量,包括元素节点和文本节点
// style.property 获取自身的样式,需要引用中间带一个减号的CSS属性,例如font-size需要转变成驼峰命名法fontSize。
// style.property这种方式只能获取元素的行内样式,无法获取浏览器默认样式和它的ID选择器或者类选择器附带的样式
// className 任何一个元素节点都有一个className
var dom = document.getElementById("test");
dom.nodeName // DIV
var text = document.getElementById("text");
text.nodeType // 1
text.firstChild.nodeType // 3
text.firstChild.nodeValue // text
dom.childNodes // 5
dom.style.fontSize // 30px
dom.className // container
//filter方法可以筛选过滤条件
$("ul li:gt(5):not(:last)") //获得索引值大于5的,但不包含最后一个的所有li元素
$("ul li").filter(":contains('苹果'),:contains('香蕉'),:contains('雪梨')").addClass("highlight");
//删除节点 remove()删除包括自身和后代所有元素 empty()只删除后代所有元素,不清空自身
$('div').remove()
$('div').empty()
//复制节点 clone(flag) flag为true代表绑定事件也复制,默认不复制
$('#test').clone(true);
//替换节点 replaceWith和 replaceAll
$("p").replaceWith("<span>test</span>") == $("<span>test</span>").replaceAll("p");
// 包裹节点 wrap() 和 wrapAll() 前者是匹配的都重新包一层,后者是把所有匹配的只包最外一层(慎用,会改变dom结构)
// wrapInner 匹配元素里面的把文本节点包一层
$('span').wrap('<strong></strong>');
$('span').wrapAll('<strong></strong>');
$('span').wrapInner('<strong></strong>');
// 切换样式,控制行为上的重复切换。如果是原来就显示则隐藏,否则相反。
$("#test").toggle(function(){
//显示元素
}, function(){
//隐藏元素
})
// 样式重复切换,效果类似前者toggle切换
$("#test").toggleClass("myClass");
//判断是否有某个样式
$("#test").hasClass("myClass");
//判断元素是否显示,可以使用jq方式的is
$("#panel box").bind("click", function(){
if($(this).next("div.btn").is("visible")){
//如果已经显示就隐藏,do something
}
})
- 创建元素节点和文本节点增加给某个父级
var container = document.getElementById("test");
var dom = document.createElement("p");
var text = document.createTextNode("This's my content");
dom.appendChild(text);
container.appendChild(dom);
parentElement.insertBefore(newElement, targetElement);
var box = document.getElementById("box");
box.parentNode.insertBefore(dom, box);
- Dom原生Ajax请求
function getHTTPObject(){
if(typeof XMLHttpRequest == "undefined"){
XMLHttpRequest = new ActiveXObject("MSXML2.XMLHTTP"); //兼容IE
}
return new XMLHttpRequest();
}
//获取服务端数据
function getContent(){
var request = getHTTPObject();
if(request){
//第一个参数是访问请求类型GET POST SEND,
//第二个参数是数据来源地址,一般指服务器接口
//第三个参数代表是否异步方式发送和处理
request.open("GET", "data.json", true);
request.onreadystatechange = function(){
//readyState有5种值,0是未初始化 1是正在加载 2是加载完毕 3是正在交互 4是完成
if(request.readyState == 4){
console.log(request.responseText);
}
};
request.send(null);
}else{
alert("Sorry, Error");
}
}
- addClass和insertAfter实现原理
//给元素增加样式
function addClass(element, className){
if(!element.className){
element.className = className;
}else{
element.className += " " + className
}
}
addClass(document.getElementById("test"), 'addCustomerClass');
//默认没有insertAfter,可以借助nextSibling实现
function insertAfter(newElement, targetElement){
var parent = targetElement.parentNode;
if(parent.lastChild == targetElement){
parent.appendChild(newElement);
}else{
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
- canvas实践
<canvas id="canvas" width="120" height="40">
<p>Power by Html5 Canvas</p>
</canvas>
//canvas原点(0,0)位于左上角,越往右x的值越大,右往下的y的越大
function draw(){
var canvas = document.getElementById("canvas");
if(canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(120.0, 32.0); //从某起点开始画
//三次贝塞尔曲线需要三个点。前两个点是用于三次贝塞尔计算中的控制点,第三个点是曲线的结束点。曲线的开始点是当前路径中最后一个点。
ctx.bezierCurveTo(120.0, 36.4, 116.4, 40.0, 112.0, 40.0); //绘制一条三次贝塞尔曲线
ctx.lineTo(8.0, 40.0); //画一条线
ctx.bezierCurveTo(3.6, 40.0, 0.0, 36.4, 0.0, 32.0);
ctx.lineTo(0.0, 8.0);
ctx.bezierCurveTo(0.0, 3.6, 3.6, 0.0, 8.0, 0.0);
ctx.lineTo(112.0, 0.0);
ctx.bezierCurveTo(116.4, 0.0, 120.0, 3.6, 120.0, 8.0);
ctx.lineTo(120.0, 32.0);
ctx.closePath();
ctx.fillStyle="green"; //填充颜色
ctx.fill();
ctx.lineWidth = 2.0; //线宽度
ctx.strokeStyle="#0000ff"; //线颜色
// ctx.strokeStyle = "rgb(255,255,255)";
ctx.stroke();
}
}
window.onload = draw();
- dom方式与Jquery获取元素方式和判断对象是否为空
// dom方式与Jquery方式
document.getElementById("test").innerHTML == $("#test").html()
var text = document.getElementById("text")
text.firstChild.nodeValue == text.innerText == text.textContent == $("#text").text();
// dom对象是否存在
document.getElementById("xx").style.color = "red"; //报错,打不到ID为xx的dom对象
if(document.getElementById("xx")){}
//jq对象是否存在
$("#xx").css("color", "red"); //不报错,找不到对象会忽略,jq方式访问永远会返回的是一个对象
if($("#xx")){} //不允许这样判断是否存在
if($("#xx").length > 0){} //根据元素的长度去判断,推荐
if($("#xx")[0]){} //dom对象方式去判断
- dom对象与jq对象互转
// dom与jq互转,jq对象只能用jq方法,dom对象只能用内置的dom方法,不能互窜
$("#test") //jq对象
$("#test")[0] //dom对象
$("#test").get(0) //dom对象
var dom = document.getElementById("test"); //dom对象
$(dom) //jq对象
- checkbox是否选中判断方式
<input type="checkbox" id="ck" checked="true"><label for="ck">同意</label>
var ck = document.getElementById("ck");
if(ck.checked){ //dom方式判断
console.log('checked');
}
if($(ck).is(":checked")){ //jq方式判断
console.log('checked');
}
- dom与jquery等价关系
$(".one+div") == $(".one").next("div"); //选择.one后下一个相邻的div标签
$("#prev~div") == $("#prev").nextAll("div"); //选择#prev后所有同级的div标签
$("#prev").siblings("div"); //选择#prev所有同级的div标签,无论前后位置
// 创建元素节点
document.createElement("li") == $("<li></li>");
var li = document.createElement("li");
document.getElementById("ul").appendChild(li) == $("ul").append("<li></li>");
//创建文本节点
var dom = document.createElement("p");
var text = document.createTextNode("This's my content");
dom.appendChild(text);
//等价于以下的jq方式
$("<p>This's my content</p>")
//创建属性节点
var dom = document.createElement("p");
var title = dom.setAttribute("title", "标题");
dom.appendChild(text);
//等价于以下的jq方式
var p = $("<p title='标题'></p>")
$("body").append(p);
// 注意append prepend是元素内部后置插入/前置插入,和appendTo prependTo是跟前面两个操作颠倒,例如是$("<p>This's my content</p>").appendTo('body');
// after before是匹配元素后面插入/前面插入 和 insertAfter insertBefore是跟前面两个操作颠倒
- jquery过滤器
//基本过滤选择器
$("div:first") //选择所有div标签元素中的第一个div元素
$("div:last") //选择所有div标签元素中的最后一个div元素
$("div:not(.myClass)") //选择class类不包含myClass的所有div标签元素
$("div:odd") //选择索引是奇数的所有div标签元素
$("div:even") //选择索引是偶数的所有div标签元素
$("div:eq(0)") //index从0开始算起,有扩展是 :gt(index)大于index不包括自身 :lt(index)小于index不包括自身
$(":header") //所有h标签元素
$(":animated") //所有当前正在执行动画的所有元素
//内容过滤选择器
$("div:contains('测试')") //选取文本内容包含'测试'的元素
$("div:empty") //选取不包含子元素或者文本的空元素
$("div:has(p)") //选取含有p元素的div元素
$("div:parent") //选取含有子元素或者文本的div元素
//可见性过滤选择器
$(":hidden") //选取所有不可见的元素
$("div:visible") //选取所有可见的div元素
//属性过滤选择器
$("div[id]") //选取含有id属性的所有div元素
$("div[title=test]") //选取含有title属性为test的所有div元素
$("div[title!=test]") //选取title属性不等于test的所有div元素(注意没有title属性也会被选中)
$("div[title=test]") //选取含有title属性为test的所有div元素
$("div[title^=test]") //选取含有title属性以test开头的所有div元素
$("div[title$=test]") //选取含有title属性以test结尾的所有div元素
$("div[title*=test]") //选取含有title属性含有test的所有div元素
$("div[id][title*=test]") //选取含有id属性并含有title属性为test的所有div元素
//子元素过滤选择器
$("div:nth-child(3n+1)") //:nth-child(index/odd/even) n从0开始算,index从1开始算起,区别eq(0)。可以选取奇偶数
$("ul li:first-child") //选取每个ul中第一个li元素
$("ul li:last-child") //选取每个ul中最后一个li元素
$("ul li:only-child") //选取每个ul中只有唯一一个li元素
//表单对象属性选择器
$("#form1:enabled") //选取id为form1的表单内所有可用元素
$("#form1:disabled") //选取id为form1的表单内所有不可用元素
$("input:checked") //选取所有被选中的input元素
$("select:selected") //选取所有被选中的选项元素
//表单选择器
$(":input") //选取所有input textarea select button元素
$(":text") //选取所有单行文本框元素
$(":password") //选取所有的密码框元素
$(":radio") //选取所有的单选框元素
$(":checkbox") //选取所有的复选框元素
$(":submit") //选取所有的提交按钮
$(":image") //选取所有的图像按钮
$(":reset") //选取所有的重置按钮
$(":button") //选取所有的button按钮
$(":file") //选取所有的文件上传域
$(":hidden") //选取所有不可见元素
- jq事件和鼠标移入移出效果实现
<a href="" class="tooltip">测试鼠标悬浮移入移出功能</a>
$("input").focus() //获取焦点事件
$("input").blur() //失去焦点事件
$("div").children() //获取匹配的元素下的所有子元素,而不考虑后代元素和文本节点
$("div").next() //获取匹配的元素后面相邻的同辈元素
$("div").prev() //获取匹配的元素前面相邻的同辈元素
$("div").siblings() //获取匹配的元素前后所有的同辈元素
$("div").closest() //获取最近的匹配元素,首先判断当前元素是否匹配,不匹配就继续往父级查找,一直查找不到返回一个空对象
//此外还有find() filter() nextAll() prevAll() parent() parents()等等方法
//前者返回实际高度,不带单位,后者返回可能是样式,例如是auto
$("#test").heigth() != $("#test").css("height")
//获取元素在当前视窗相对偏移量,返回对象包含两个属性,即top和left,它只对可见元素可效
$("div").offset()
//获取元素相对于最近的一个祖父级样式设为relative或absolute的相对偏移量,返回对象跟offset()一样
$("div").position()
//scrollTop() scrollLeft() //分别获取元素的滚动条距离顶端和左侧的距离,也可以设参数赋值
//mouseover() mouseout() 鼠标移入移出效果,也可以用hover的方式实现 hover(enter,leave)
//方式一
$("a.tooltip").mouseover(function(e){
var tooltip = "<div id='tooltip'>我是弹出框提示</div>";
$('body').append(tooltip);
$("#tooltip").css({
"top": e.pageY + "px",
"left": e.pageX + "px"
}).show('fast');
}).mouseout(function(){
$("#tooltip").remove();
}).mousemove(function(e){
$("#tooltip").css({
"top": e.pageY + "px",
"left": e.pageX + "px"
});
})
//方式二
$("a.tooltip").hover(function(e){
var tooltip = "<div id='tooltip'>我是弹出框提示</div>";
$('body').append(tooltip);
$("#tooltip").css({
"top": e.pageY + "px",
"left": e.pageX + "px"
}).show('fast');
}, function(){
$("#tooltip").remove();
});
- 事件绑定
// 事件绑定可以用bind和on,删除事件绑定用unbind
$("#panel box").bind("click", function(){}) 等价于 $("#panel box").on("click", function(){})
$("#panel box").bind("click", function(){}) 等价于 $("#panel box").click(function(){})
$("#panel box").unbind(); //不带任何参数,全部事件类型的绑定事件被删除
$("#panel box").unbind("click"); //只带事件类型参数,只会删除所有事件类型的绑定方法
$("#panel box").unbind("click", funcName); //只删除事件类型一致且方法一样的绑定方法
// 一次性绑定多个事件类型,用空格隔开多个事件类型
$("#panel box").bind("mouseover mouseout", function(){
$(this).toggleClass('over');
})
// 只想绑定事件触发一次用one,用法类似bind
$("#panel box").one("click", function(){})
// 主动触发绑定事件可以用trigger
$("input").trigger("focus") //不仅会触发input上绑定的focus事件,也会使input获得焦点(默认行为)
$("input").triggerHandler("focus") //只会触发input上绑定的focus事件,不会获取焦点
//事件对象的属性
$("a").click(function(event){
console.log(event.type); //事件的类型,返回click
event.preventDefault(); //阻止事件的默认行为
event.stopPropagation(); //阻止事件的向上(父级)冒泡行为
event.target; //获取触发事件的元素本身对象
event.relatedTarget; //属性的返回值是不确定的,这取决于触发事件的具体行为,返回的是相关元素
return false; //阻止链接跳转
});
- 自定义animate动画
//fadeIn() fadeOut() //淡入淡出功能,参数是 fast/slow/normal/1000(毫秒)
//fadeTo(speed, opacityVal) //eg:fadeTo(600, 0.2)
//slideDown() slideUp() 当某个元素dispaly为none时候,slideDown从上到下延伸,参数跟fadeIn一样
//slideToggle() 跟slideDown() slideUp()切换效果一致
//自定义animate(params, speed, callback)动画
//停止动画用stop(flag) 没指定参数时候只会停止当前正在执行的动画,如果flag为true,还会清空所有的动画队列
$("#panel1").click(function(){
$(this).animate({left:"+=500px", height:"200px"}, 300); //两个距离同时发生
$(this).animate({left:"+=500px"}, 300).animate({height:"200px"}, 300); //链式写法,一个接一个
});