jQuery.fn.attr与jQuery.fn.prop

jQuery.fn.attr、jQuery.fn.prop的区别

假设页面有下面这么个标签,$('#ddd').attr('nick')、$('#ddd').prop('nick')分别会取得什么值?

<div id="test" nick="casper" class="dddd"></div>

没什么关子好卖,答案如下:

$('#test').attr('nick');  // "casper"
$('#test').prop('nick'); // undefined

再看看下面这几行代码:

$('#test')[0].nick = 'chyingp';
$('#test').attr('age'); // "casper"
$('#test').prop('nick'); // "chyingp"

看到这里应该知道这两个方法的区别了。其实从方法名也可以大致猜出来,.attr()、.prop()分别取的是节点的attribute值、property值。

至于attribute、property的区别,还真不知道怎么解释,有分别翻译成“特性”、“属性”的,这两个词看完后还是有头雾水。我就干脆直接理解成:

attribute: 直接写在标签上的属性,可以通过setAttribute、getAttribute进行设置、读取

property: 通过“.”号来进行设置、读取的属性,就跟Javascript里普通对象属性的读取差不多。

怎么方便怎么记吧。为方便区分,下文统一用特性来代指attribute,用属性来表示property。

费解的attribute和property——隐形创建的property

attribute、property令人费解的地方在于:

1、一些常用attribute,比如id、class、value等,在设置attribute值的时候(直接写标签里,或通过setAttribute方法),会创建对应的property,部分情况下是同名的,比如id

document.getElementsByTagName('div')[0].id;  // "casper"
document.getElementsByTagName('div')[0].getAttribute('id');  // "casper"

2、如1提到的,对某个attribute,创建了对应的property,但却用了不同的名称,比如class,对应的property为className

document.getElementsByTagName('div')[0].className;  // "dddd"
document.getElementsByTagName('div')[0]['class']; // undefined

所以导致下面代码的诡异之处:

$('test').attr('class', 'dddd');  //有效
$('test').attr('className', 'dddd'); //无效 $('test').prop('class', 'dddd'); //无效
$('test').prop('className', 'dddd'); //有效

费解的attribute和property——以checkbox为例

假设页面有这么个复选框,假设它的初始状态为选中

<input type="checkbox" id="box" checked="checked" />

不知道有多少人曾经想我一样,被下面的代码弄得有些抓狂:false、null、"" 轮番上阵,复选框依旧保持“选中”状态

$('#box')[0].setAttribute('checked', false);
$('#box')[0].getAttribute('checked', false); // 'false'

再试试下面这行代码估计更要抓狂了,T-T

$('#box')[0].checked;  // true

好吧,如checkbox的checked属性,它的值为Boolean类型,特点是:

1)只要特性checked在标签里出现了,不管值是什么,复选框就会被选中。此时属性checked为true,否则为false;

2)后续修改特性checked的值,不会导致checkbox的选中状态改变;

3)后续修改属性checked的值,会导致checkbox的选中状态改变;

简单demo如下:

<input type="checkbox" id="box" checked="checked" />

<script>
document.getElementById('box').setAttribute('checked', false);
document.getElementById('box').getAttribute('checked'); // "false"
document.getElementById('box').checked; // true document.getElementById('box').checked = false; // 复选框选中态消失 </script>

也可以参考jQuery官网的demo:http://api.jquery.com/attr/

.attr()、.prop()源码

.attr()内部是通过jQuery.attr()实现的,.prop()实现类似,所以这里只简单讲一下jQuery.attr()的实现,如下:

其中,大部分的特性值可通过getAttribute、setAttribute进行获取/设置,部分特殊的,比如href、src、checked等,需要调用相应的hook(钩子,很奇怪的名字)的get、set方法几i女性获取/设置值。

