HTML中拖放介绍

HTML中拖放介绍

1.在jQuery UI里面会经常使用Draggable和Droppable,实现Web开发中拖放效果,当然这不是原生条的拖放,所以在处理复杂的拖放上还是需要自己动手写很多代码,最近开发中就遇到这个问题。拖放的广泛用途:文件管理、数据传输、图标绘制和其他许多操作。个人觉得在列表文件,比如树形菜单上用的比较多。但是这里的拖放和iphone上的触摸(touch)滑动还不完全一样,这里的拖放可能是用鼠标操作,但是触摸滑动主要是通过手指之类的。没有具体开发过mobile web应用,不知道jQuery UI的draggable和droppable是否支持手机上的触摸操作。

Web拖放发展历史

第一阶段:

因为HTML和DOM可以处理底层的鼠标事件,所以早起的开发人员可以借助Javascript和CSS,DOM事件基础,可以近似实现一个简单的拖放功能。需要在Web页面拖放元素,需要使用到下面的方法,大多数是和鼠标有关的事件

事件 说明 备注
mousedown 用户按下鼠标开始操作 需要判定是拖放还是单击?
mousemove 如果鼠标没有松开,则是移动操作 需要判定拖动还是选择?
mouseover 鼠标移动到了每个元素上 放置在哪个元素上面
mouseout 鼠标移除了某个元素,此元素不再是

可放置的元素 需要为用户给出提示吗?

mouseup 释放鼠标按键,可能会触发放置操作 基于鼠标起始位置,是否放置在此位置

弊端:

1.需要考虑边界,而已需要提示哪里位置可以放置元素

2.不能将自己的页面的元素与其他页面,或者窗口、浏览器中其他内容合并或者交互

3.无法与用户的桌面交互,也无法跨浏览器窗口

第二阶段:

大家觉得用DOM和Javascript事件处理拖放操作很复杂,所以就有很多公司使用Flash去完成这个任务。所以可以看到很多拖放文件上传工具使用了flash去上传,业务逻辑上又复杂的拖放操作也都交给了flash去完成。毕竟flash在动画交互方面还是很有优势的。

第三阶段:

HTML5发布之后,技术越来越成熟。而已标准中提供了拖放的API,所以越来越多的公司关注HTML5中拖放操作。看一个Skydrive上传文件的示例和Dropbox上传文件的示例。

Skydrive没有给出具体的提示,表示用户拖放文件到页面就可以上传,但是我们可以用这个方法上传文件。Dropbox提示了用户,可以拖放文件到页面然后上传上去。截图如下:

clip_image001

因为没有具体查看代码,不知道这2家公司是否也是使用了HTML5的Drag API,同时没有去测试对较老的浏览器的支持,所以不知道他们是使用的哪种技术。

参考网址:

http://jqueryui.com

http://www.prohtml5.com

jQuery核心源码结构

2013-05-30 22:55 by 程序猿小卡, 494 阅读, 0 评论, 收藏编辑

从github直接拷贝过来,排版不是很友好,可点击这里查看github上的文章

前端的童鞋对jQuery绝对不会陌生,有不少刚入门的筒子,在不知JS为何物的时候,就已经在用jQuery了。这也应该归功于前端恶劣的生存环境:各自为政的浏览器厂商,依旧严峻的兼容性问题,并不好用的原生API。。。

使用jQuery的理由有很多,喜欢它的理由也很多,优雅的接口,丰富的插件,完善的文档等。作为一名有进取心的前端攻城狮,大家心理或多或少都有一个框架梦,总用它人写的库,内心总归有些那么不是滋味。

那好吧,干脆自己写一个,“师夷长技以自强”嘛,于是热火朝天地开工,一个又一个小JQ就这样横空出世。再精心挑选上好的测试用例证明自己的库比其他库更牛逼,当然,jQuery基本都在对比之列。

此处省略三千字。。下面开始进入jQuery源码分析之路

jQuery是什么

