问题1:
    web开发中表单无处不在,从邮件订阅、登陆注册到多页填写信息提交,每次都需要花费大量时间和精力处理。
    为了让客户端表单验证变得更简单,请基于jQuery 开发一个微量级验证插件(validate),为表单提供验证功能,并提交你的代码。
    要求:
    (1)可以让用户去配置选项,拥有定制validate插件的能力,如:

    1. $(“form”). validate({
    2. defaultEvent: “change”, //自定义校验触发事件
    3. })

    (2)至少包含四种表单验证方式(身份证号码验证、手机电话号码、电子邮箱验证、必填字段验证、最大值/最小值验证)。

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
    7. <title>jQuery 作业</title>
    8. <script src="jquery-2.0.3.js"></script>
    9. <script src="jquery.validate.js"></script>
    10. <style>
    11. .context{
    12. width: 500px;
    13. padding: 30px;
    14. margin:50px auto;
    15. border-radius:5px;
    16. box-shadow: 3px 3px 10px #888888;
    17. }
    18. </style>
    19. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
    20. crossorigin="anonymous">
    21. </head>
    22. <body>
    23. <div class="context">
    24. <form>
    25. <div class="form-group">
    26. <label>邮箱</label>
    27. <input type="text" class="form-control" placeholder="请输入邮箱"
    28. data-dv-email = true
    29. data-dv-email-error = '请输入正确的邮箱'
    30. >
    31. </div>
    32. <div class="form-group">
    33. <label>手机</label>
    34. <input type="text" class="form-control" placeholder="请输入手机"
    35. data-dv-mobile = true
    36. data-dv-mobile-error = '请输入正确的手机'
    37. >
    38. </div>
    39. <div class="form-group">
    40. <label>座机</label>
    41. <input type="text" class="form-control" placeholder="请输入座机"
    42. data-dv-landline = true
    43. data-dv-landline-error = '请输入正确的座机'
    44. >
    45. </div>
    46. <div class="form-group">
    47. <label>密码</label>
    48. <input type="password" class="form-control" placeholder="请输入密码"
    49. data-dv-password = true
    50. >
    51. </div>
    52. <button type="text" class="btn btn-success">提交</button>
    53. </form>
    54. </div>
    55. <script>
    56. $('form').validate({
    57. initEvent: 'blur'
    58. });
    59. //扩展功能
    60. $('form').validate.expand({
    61. landline: function() {
    62. return /^\d{3,4}-\d{7,8}$/.test(this.val());
    63. }
    64. });
    65. </script>
    66. </body>
    67. </html>

    正则复习:
    *:匹配前面的子表达式零次或多次。例如,zo 能匹配 “z” 以及 “zoo”。 等价于{0,}。
    +:匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
    ?:匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。
    {n}:n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
    {n,}:n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o‘。
    {n,m}:m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。
    *\w
    :匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。

    1. (function(root, plug) {
    2. var RULES = {
    3. email: function() {
    4. // \w:匹配包括下划线的任何单词字符, 等价于'[A-Za-z0-9_]'
    5. return /^\w+@\w+\.\w+$/.test(this.val());
    6. },
    7. mobile: function() {
    8. // 匹配一个数字字符, 等价于 [0-9]
    9. return /^1\d{10}$/.test(this.val());
    10. },
    11. password: function() {
    12. // 匹配字符,6-12位,注意6,和12之间不能有空格
    13. return /^\w{6,12}$/.test(this.val());
    14. }
    15. };
    16. $.fn[plug] = function(options) {
    17. // 判断this是否为form元素
    18. if (!this.is('form')) {
    19. return this;
    20. }
    21. // 以默认配置为优先,用户配置为覆盖的原则
    22. var __def__ = {
    23. initEvent: 'input',
    24. sign: 'dv',
    25. error: '输入不合法,请检查您的输入'
    26. };
    27. //合并用户配置和默认配置,注意顺序
    28. var ret = $.extend({}, __def__, options);
    29. // 获取所有的input控件
    30. var keyNot = this.find('input');
    31. keyNot.on(ret.initEvent, function() {
    32. var error;
    33. // 因为event事件是在这个DOM上出发的,所以这里的this指向DOM元素
    34. // 要把这里的this包装成jQuery对象
    35. var _this = $(this);
    36. //如果已经有错误信息,则移除
    37. _this.next('span').remove();
    38. $.each(RULES, function(key, func){
    39. var attrValue = _this.data(ret.sign + '-' + key);
    40. if (attrValue) {
    41. var result = func.call(_this);
    42. if (!result) {
    43. error = _this.data(ret.sign + '-' + key + '-error') || __def__.error;
    44. if (error) {
    45. _this.after('<span style="color: red">'+ error +'</span>');
    46. }
    47. }
    48. }
    49. });
    50. });
    51. };
    52. // 扩展功能
    53. $.fn[plug]['expand'] = function(options) {
    54. $.extend(RULES, options);
    55. };
    56. })(this, 'validate');

    问题2:
    图片懒加载(LazyLoad)一直是前端的优化方案之一。
    其核心思想是:先将img标签中的src链接设为同一张图片,真正的图片地址存储在img标签的自定义属性中。当js监听到该图片元素进入可视窗口时,将自定义属性中的地址存储到src属性中。
    请基于jQuery开发一个懒加载插件。

    基础知识拓展:
    http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
    动画展示效果: 网页开发时,常常需要了解某个元素是否进入了”视口”(viewport),即用户能不能看到它。
    jQuery作业练习 - 图1
    目前有一个新的 IntersectionObserver API,可以自动”观察”元素是否可见,Chrome 51+ 已经支持。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做”交叉观察器”。