可以参照 http://api.jquery.com/attr/ 对.attr() 这个API的讲解,并结合断点调试来理解下面的源码。体力活,不赘述~~

    attr: function( elem, name, value ) {
// 这里一坨代码可以先直接忽视,不影响下面主要逻辑,...代表被忽略的代码
// ... // All attributes are lowercase
// Grab necessary hook if one is defined
if ( notxml ) {
name = name.toLowerCase();
// 这里几种情况:
// 1、一些特殊的特性,如href、width等=>attrHooks
// 2、一些值为Boolean的属性,如checked等=>boolHook
// 3、其他:nodeHook,主要是针对IE6/7的bug
hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
} if ( value !== undefined ) { //设置节点特性,包括:
//$(node).attr('nick','casper')
//或 $(node).attr({'nick':'casper', 'age':100})
//或 $(node).attr('nick', null) if ( value === null ) { // 删除
jQuery.removeAttr( elem, name ); } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret; // 一些特殊的特性,比如href、src等,有专门的set方法 } else { // 普通的setAttribute
elem.setAttribute( name, value + "" );
return value;
} } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
// 获取特性值,且该特性有对应的hook~
return ret; } else { // 普通的获取特性值 // In IE9+, Flash objects don't have .getAttribute (#12945)
// Support: IE9+
if ( typeof elem.getAttribute !== core_strundefined ) {
ret = elem.getAttribute( name );
} // Non-existent attributes return null, we normalize to undefined
return ret == null ?
undefined :
ret;
}
}

参考连接:

http://stylechen.com/attribute-property.html

http://api.jquery.com/attr/

 
分类: 经验总结
标签: attrpropjquery源码

【position也可以很复杂】当弹出层遇上了鼠标定位(上)

前言

周五时同事有一个关于弹出层的问题没有解决,但是面临下班问题,我有点不舒服,便叫回去周六过来解决,但是上周六病了,所以请了个假,于是故事发生啦。。。。

今天上班时候,组员们卡到了那个地方,然后结果就是前端组拖慢了进度,额。。。。这是事实。

于是早会结束,我便投入处理这个问题,因为这个项目原来是外包出去的,后面点要重构,现在只是优化工作,我便一直不太关注,有两个同事主要负责。

但是今天一看到代码我就哭了。。。那家伙,这个还不单单是弹出层的问题呢,里面很有点东西!好了我们进入正题,来一起看看这个问题吧。

请用现代浏览器测试

引出问题

有图有真相,我们来看一个智联招聘里面经常出现的图层:

他这个是没有什么问题的,我们来简单看看其实现:

 
 1 <div id="zbwJobSearch">
2 <div style="width: 710px;" class="sPopupDiv">
3 <div class="sPopupTitle213 sPopupTitle">
4 <h1>
5 选择职位</h1>
6 <div class="sButtonBlock">
7 <a onclick="return zbw.PopupDiv.allIns['buttonSelJobType'].fnClickAll()" href="#"
8 class="blueButton">不限</a> <a onclick="return zbw.PopupDiv.allIns['buttonSelJobType'].fnClickClose()"
9 href="#" class="blueButton">关闭</a></div>
10 <div class="clear">
11 </div>
12 </div>
13 <div class="clear">
14 </div>
15 <div class="sPopupBlock">
16 </div>
17 </div>
18 </div>

他一开始便有一个容器在页面上,看着我们这个“zbwJobSearch”的容器,他是一个一般流的东西,里面放了3个绝对定位的东西,从这里看出,他这个不只是用于职位选择还有城市选择什么的。。。。

然后我们把多余的东西给去掉,点击了一下我本来以为会发送http请求什么的,重新获取数据,再生成我们看到的那颗树,但是解压js后发现这个东西好像被写到了js中,基本就是生成了这个东西:

 生成的职位列表

他是一个表格,里面有很多事件!!!

我们这个td里面有一个span元素,给span了一个click事件,点击后会弹出我们要的结果:

然后进行最后的操作。

分析问题

好了,到了这里我们不知道我把问题解释清楚没有:

1 点击外部按钮便弹出了我们要的第一个弹出层。

2 点击其中的“加号”或者文字便弹出具有多选框的可选项

3 选择项目点击确定。

以上几个做完,我们的流程便结束了。

优化方案

不知从什么时间开始,我有了一点代码洁癖,看着这个代码我怎么就感觉有点不爽,他这个东西主要有以下问题:

1 table渲染速度慢

2 td/span有太多的事件,过多的事件绑定对我们的性能也有影响。

3 他的click函数全部写到了标签上(仁者见仁,我是非常不喜欢这样做)

其它

我们来看看,他其它地方其实做了一定处理:

<span onclick="zbw.PopupDiv.allIns['buttonSelJobType'].fnPopupChildren(this,['348','物流/仓储'])" class="availItem">物流/仓储</span>