好吧,这里的jQuery指的并不是“jQuery库”,而是jQuery这个对象。首先用你习惯使用的编辑器打开jQuery-1.9.1.js,最好能够支持代码高亮和智能折叠。好家伙,源码加注释共9500++行,怪吓人的。没错,这是每个有志学习jQuery源码的童鞋需要过的第一道坎。其实,完全没有必要害怕,将多余的噪音去掉,其实jQuery就是下面几行代码而已:

(function( window, undefined ) {
    var jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    };
    window.jQuery = window.$ = jQuery;
})( window );

我们更为常用的美元符号$,其实就是jQuery的同名对象,而jQuery是个方法,它的作用是返回一个jQuery对象,更确切地来说,是jQuery.fn.init对象。至于为什么会返回jQuery.fn.init对象,可以小小参考下之前写的另一篇文章【jquery学习笔记】美元背后的一点小技巧

从一行代码说jQuery的核心源码结构

有下面这么一行代码

$('#casper').addClass('handsome‘),

这行代码的作用不用多说:给ID为casper的dom节点添加一个名为handsome的class。很简单的一句代码,拆成两部分来看:

  • $('#casper') 返回一个jQuery对象,该对象的属性’0‘包含了选中的dom节点=> $('#casper')[0] === document.getElementById('casper')
  • .addClass('handsome') 给选中的dom节点添加handsome类,addClass为jQuery的prototype方法

于是我们把之前的那个简陋的骨架再丰满下,整个jQuery的骨架就基本出来了,里面的代码关键点在**源码骨架**后面会逐个进行讲解

源码骨架

(function( window, undefined ) {
var
    jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    };

    //各种原型属性
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function( selector, context, rootjQuery ) {
            //...
        },
        ...
    };
    jQuery.fn.init.prototype = jQuery.fn;

    //extend方法,用来扩展jQuery,或jQuery.fn
    jQuery.extend = jQuery.fn.extend = function() {
        //...
    };

    jQuery.fn.extend({
        addClass: function( value ) {
            //...
            return this;    //返回this,链式调用的秘密
        }
    });

    window.jQuery = window.$ = jQuery;

})( window );

return new jQuery.fn.init( selector, context, rootjQuery );

$('#casper')跟new $('#casper')是一样的。个人觉得这里设计的原因,一个减少写一堆new的麻烦,同时也可以避免开发者不小心遗漏了new导致的诡异bug。当然,不好的地方是,代码有点绕,这也算是jQuery源码的其中一个特点。

jQuery.fn = jQuery.prototype

没什么好讲,jQuery.prototype为jQuery的原型方法,这里用jQuery.fn来代替jQuery.prototype,只是为了少写几个字符,平常写插件时就是在这东东上面做修改

jQuery.fn.init.prototype = jQuery.fn

