标签归档:JS

jQuery事件处理

在浏览器交互过程中特定事件发生时脚本会进行相应的处理, jQuery 会针对不同的事件进行特定的处理。

浏览器检测到自身发生变化或遇到错误时,抛出的事件称为浏览器事件。比如浏览器页面内容发生滚动时会触发 scroll 事件,浏览器出错会触发 error 事件。可分别对应事件绑定相应的事件处理函数,这样当事件发生时就会调用此函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//当一个image标签指定要加载的图片不存在时,产生错误
$("<img />", {
  "src" : "not/an/bb.png",
  "alt" : "no image"
})
.error(function() {
  console.log("图片无法加载");
})
.appendTo("body");
 
//当滚动浏览页面内容时,触发 scroll 事件
$(window)
  .scroll(function() {
    console.log("窗口滚动");
  });

通常在页面中的 javascript 会在页面加载完成后才能开始执行,为了防止脚本过早执行,而页面中的元素还未加载而导致异常,通常会使用 ready 函数来保证等 DOM 准备好可以接受处理时才触发进行处理,通常会把整个脚本做成一个回调函数传递给 ready 函数。

1
2
3
$(document).ready(function() {
  //脚本
});

在浏览器中可以触发很多事件,jQuery 提供很多快捷方法对应相应的事件,常见的事件有 click 、 blur 、 focus 、 mousedown 、 mouseup 、submit 等,给对应的元素绑定事件及其处理函数可在事件发生时进行相应的响应。

bind()

可以给元素绑定事件处理函数,可最多接受三个参数,第一个参数为事件名,第二个参数为事件处理函数,可以一次为多个事件绑定同一个事件处理函数,也可以为不同的事件绑定不同的事件处理函数。如果为多个事件绑定同一个事件处理函数,在第一个参数中用空格分隔不同的事件。如果要为不同的事件绑定不同的事件处理函数,需要给bind方法传递一个 JSON 对象。另外可接受的第三个参数用于向事件处理函数传递数据,这个参数是一个 JSON 对象,该参数的数据会绑定到事件处理函数的 event 对象,从而完成数据的传递。

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
//给段落绑定 click 事件,点击段落输出段落被点击信息
$("p").bind("click", function() {
  console.log("段落被点击");
});
 
//给段落绑定 click, mouseover 事件,并输出事件发生信息
$("p").bind("click mouseover", function() {
  console.log("事件发生");
});
 
//给段落绑定 click, mouseover 事件,并输出不同的信息
$("p")
  .bind({
    "click" : function() {
      console.log("Click Event");
    },
    "mouseover" : function() {
      console.log("MouseOver Event");
    }
  });
 
//给事件处理函数传递数据
var Msg = "message 1";
$("#bar").bind("click", {m:Msg}, function(event) {
  console.log(event.data.m);
});
 
var Msg = "message 2";
$("p.foo").bind("click", {m:Msg}, function(event) {
  console.log(event.data.m);
});

unbind()

可以使用 unbind 方法移除元素的事件,如果不带参数调用该方法,则会移除当前元素的所有绑定事件,如果需要指定移除那个事件,就把该事件名作为第一个参数传递给 unbind 方法,如果要移除指定的事件处理函数,就把准备移除的事件处理函数作为第二个参数传递给 unbind 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//删除绑定在段落中的所有事件
$("p").unbind();
 
//仅删除绑定在段落中的click事件
$("p").unbind("click");
 
//删除指定事件处理函数
var fun1 = function() {
  console.log("event one triggered!");
},
    fun2 = function() {
  console.log("another one event!");
};
$("#bar").bind("click",fun1)
         .bind("click",fun2)
         .trigger("click")
         .unbind("click", fun1);

live() 和 die()

live 和 die 跟 bind 和 unbind 类似,也是负责为元素绑定事件和事件处理函数,所不同的是能为动态添加到 DOM 中的匹配元素绑定事件和事件处理函数,用 live 绑定的事件处理和事件处理函数必须使用 die 来解除绑定, 在 jQuery 1.7 以后 live 以过时,应该使用on方法。

one()

跟bind功能唯一的区别就是使用one绑定的事件及事件处理函数是一次性的,事件触发后自动解除绑定,其他功能跟bind相同。

trigger()

触发事件使用trigger,接受两个参数,第一个参数是被触发的事件名,第二个参数可选,为数组类型,用于给事件处理函数传递数据。

1
2
3
4
5
6
7
8
9
10
11
//给 id = bar 的元素绑定 click 事件,然后触发
$("#bar").bind("click", function() {
  console.log("Clicked!");
}).trigger("click");
 
//给事件处理函数传递数据
var notice = "I was triggered!";
$("#bar").bind("click", function(event, msg) {
  var log = msg || "I was clicked!";
  console.log(log);
}).trigger("click", [notice]);

jQuery数据集处理函数及动画效果函数

map / each / show / hide / fadeOut / fadeIn / fadeTo / slideUp