为了防止命名冲突,我们看看这家伙定义的命名空间可长可长了。长到我都不想看了。。。。

好了暂时其它问题我这里还没发现,只不过我认为其中几个图片按钮相关可以用标签实现啦。。。

既然说都说了这么多,那我们不如先来写一个呗,写了再继续我们的问题吧!

实现职位选择功能

我们现在一起来实现这个职位选择功能,所以我们先分析下我们需要干些什么:

① 点击text在text处出现弹出层

② 弹出层出来后,我们点击其中的“加号”或者文字便弹出第三个弹出层

③ 选择第三个弹出层里面的checkbox项目最后点击确定后便将选择插入text(多项以分号分割)

若是想要优化的话,也许可以尝试点击后再加载数据再生成dom,一旦生成后便将dom缓存起来,我们这里作为demo就不搞那么多事情了。

第一步,准备工作

下拉选择文本

实现功能前,我们先准备一点点小东西,第一个就是长得像下拉菜单的文本框:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head>
3 <title></title>
4 <style type="text/css">
5 .dropText { display: inline-block; border: 1px solid #B6B6B6; border-right: none; border-radius: 5px 0 0 5px;
cursor: pointer; margin-right: 20px; }
6 .dropText input { border: none; border-radius: 5px 0 0 5px; cursor: pointer; padding-left: 5px; }
7 .dropText span { display: inline-block; margin-right: -10px; width: 20px; border: 1px solid #B6B6B6;
border-radius: 0 5px 5px 0; margin: -1px -20px -1px 0; text-align: center; padding: 4px 0 4px 8px; }
8 .dropText i { display: inline-block; border: 6px solid black; border-color: black transparent transparent;
border-bottom: none; vertical-align: 3px; }
9 </style>
10 <script src="../../scripts/jquery-1.7.1.js" type="text/javascript"></script>
11 <script type="text/javascript">
12 $(document).ready(function () {
13 });
14 </script>
15 </head>
16 <body>
17 <div style="margin: 100px auto; padding-left: 100px;">
18 <div class="dropText" id="dropText">
19 <input type="text" placeholder="请选择职位" /><span><i></i>&nbsp;</span>
20 </div>
21 <span>dddd</span>
22 </div>
23 </body>
24 </html>

我们来看看我们形成的这个框,这个在现代浏览器还能看,而且各位千万不要小看这个东西,这个东西真不像各位想象那么简单,比如我这个代码就有很大的优化空间!

PS:各位看到我的span里面多了一个&nbsp;我为什么会这么做?不这么做有什么影响?i被设置为inline-block对整体行对齐有什么影响,这块代码还可以如何优化?这个问题暂时留给各位了,我们下来再一起解决,这个对行内元素的理解有莫大的帮助,请各位动手吧。

十字开关

 1 <style type="text/css">
