Write By Monkeyfly
以下内容均为原创,如需转载请注明出处。
前提
昨天要实现一个功能:点击空白关闭弹窗。当时也不知道该怎么实现,于是就百度到了方法:关于点击空白关闭弹窗的js写法推荐?【可点击查看】
下面是被采纳的方法,代码实现如下:
$(document).click(function(e){
var _con = $(' 目标区域 '); // 设置目标区域
if(!_con.is(e.target) && _con.has(e.target).length === 0){// Mark 1
some code... // 功能代码
}
});
/* Mark 1 的原理:
判断点击事件发生在区域外的条件是:
1. 点击事件的对象不是目标区域本身
2. 事件对象同时也不是目标区域的子元素
*/
说明:
- 该实现主要用到了2个
jQuery
的方法:is()
方法和has()
方法。 - 要看明白该方法的实现原理,必须知道这两个方法的用法。
is()
方法 —— 用于筛选
语法:
jQueryObject.is( expr )
返回值:
is()
函数的返回值为Boolean
类型。true
或者false
。- 只要其中至少有一个元素符合给定的表达式就返回
true
,否则就返回false
。
说明:
is()
方法用于判断与当前jQuery
对象相匹配的元素是否符合指定的表达式。- 这里的表达式包括:选择器(字符串)、
DOM
元素(Element)
、jQuery
对象、函数。 - 可以看出来,它是根据选择器、
DOM
元素或jQuery
对象来检测匹配元素集合。
has()
方法 —— 用于筛选
语法:
jQueryObject.has( expr )
返回值:
返回值为jQuery类型
返回一个新的jQuery对象
该对象中封装了所有符合筛选条件的,并且与当前指定的jQuery对象相匹配的元素。
说明:
has()
函数用于筛选出包含特定后代的元素,返回的是特定的jQuery
对象。- 特定的后代元素:指该元素至少有一个后代元素能满足指定的表达式。
- 这里的表达式包括:选择器(字符串)、
DOM
元素(Element)
、jQuery
对象。 其实,该函数是根据后代元素来筛选的父级元素的。
如果与当前的jQuery
对象相匹配的每一个元素,它们的后代元素只要有一个元素符合指定的表达式,那么该元素就满足筛选条件。
注:该方法并不是获取后代元素,而是返回一个指定的jQuery对象
。(其中包含了所有满足条件的元素)
练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>.has方法(一个选择器字符串|一个DOM元素)</title>
<script src="../jquery-3.2.1.min.js"></script>
<script>
$(document).ready(function() {
var oLi = $('li').has('ul');
oLi.css('background-color', '#f40');
console.log(oLi);//会返回符合条件的所有li元素,匹配到的元素是一个集合
console.log(oLi[0]);//返回符合条件的第1个li元素
console.log(oLi[1]);//返回符合条件的第2个li元素
console.log(oLi.length);//2;即返回符合条件的元素个数
$(document).on('click', function(event) {
var obj = $(".list2");
//判断当前点击的元素是否为class="list2"的li元素,是则执行下面的代码
if( obj.is(event.target)){//如果此时点击的是它的子元素或者其他元素,则is()方法返回false
$(".list2").attr("click","self");
}
//问: 如何判断当前点击的元素是不是目标元素的子元素呢?
//答:根据event.target来筛选符合条件的obj,length属性为0肯定说明event.target不符合筛选条件。
//判断当前点击的元素是否为class="list2"的li元素的子元素,是则执行下面的代码
if( obj.has(event.target).length !== 0 ){
$(".list2").attr("click","child");
}
//注:下面两种写法等价,一个是js对象,一个是jQuery对象
/*
*(1)$(".list2")是jQuery对象的写法。
*(2)$(".list2")[0]是将jQuery对象转换为了JavaScript对象。
*/
// if ( event.target != $(".list2")[0] && $(".list2").has(event.target).length === 0)
//obj.has(event.target).length === 0)说明:根据当前点击的元素并没有筛选出任何一个符合条件的父元素。
//换句话说就是,当前点击的对象并不在目标元素obj的范围之内,即点击的是其他DOM元素。
if ( !obj.is(event.target) && obj.has(event.target).length === 0) {
console.log(event.target);
$(".list2").attr('click',"other");
}
switch($(".list2").attr("click")){
case "self":
alert("当前点击的是list item 2元素");
break;
case "child":
alert("当前点击的是list item 2的子元素");
break;
case "other":
alert("当前点击的是其他元素");
}
});
});
</script>
</head>
<body>
<h3>$('ele').has(一个选择器字符串|一个DOM元素)</h3>
<h3>$('ele').has()方法将会从给定的jQuery对象中重新创建一组匹配的对象。</h3>
<h3>提供的选择器会一一测试原先那些对象的后代,含有匹配后代的对象将得以保留。</h3>
<h3>如果找不到指定jQuery对象内所包含的需要匹配的元素,则$('li').has('ul').length === 0</h3>
<ul>
<li class="list1">list item 1</li>
<li class="list2">list item 2
<ul>
<li>list item 2-a</li>
<li>list item 2-b</li>
</ul>
<p>1234546</p>
</li>
<li class="list3">list item 3
<ul>
<li>list item 3-a</li>
<li>list item 3-b</li>
</ul>
</li>
<li class="list4">list item 4</li>
</ul>
</body>
</html>