slideDown / slideToggle /animate

本文中代码其测试页面点击此处可以查看

map & each

使用回调函数对结果集内的每个元素进行处理,回调函数接受两个参数,分别是当前元素索引和当前元素。二者的区别在于map返回回调函数返回值的新对象,each返回受回调函数影响的原始对象。
比如给所有的段落和类为foo的元素追加标签名和索引。

1
2
3
$("p,.foo").map(function(index, ele) {
  $(this).append("  " + ele.tagName + "  #" + index);
});

可同样使用each完成同样的功能,但是如果对追加了标签名和索引的元素集合进一步处理,比如给标签为,类为foo的元素设置一个红色的字体,黄色的背景,则应该使用each,如果使用map则无法达到期望的结果。

1
2
3
4
5
$("p,.foo")
  .each(function(index,ele) {
    $(this).append("  " + ele.tagName + "  #" + index);
  })
  .find("span.foo").css({"color" : "red", "background" : "yellow"});

show & hide

不带参数调用这两个函数会对元素的样式添加或删除display:none;
如 $(“#bar”).hide(); 或 $(“#bar”).show();
这样调用没有动画效果,直接显示或者直接隐藏,没有过度效果,可以通过增加过度时间参数来增加效果。
如 $(“#bar”).hide(2000); 或 $(“#bar”).show(2000);

fadeOut 、fadeIn、fadeTo

可以实现元素淡入淡出效果,fadeOut淡出,通过将元素透明度从1调整到0,来实现元素的淡出,元素淡出结束后设置元素display:none;样式,可设置持续时间参数,默认持续时间为400ms,也接受回调函数参数,在结束后被调用。fadeIn淡入,通过将元素透明度从0调整到1,来实现元素的淡入,元素淡入结束后如果元素有display:none;样式,则会移除该样式。fadeTo可指定淡入或淡出的透明度,为0至1之间的一个数值。必须提供两个参数,一个是持续时间,另一个是目标透明度,也可以通过回调函数作为第三个参数用于在调用结束后被调用。
淡入淡出函数接受两个文本的快捷持续时间,分别是fast和slow,分别对应200ms和600ms。
如将表单元素淡出,并输出对应淡出信息,再讲表单元素淡入,输出对应淡入信息。

1
2
3
4
5
6
7
$("form")
  .fadeOut(1000, function() {
    console.log("淡出!");
  })
  .fadeIn(1000, function() {
    console.log("淡入!");
  });

将表单淡出到50%透明度,并输出对应信息。

1
2
3
$("form").fadeTo(1000, 0.5, function() {
  console.log("50%透明度");
});

slideUp、slideDown、slideToggle

可以实现元素的收缩与展开,slideUp向上收缩元素,slideDown向下展开元素,slideToogle是展开和收缩的开关,当前元素处于展开状态,应用slideToggle则会收缩,当处于收缩的时候应用则会展开,收缩与展开结束后通过设置元素display:none;样式或删除该样式给用户视觉展现。都可以接受两个参数,分别是持续时间和回调函数。

1
2
3
4
5
6
7
$("p.foo")
  .slideUp(1000, function() {
    console.log("收缩!");
  })
  .slideDown(1000, function() {
    console.log("展开!");
  });

同样针对类为foo的段落使用slideToggle。

1
2
3
4
5
6
7
8
$("p.foo").slideToggle(1000, function() {
  $bar = $("p.foo").attr("style");
  if ($bar === "display: none;") {
    console.log("slide Up");
  } else {
    console.log("slide Down");
  }
});

animate

能利用元素绝大多数可视CSS属性制作动画,其接受两种格式的多种参数,其中第二种格式的参数有更多的选项​,分别是
animate({json target css}, duration, action, succ callback)
animate({json target css}, {json animate options})
我们给id=bar的段落增加背景色和边框,然后5秒内完成段落的长宽缩放,并输出完成信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$("#bar")
  .css({
    "background" : "yellow",
    "border" : "1px solid black"
  })
  .animate(
    {
      "width" : "500px",
      "height" : "100px"
    },
    5000,
    "swing",
    function() {
      console.log("animate complete!");
    });

采用第二种格式的参数代码如下,效果与前段一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$("#bar")
  .css({
    "background" : "yellow",
    "border" : "1px solid black"
  })
  .animate({
               "width" : "500px",
               "height" : "100px"
           },
           {
             "duration" : 5000,
             "easing" : "swing",
             "complete" : function() {
               console.log("Animate complete!");
             }
          });

jQuery中的内容包装与元素删除函数

wrap / unwrap / wrapAll / wrapInner

remove / detach

测试文件见前篇文章中的测试页面代码。点击此处可直接进入

wrap

在元素(标签)外包装一个或多个元素(标签),函数参数接受元素集合,也接受返回标签的回调函数作为参数。如通过在所在标签<span></span> 标签外包装<strong></strong>标签、给所有的段落包装<strong></strong>标签,使得文字变粗,或者给所选元素集合包装一个<div>

在使用的时候注意标签的嵌套是否合法,如给所有的段落外增加<strong></strong>就属于嵌套不合法。

1
2
3
4
5
6
7
8
$("span").wrap("<strong></strong>");
//$("span").wrap("<strong />"); $("span").wrap("<strong>");
//像上面这样写也可以
 
//类为foo的span包装<strong>标签,其他span标签包装<em>标签
$("span").wrap(function() {
  return $(this).is(".foo") ? "<strong></strong>" : "<em></em>";
});

unwrap

删除包住所选元素的元素,不接受参数,如要删除包住<span>元素的元素。

1
$("span").unwrap();

wrapAll

wrapAll将所选的元素集合都用一个元素包装,如将所有的段落用一个<div>包住,需要注意的是wrapAll是会移动元素的,在<span>元素集合上使用wrapAll,使用<strong>包住该元素集合。

1
2
3
4
5
6
7
var div = $("<div>", {
  "css" : {"background" : "yellow"}
});
$("p").wrapAll(div);
 
//注意元素的移动
$("span").wrapAll("<strong></strong>");

wrapInner

包裹元素内容,可以用标签包住元素内的所有内容,如将所有的段落文字变成粗体。

1
$("p").wrapInner("<strong />");

remove & detach

remove和detach用于删除DOM中的元素,其区别是remove直接删除选中的元素,detach除了删除选中的元素外,还保存了删除元素的数据。

jQuery在DOM中添加元素

学习jQuery使用的测试页面代码如下,后续的继续学习中如无变化则以该文档为测试练习文档,练习时jQuery的版本为1.11.1,其所在路径与测试页面相同,该系列文档为《深入PHP与jQuery开发》的阅读笔记及总结。

    <!DOCTYPE html>
    <html>
    <head>
      <title>Reading Test Page</title>
    </head>
    <body>
      <p>Hello World!</p>
      <p class="foo">Another paragraph, but this one has a class.</p>
      <p><span>This is a span inside a paragraph.</span></p>
      <p id="bar">Paragraph with an id. 
        <span class="foo"> And this sentence is in a span.</span>
      </p>
 
      <form action="#" method="post">
        <fieldset>
          <legend>Sign Up Form</legend>
          <label for = "name">Name</label><br>
          <input name="name" id="name" type="text"><br>
          <label for="password">Password</label><br>
          <input name="password" id="password" type="password"><br><br>
          <label>
            <input type="radio" name="loc">
            I'm on my computer
          </label><br>
          <label>
            <input type="radio" name="loc" checked="checked">
            I'm on a shared computer
          </label><br><br>
          <input type="submit" value="Log In"><br>
          <label>
            <input type="checkbox" name="notify" disabled="true">
            Keep me signed in on this computer
          </label><br>
        </fieldset>
      </form>
      <script type="text/javascript" src="jquery-1.11.1.js"></script>
    </body>
    </html>

append() / appendTo()

作用:在目标元素内之后添加元素
区别:由目标元素调用 / 由新建元素调用
示例:

    //append()
    var para = $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    });
    $("body").append(para);
 
    //appendTo()
    $("<p>", {
       "text" : "I'm a new paragraph!",
       "css"  : {"background" : "yellow"}
    }).appendTo("body");

