14 jQuery与jQuery ajax

题目1: jQuery 中, $(document).ready()是什么意思?

定义和用法:

当 DOM(文档对象模型) 已经加载,并且页面(包括图像)已经完全呈现时,会发生 ready 事件。
由于该事件在文档就绪后发生,因此把所有其他的 jQuery 事件和函数置于该事件中是非常好的做法。
ready() 函数规定当 ready 事件发生时执行的代码。
ready() 函数仅能用于当前文档,因此无需选择器。

允许使用以下三种语法:
$(document).ready(function)
$().ready(function)
$(function)

jQuery中$(document).ready与Javascript中window.onload区别:

window.onload:
window.onload在页面的DOM加载完成,所有的图片、子frame等所有的元素都加载完成的时候才会触发。
$(document).ready():
$(document).ready方法发生在DOM树构造完成,而不会等到其余的所有的元素都加载完成。其实说白了就是ready方法在onload之前发生,一般发生在DOM树构造完成的时候。

具体一些,可以从以下几方面对比$(document).ready和window.onload的区别:

1.执行时间
window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready是DOM结构绘制完毕后就执行,不必等到图片等资源加载完成后才执行。

2.编写个数不同
window.onload不能同时编写多个,如果有多个window.onload方法,后面会覆盖前面,并且只会执行一个onload方法。
$(document).ready可以同时编写多个,并且都可以得到执行。
如下例:

1
2
3
4
5
6
7
8
9
10
11
12
window.onload = function(){
console.log("window.onload event1");
}
window.onload = function(){
console.log("window.onload event2");
}
$(document).ready(function(){
console.log("jquery ready event1");
})
$(document).ready(function(){
console.log("jquery ready event2");
})

执行结果如下:
输出结果
可以看出ready先于onload事件。并且onload只能有一个,后面覆盖前面,而ready恰好相反。

3.简化写法
window.onload没有简化写法。
$(document).ready(function(){})可以简写成$(function(){});
在一些开发中,大多数时候,第一行写的是:

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

关于$(window).load:

$(window).loadwindow.onload其实没什么大的区别
jquery API中提到$(window).load方法是$(window).on('load',handler)的shortcut,而且$(window).on('load',handler)相当于window.onload方法

1
2
3
4
5
6
7
$(window).load(function (){  
// coding
});
//等价于 JavaScript 中的以下代码
window.onload = function (){
// coding
}

如果真要说区别的
$(window).load(handler)可以用多次使用,并且handler都会依次执行。但是window.onload就不行,就像上面介绍的一样,window.onload = handler后面的hanlder会覆盖之前的handler。

注意:由于在$(document).ready()方法内注册的事件,只要 DOM 就绪就会被执行,因此可能此时元素的关联文件未下载完。例如与图片有关的 html 下载完毕,并且已经解析为 DOM 树了,但很有可能图片还没有加载完毕,所以获取图片的高度和宽度这样的属性此时不一定有效。要解决这个问题,可以使用 jquery 中另一个关于页面加载的方法 —load() 方法。 Load() 方法会在元素的 onload 事件中绑定一个处理函数。如果处理函数绑定给 window 对象,则会在所有内容 ( 包括窗口、框架、对象和图像等 ) 加载完毕后触发,如果处理函数绑定在元素上,则会在元素的内容加载完毕后触发。

用原生JS实现jQuery的ready方法

那么,对于某些特殊需求,不希望使用jQuery,但又想实现jQuery的ready方法。该如何用原生JS实现jQuery的ready方法呢?下面是其中之一的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function ready(fn){  
if(document.addEventListener){
//标准浏览器
document.addEventListener('DOMContentLoaded',function(){
//注销事件,避免反复触发
document.removeEventListener('DOMContentLoaded',arguments.callee,false);
//执行函数
fn();
},false);
}else if(document.attachEvent){
//IE浏览器
document.attachEvent('onreadystatechange',function(){
if(document.readyState=='complete'){
document.detachEvent('onreadystatechange',arguments.callee);
//执行函数
fn();
}
});
}
}

下面用一段代码验证ready函数的正确性:

1
2
3
4
5
6
window.onload = function(){
console.log("window.onload event");
}
ready(function(){
console.log('window ready event')
})

执行效果如下:
执行效果

题目2: $node.html()和$node.text()的区别?

  • 相同点:
    html()和text()都是读写两用方法。

  • 区别:

    • html()对jQuery对象的html进行操作,相当于原生js的innerHTML;text()对jQuery对象的text进行操作,相当于原生js的innerText
    • 没有传递参数时,html()获取的是第一个匹配元素的innerHTML;text()获取的是所有匹配元素的innerText
    • 传递了string参数时,html()修改所有匹配元素的innerHTML为参数值,text()修改所有匹配元素的innerText为参数值
      如例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      <body>
      <ul>
      <li><span>item1 </span></li>
      <li><span>item2 </span></li>
      <li><span>item3 </span></li>

      </ul>
      <script>
      console.log($('li').html())//<span>item1 </span>
      console.log($('li').text())//item1 item2 item3

      console.log($('li').html('<span>insert span</span>'))//
      console.log($('li').text('insert text'))//
      </script>
      </body>

下面代码打印结果:

1
2
console.log($('li').html())//<span>item1 </span>
console.log($('li').text())//item1 item2 item3

下面代码打印结果:

1
2
console.log($('li').html('<span>insert span</span>'))
console.log($('li').text('insert text'))

题目3: $.extend 的作用和用法?

定义
jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象。相同属性后面对象的值覆盖前面对象的值,target将被修改并通过$.extend()返回。参数 deep 为布尔值true/false,用来设置合并操作是否递归(深拷贝)。$.extend( [deep ], target, object1 [, objectN ] )
注意:

  1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略。此时,target就是jQuery对象本身。通过这种方式,我们可以为全局对象jQuery添加新的函数。
  2. 如果多个对象具有相同的属性,则后者会覆盖前者的属性值。

用法:
如果我们想保留原对象,可通过传递一个空对象作为目标对象:
var object = $.extend({}, object1, object2); //将object1, object2合并到{}中
默认$.extend()合并操作是浅复制,如果第一个对象的属性本身是一个对象或数组,那么它将完全用第二个对象相同的key重写一个属性。这些值不会被合并。如果将 true作为该函数的第一个参数,那么会在对象上进行递归的合并。

######语法:
$.extend( target [, object1 ] [, objectN ] )

如例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
var object1 = {
amy: 0,
tom: {
height: 180, user: {
age: 20
}
},
}
var object2 = {
jim: 100,
tom: {
weight: 100, user: {
age: 100
}
}
}
console.log($.extend(object1, object2))//浅复制,将object2合并到object1中
console.log(object1)//object1为返回的最终结果
console.log(object2)//object2值不变
console.log($.extend(true, object1, object2))//深复制,将object2合并到object1中
</script>

打印结果:

1
2
console.log($.extend(object1, object2))
//浅复制,将object2合并到object1中,tom对象属性完全被object2中的tom属性取代


1
console.log(object1)//object1为返回合并后的最终结果


1
console.log(object2)//object2值不变


1
2
console.log($.extend(true, object1, object2))
//深复制,将object2合并到object1中


关于深复制和浅复制的区别参考:https://www.cnblogs.com/tracylin/p/5346314.html

题目4: jQuery 的链式调用是什么?

链式调用适用于异步编程,可避免线程阻塞,实现原理是在当前函数执行完后return this,即返回该函数的执行环境,下一个函数就可以继续在这个函数下运行了,结果就是多种方法在一个jQuery对象上一个接一个地调用
示例:

1
2
3
4
5
6
7
8
9
10
11
<body>
<p>hello world</p>
<h2>bybe world</h2>
<script>
$('p').on('mouseenter', function () {
$(this).css('background-color', 'red')
}).on('mouseleave', function () {
$(this).css('background-color', 'blue')
}).parents('body').find('h2').toggle(500)
</script>
</body>

执行效果:
初始状态

500ms后bybe world消失