很好很绕的一个语句,上面说了$(’#casper‘)返回的其实是个jQuery.fn.init对象。所以,这里的作用,是让jQuery.fn上的方法都成为jQuery.fn.init对象的原型方法。 这个语句应该让很多刚接触jQuery源码的人感到困惑,包括我(=_=),可以试jQuery.fn.init.prototype.init.prototype.init...,如果你愿意可以一直写下去。

addClass: function( value ) {...

下面这段代码很短很关键,别看它很简单,jQuery众多强大的接口就是这样通过jQuery.fn.extend一个一个扩展出来的,不赘述

    jQuery.fn.extend({
        addClass: function( value ) {

写在后面

本文对jQuery源码核心结构进行了粗略的介绍,当然jQuery实际的源码要比这个复杂得多,但只要掌握了上面的要点,后续的分析就会轻松很多。jQuery源码之所以比较难看懂,是因为里面有许多为了解决糟糕的浏览器兼容性问题而引进的hack。

万事开头难,这是笔者jQuery源码解析的开篇之作,网络上这类的文章很多,而且有些写的很不错,这里写作的原因,一来总结,二来备忘。

未完待续。

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

通过js的面向对象来理解jQuery.extend()

1、$.extend()为jQuery添加扩展方法和属性,用一个或多个多想扩展另一个对象,并返回已修改的原始对象;

语法:$.extend({object1},{object2},{object3},{object4});把object2,object3,object4的对象中的属性和方法合并(重构)到object1对象中,后面参数的键值与前面的相同的话,合并(重构)后以后面的为主;

复制代码
//(1)多个参数对象
   var parameObj = { "province": "山东", "city": "济南" }; //实例的对象
   var parameObj1 = { "province": "河南", "name": "张三" };
   var parameObj2 = { "province": "山西", "sex": "男" };
   var parameObj3 = { funWay: function () { alert("方法") } };
   var newStr = $.extend(parameObj, parameObj1, parameObj2, parameObj3);
//object1的结构变化
   alert(parameObj.province); //山西  若键值相同合并(重构)以最后一个对象为主
   alert(parameObj.city); //济南
   alert(parameObj.name); //张三
   alert(parameObj.sex); //
parameObj.funWay(); //var newObj = new newStr(); 返回的newStr本身就是一个实例对象了,所以不能在new对象来调用方法和属性 //生成的newStr实例对象 alert(newStr.province); //山西 alert(newStr.city); //济南 alert(newStr.name); //张三 alert(newStr.sex); // newStr.funWay(); /*****通过jquery的扩展方法extend合并生成的是一个实例对象,所以他不需要再new生成实例对象或者通过prototype来添加方法*****/
复制代码

*通过合并(重构)后parameObj的对象结构发生了变化;然后把新生成的对象赋值给newStr,parameObj对象的结构和newStr对象的结构一样;

2、$.extend()一个参数对象的情况,要想理解这种情况,首先得明白Javascript的面相对象和jQuery对象;

(1)javascript的面相对象看下这篇博文有助于下面的理解:http://www.cnblogs.com/heluo/archive/2013/05/21/3091743.html

(2)jQuery就是javascript的一个巨大类库,类库中有许多方法,比如我们用语句 $("#btn1") 会生成一个 jQuery类的实例或者说是jQuery的实例对象,$("#btn1")所调用的函数就是,就是Jquery类库中定义的函数;

(3)我们为JQuery类扩展函数和属性经常用以下两种方法:

        1)jQuery.extend()  相当于为jQuery的类库扩展静态的方法和属性

        2)jQuery.fn.extend()  相当于为jQuery实例对象扩展方法和属性

        jQuery可以看成类名,也可以简写成$; $.fn.extend()=$.prototype.extend()这样扩展的方法只有new实例对象后才能调用;

var funObj = { Validate: function () { alert("验证方法"); } };
var f1 = $.extend(funObj);
$.Validate(); //就像调用静态方法一样
var f2 = $.fn.extend(funObj);
$("#but").Validate(); //调用实例对象的方法

(4)下面我们看一下$.extend()一个参数对象的情况,先看下面的例子:

复制代码
var obj = { "name": "小柳", run: function () { alert("一个参数对象") } };
var newObj = $.extend(obj);
alert(obj.name);
obj.run();
alert(newObj.name);
newObj.run();
$.run();
alert($.name);
newObj.prototype.AddFun = function () { }; //通过prototype添加方法
var oneObj = new newObj();
oneObj.AddFun();
复制代码

我们看到obj的结构没有发生变化,仍是一个实例对象,但是newObj对象结构和obj一样,但是是一个函数对象(或者类,因为javascript中的函数和类区分不明确),还能够通过prototype为其扩展添加属性和方法,然后通过new生成实例对象,但是新生成的oneObj对象不能再调用静态类中的方法和属性。

(5)JQuery 对象之所以能够实现链式操作是因为大多数的JQuery函数返回的是JQuery对象,除了那些获取值得JQuer函数;使用链式操作可以是代码看着简洁,并能提高性能,不用多次组合jQuery实例对象,链不宜过长,过长的话会降低可读行,不利于维护,所以适中为好!

 
 
原文地址:https://www.cnblogs.com/Leo_wl/p/3109772.html