prepend() / prependTo()

作用: 在目标元素内之前添加元素
区别: 由目标元素调用 / 由新建元素调用
示例:

    //prepend()
    var para = $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    });
    $("body").prepend(para);
 
    //prependTo()
    $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    }).prependTo("body");

after() / insertAfter()

作用: 在目标元素外之后添加元素
区别: 由目标元素调用 / 由新建元素调用
示例:

    //after()
    var para = $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    });
    $("p.foo").after(para);
 
    //insertAfter()
    $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    }).insertAfter("p.foo");

before() / insertBefore()

作用: 在目标元素外之前添加元素
区别: 有目标元素调用 / 由新建元素调用
示例:

    //before()
    var para = $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    });
    $("p.foo").before(para);
 
    //insertBefore()
    $("<p>", {
      "text" : "I'm a new paragraph!",
      "css"  : {"background" : "yellow"}
    }).insertBefore("p.foo");

常见的腻子脚本功能摘要

经常见到一些网站中用一些腻子脚本「polyfill」,对其主要的功能进行一下摘要记录。

html5shiv.js  让IE8及更低版本的IE浏览器识别section、article、nav等HTML5元素;
selectivizr 让IE6/7/8 支持:first-child 等CSS选择符;
CSS3Pie 让低版本的IE支持圆角、渐变、边框图片、阴影等可视化CSS3功能;
Respond.js 让旧浏览器支持媒体查询;
-prefix-free 为需要厂商前缀的CSS3声明增加前缀;
borderBoxModel.js 让IE6/7支持CSS3的box-sizing属性;

这些腻子脚本主要用于弥补IE及低版本浏览器的不足,在GitHub有一个腻子脚本列表,参见「这里」。