鼠标放置上去
鼠标移开
本例中,mouseenter和mouseleave是事件监听,只有事件触发后才会执行相应函数中的代码,属于异步执行,与以上所说的在同一jQuery上一个接一个地调用方法并不冲突。
结果就是无论如何js引擎都会先执行$('p').parents('body').find('h2').toggle(500)切换h2的显示状态为隐藏,再根据用户是否触发鼠标事件来计算结果。

题目5: jQuery 中 data 函数的作用?

  • #####jquery data()的作用
    data() 方法向被选元素附加数据,或者从被选元素获取数据。
    通过data()函数存取的数据都是临时数据,一旦页面刷新,之前存放的数据都将不复存在。
    该函数属于jQuery对象(实例)。如果需要移除通过data()函数存放的数据,请使用 removeData() 函数。

  • #####jquery data的使用方式
    1、获取附加的data的值
    $(selector).data(name)
    参数说明
    name:可选。规定要取回的数据的名称。
    如果没有规定名称,则该方法将以对象的形式从元素中返回所有存储的数据。

2、用name和value为对象附加数据
$(selector).data(name,value)
参数说明
selector:为需要附加或者获取数据的对象。
name:参数为数据的名称。
value:参数为数据的值。

3、使用对象向元素附加数据
使用带有名称/值对的对象向被选元素添加数据。
除了以提供 name 和 value 的方式进行赋值,我们还可以直接传入另一个对象( “another” )作为参数。这种情况下,“another” 的属性名称和属性值将被视为多个键值对,从中提取的 “name” 和 “value” 都会被复制到目标对象的缓存中。
$(selector).data(object)
参数说明
object:必需。规定包含名称/值对的对象。

示例:

1
2
3
4
5
6
7
$('body').data('name', 'haha')
$('body').data('hobby', { fav: 'music', love: 'chicken' })
$('body').data({ arr: [1, 2, 3, 4, 5] })

console.log($('body').data('name'))//haha
console.log($('body').data())
//{ name: "haha",hooby: { fav: "music", love: "chicken" },arr: [1,2,3,4,5] }

打印结果:
image.png

题目6:写出以下功能对应的 jQuery 方法:

  • 给元素 $node 添加 class active,给元素 $noed 删除 class active

    1
    2
    $node.addClass('active')
    $node.removeClass('active')
  • 展示元素$node, 隐藏元素$node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //方法1:
    $node.show()
    $node.hide()
    //方法2:
    $node.css('display','block')
    $node.css('display','none')
    //方法3:
    //给node设置css属性{display: none;},默认隐藏; 增加active属性 node.active{display: block;}显示
    $node.addClass('active'); //显示
    $node.removeClass('active'); //隐藏
  • 获取元素$node 的 属性: id、src、title, 修改以上属性

    1
    2
    3
    4
    5
    6
    7
    8
    //获取属性
    $node.attr('id')
    $node.attr('src')
    $node.attr('title')
    //修改属性
    $node.attr('id','newId')
    $node.attr('src','newSrc')
    $node.attr('title','newTitle')
  • 给$node 添加自定义属性data-src

    1
    $node.prop('data-src')
  • 在$ct 内部最开头添加元素$node

    1
    2
    3
    $ct.prepend($node)
    //或
    $node.prependTo($ct)
  • 在$ct 内部最末尾添加元素$node

    1
    2
    3
    $ct.append($node)
    //或者
    $node.appenTo($ct)
  • 删除$node

    1
    2
    $node.remove()
    $ct.detach($node)
  • 把$ct里内容清空

    1
    2
    $ct.empty()
    $ct.text('')
  • 在$ct 里设置 html<div class="btn"></div>

    1
    $ct.html('<div class="btn"></div>')
  • 获取、设置$node 的宽度、高度(分别不包括内边距、包括内边距、包括边框、包括外边距)

获取宽高:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//不包括内边距
$node.width()
$node.height()
$node.css('width')
$node.css('height')

//包括内边距
$node.innerWight()
$node.innerHeight()

//包括内边距,包括边框
$node.outerWidth() //不传参数或参数为false
$node.outerHeight() //不传参数或参数为false

//包括内边距,边框,外边距
$node.outerWidth(true)
$node.outerHeight(true)

