进阶15: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可以同时编写多个,并且都可以得到执行。
如下例:

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(){});
在一些开发中,大多数时候,第一行写的是:

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

关于$(window).load:

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

$(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方法呢?下面是其中之一的做法:

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函数的正确性:

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为参数值
      如例:
<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>

下面代码打印结果:

 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'))

题目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 ] )

如例:

<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>

打印结果:

console.log($.extend(object1, object2))
//浅复制,将object2合并到object1中,tom对象属性完全被object2中的tom属性取代
console.log(object1)//object1为返回合并后的最终结果
 console.log(object2)//object2值不变
console.log($.extend(true, object1, object2))
//深复制,将object2合并到object1中


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

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

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

<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:必需。规定包含名称/值对的对象。

示例:

$('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
$node.addClass('active')
$node.removeClass('active')
  • 展示元素$node, 隐藏元素$node
//方法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, 修改以上属性
//获取属性
$node.attr('id')
$node.attr('src')
$node.attr('title')
//修改属性
$node.attr('id','newId')
$node.attr('src','newSrc')
$node.attr('title','newTitle')
  • 给$node 添加自定义属性data-src
$node.prop('data-src')
  • 在$ct 内部最开头添加元素$node
$ct.prepend($node)
//或
$node.prependTo($ct)
  • 在$ct 内部最末尾添加元素$node
$ct.append($node)
//或者
$node.appenTo($ct)
  • 删除$node
$node.remove()
$ct.detach($node)
  • 把$ct里内容清空
$ct.empty()
$ct.text('')
  • 在$ct 里设置 html<div class="btn"></div>
$ct.html('<div class="btn"></div>')
  • 获取、设置$node 的宽度、高度(分别不包括内边距、包括内边距、包括边框、包括外边距)

获取宽高:

//不包括内边距
$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)

设置宽高:

//不包括内边距
$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)
  • 获取窗口滚动条垂直滚动距离
$(window).scrollTop()
  • 获取$node 到根节点水平、垂直偏移距离
$node.offset().left
$node.offset().top
  • 修改$node 的样式,字体颜色设置红色,字体大小设置14px
$node.css({
  'color': 'red',
  'font-size': '14px' 
})
  • 遍历节点,把每个节点里面的文本内容重复一遍
$node.each(function(){
  $(this).text($(this).text() + $(this).text())
})
  • 从$ct 里查找 class 为 .item的子元素
$ct.find('.item')
$ct.children('.item')
  • 获取$ct 里面的所有孩子
$ct.children()
  • 对于$node,向上找到 class 为'.ct'的父亲,再从该父亲找到'.panel'的孩子
$node.parents('.ct').find('.panel')
  • 获取选择元素的数量
$node.length
  • 获取当前元素在兄弟中的排行
node.index()

题目7:

  • 用jQuery实现以下操作
    • 当点击$btn 时,让 $btn 的背景色变为红色再变为蓝色
<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

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

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

  • 当鼠标放置到$div 上,把$div 背景色改为红色,移出鼠标背景色变为白色
<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 输入框时让输入框边框变为蓝色,当输入框内容改变时把输入框里的文字小写变为大写,当输入框失去焦点时去掉边框蓝色,控制台展示输入框里的文字
<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 后,获取用户选择的内容
//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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342