2 /*十字开关*/
3 .croSwitch { display: inline-block; border: 1px solid #108efe; border-radius: 4px; width: 16px;
height: 16px; text-align: center; position: relative; cursor: pointer; }
4 .croSwitch i { background-color: #108efe; border-radius: 6px; position: absolute; }
5
6 .croSwitch .horizontal { width: 12px; height: 2px; left: 2px; top: 7px; }
7 .croSwitch .vertical { height: 12px; width: 2px; top: 2px; left: 7px; }
8 .cls .vertical { display: none; }
9 </style>
10
11 <span class="croSwitch"><i class="horizontal"></i><i class="vertical"></i></span>
12 <span class="croSwitch cls"><i class="horizontal"></i><i class="vertical"></i></span>

虽然很丑但是很温柔。。。

Ps:请思考若是外层span不设置高度会有什么后果

好啦,小东西大概懂弄好了,我们现在来组织职位的dom结构吧。

职位列表样式

我们首先根据上面的表格,使用jquery操作他生成如下结构:

 最新的结构

好了,我们现在来调整一下样式。

由于这个家伙着实太丑了,我放弃了,我这里上传个图片好了。。。。

可运行代码:

 基本列表样式

PS:第三个坑,不知道各位发现没,就算使用背景图片,我们的小图片看上去感觉还是有一些问题呢,我们是不是应该看看呢?

好了,我们将我们第一阶段的代码连起来:

 带交互代码

结语

那撒。。。小叶确实熬不住了,明天再接着写吧,若您觉得这次这个有点意思请持续关注,届时我们在解释其中的问题。

 
 
分类: Web前端

jQuery.fn.attr与jQuery.fn.prop的更多相关文章

  1. jQuery源码-jQuery.fn.attr与jQuery.fn.prop

    jQuery.fn.attr.jQuery.fn.prop的区别 假设页面有下面这么个标签,$('#ddd').attr('nick').$('#ddd').prop('nick')分别会取得什么值? ...

  2. jquery中attr()与prop()函数用法实例详解(附用法区别)

    本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是a ...

  3. jQuery 中 attr() 和 prop() 方法的区别

    前几天,有人给 Multiple Select 插件 提了问题: setSelects doesn't work in Firefox when using jquery 1.9.0 一直都在用 jQ ...

  4. 对jquery的 attr()和prop()理解

    jquery1.6版本后引入了prop()方法,很多时候总是混淆attr()与prop()这俩,下面分析一下这俩的区别 在此之前,先来了解一下html 的attribute和property,因为jq ...

  5. jQuery 中 attr() 和 prop() 方法的区别<转>

    前几天,有人给 Multiple Select 插件 提了问题: setSelects doesn't work in Firefox when using jquery 1.9.0 一直都在用 jQ ...

  6. jQuery中attr和prop方法的区别

    jQuery中attr和prop方法的区别。 http://my.oschina.net/bosscheng/blog/125833 http://www.javascript100.com/?p=8 ...

  7. jQuery原生框架中的jQuery.fn.extend和jQuery.extend

    extend 方法在 jQuery 中是一个很重要的方法,jQuey 内部用它来扩展静态方法或实例方法,而且我们开发 jQuery 插件开发的时候也会用到它.但是在内部,是存在 jQuery.fn.e ...

  8. jQuery.fn.extend() 与 jQuery.extend()

    jQuery.fn如何扩展. jQuery插件 $.fn(object)与$.extend(object) jQuery提供了两个方法帮助开发插件 $.extend(object);扩展jQuery类 ...

  9. [转载]jquery中attr和prop的区别

    在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答案很多.这里谈谈我的心得,我的心得很简单: ...

随机推荐

  1. Utility Classes Are Evil

    原文地址:http://alphawang.com/blog/2014/09/utility-classes-are-evil/ This post is a summary of this arti ...

  2. jquery_mobile.js+html5+css3打造手机平板等各种效果

    http://www.w3school.com.cn/jquerymobile/jquerymobile_events_orientation.asp

  3. MVC验证06-自定义错误信息

    原文:MVC验证06-自定义错误信息 本文体验自定义错误信息.   系统默认的错误信息 在"MVC验证02-自定义验证规则.邮件验证"中,我们自定义了一个验证Email的类.如果输 ...

  4. jQuery.extend()源码解读

    // extend方法为jQuery对象和init对象的prototype扩展方法// 同时具有独立的扩展普通对象的功能jQuery.extend = jQuery.fn.extend = funct ...

  5. 转载JQuery绑定鼠标粘贴事件工具类

    // 粘贴事件监控 $.fn.pasteEvents = function( delay ) { if (delay == undefined) delay = 10; return $(this). ...

  6. jquery自己主动旋转的登录界面的背景代码登录页背景图

    在其他网站上看到比较爽Web登录界面.背景图片可以自己主动旋转. 介绍给大家.有兴趣的可以改改下来作为自己的系统登录界面. 如图: watermark/2/text/aHR0cDovL2Jsb2cuY ...

  7. 编程算法 - 二部图确定 代码(C)

    二部图确定 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定一个具有n个顶点的图. 要给图上每一个顶点染色, 而且要使相邻的顶点颜色不同.  ...

  8. 2.3 LINQ查询表达式中 使用select子句 指定目标数据

    本篇讲解LINQ查询的三种形式: 查询对象 自定义查询对象某个属性 查询匿名类型结果 [1.查询结果返回集合元素] 在LINQ查询中,select子句和from子句都是必备子句.LINQ查询表达式必须 ...

  9. jquery 超简单的点赞效果

    1.HTML(可以优化一下,尽量少些几个标签.....) <div id="dianz"> <b class="cz"><em&g ...

  10. JSFIDDLE 动力 Threejs 功能探秘

    JSFIDDLE 助力 WebGL 功能探秘 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协 ...