设置宽高:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//不包括内边距
$node.width(100) //如果没有规定长度单位,则使用默认的 px 单位
$node.height(100)
$node.css({width:'200px',height:'300px'})//设置元素的宽度和高度,也可以不要引号和单位

//包括内边距
$node.innerWidth(30)
$node.innerHeight(30)

//包括内边距,包括边框
$node.outerWidth(60)
$node.outerHeight(30)

//包括内边距,包括边框,包括外边距
$node.outerWidth(70,true)
$node.outerHeight(70,true)

  • 获取窗口滚动条垂直滚动距离

    1
    $(window).scrollTop()
  • 获取$node 到根节点水平、垂直偏移距离

    1
    2
    $node.offset().left
    $node.offset().top
  • 修改$node 的样式,字体颜色设置红色,字体大小设置14px

    1
    2
    3
    4
    $node.css({
    'color': 'red',
    'font-size': '14px'
    })
  • 遍历节点,把每个节点里面的文本内容重复一遍

    1
    2
    3
    $node.each(function(){
    $(this).text($(this).text() + $(this).text())
    })
  • 从$ct 里查找 class 为 .item的子元素

    1
    2
    $ct.find('.item')
    $ct.children('.item')
  • 获取$ct 里面的所有孩子

    1
    $ct.children()
  • 对于$node,向上找到 class 为’.ct’的父亲,再从该父亲找到’.panel’的孩子

    1
    $node.parents('.ct').find('.panel')
  • 获取选择元素的数量

    1
    $node.length
  • 获取当前元素在兄弟中的排行

    1
    node.index()

题目7:

  • 用jQuery实现以下操作
    • 当点击$btn 时,让 $btn 的背景色变为红色再变为蓝色
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <body>
      <button class="btn">按钮</button>
      <script>
      var $btn = $('.btn')
      $btn.on('click',function(){
      $btn.css({
      'background': 'red'
      })
      setTimeout(function(){
      $btn.css({'background': 'blue'})
      },500)
      })
      </script>
      </body>

效果预览:http://js.jirengu.com/maqihelosa/1/edit

  • 当窗口滚动时,获取垂直滚动距离
    1
    2
    3
    4
    5
    6
    <script>
    $('.content').on('scroll',function(){
    var num = $('.content').scrollTop()
    $('span').text(num)
    })
    </script>

效果预览:http://js.jirengu.com/bajivefije/1/edit

  • 当鼠标放置到$div 上,把$div 背景色改为红色,移出鼠标背景色变为白色
    1
    2
    3
    4
    5
    6
    7
    8
    <script>
    var $box = $('.box')
    $box.on('mouseenter',function(){
    $(this).css('background','red')
    }).on('mouseleave',function(){
    $(this).css('background','white')
    })
    </script>

效果预览:http://js.jirengu.com/tayoxeyeye/1/edit

  • 当鼠标激活 input 输入框时让输入框边框变为蓝色,当输入框内容改变时把输入框里的文字小写变为大写,当输入框失去焦点时去掉边框蓝色,控制台展示输入框里的文字
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <script>
    var $input = $('.ipt')
    $input.focus(function(){
    $(this).css('border-color','blue')
    .on('keyup',function(){
    $(this).val($(this).val().toUpperCase())
    })
    })
    $input.blur(function(){
    $(this).css('border-color','black')
    console.log($(this).val())
    })
    </script>

效果预览:http://js.jirengu.com/likesomeca/1/edit

  • 当选择 select 后,获取用户选择的内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //html
    <select>
    <option value="1">item 1</option>
    <option value="2">item 2</option>
    <option value="3">item 3</option>
    <option value="4">item 4</option>
    <option value="5">item 5</option>
    </select>
    <p>用户选取的内容是:<span>item</span></p>

    //js
    $('select').on('change', function () {
    $('span').text($('select>option:selected').text())
    })

效果预览:http://js.jirengu.com/budugazave/1/edit

题目8: 用 jQuery ajax 实现如下效果。当点击加载更多会加载数据展示到页面效果预览

github代码

本地mock成功.gif