html5之拖放詳解

拖放是一種常見的特性整袁,即抓取對象以后拖到另一個位置菠齿。在 HTML5 中,拖放是標準的一部分坐昙,任何元素都能夠拖放绳匀。Internet Explorer 9、Firefox炸客、Opera 12疾棵、Chrome 以及 Safari 5 支持拖放。

1.drggable屬性

如果網(wǎng)頁元素的draggable元素為true痹仙,這個元素就是可以拖動的是尔。

<div draggable="true">Draggable Div</div>

注意:在大多數(shù)瀏覽器中,a元素和img元素默認就是可以拖放的开仰,但是為了保險起見拟枚,最好還是加上draggable屬性。

2.事件

dragstart:網(wǎng)頁元素開始拖動時觸發(fā)众弓。
drag:被拖動的元素在拖動過程中持續(xù)觸發(fā)恩溅。
dragenter:被拖動的元素進入目標元素時觸發(fā),應在目標元素監(jiān)聽該事件谓娃。
dragleave:被拖動的元素離開目標元素時觸發(fā)脚乡,應在目標元素監(jiān)聽該事件。
dragover:被拖動元素停留在目標元素之中時持續(xù)觸發(fā)滨达,應在目標元素監(jiān)聽該事件奶稠。
drap:被拖動元素或從文件系統(tǒng)選中的文件,拖放落下時觸發(fā)弦悉。
dragend:網(wǎng)頁元素拖動結束時觸發(fā)窒典。
注意:以上這些事件都可以指定回調(diào)函數(shù)。

3.dataTransfer對象

拖動過程中稽莉,回調(diào)函數(shù)接受的事件參數(shù)瀑志,有一個dataTransfer屬性。它指向一個對象污秆,包含了與拖動相關的各種信息劈猪。

draggableElement.addEventListener('dragstart', function(event) {       event.dataTransfer.setData('text', 'Hello World!');
});

上面代碼在拖動開始時,在dataTransfer對象上儲存一條文本信息良拼,內(nèi)容為“Hello World”战得。當拖放結束時,可以用getData方法取出這條信息庸推。

dataTransfer對象的屬性:

**dropEffect:**拖放的操作類型常侦,決定了瀏覽器如何顯示鼠標形狀浇冰,可能的值為copy、move聋亡、link和none肘习。

effectAllowed:指定所允許的操作,可能的值為copy坡倔、move漂佩、link、copyLink罪塔、copyMove投蝉、linkMove、all征堪、none和uninitialized(默認值瘩缆,等同于all,即允許一切操作)请契。
files:包含一個FileList對象咳榜,表示拖放所涉及的文件,主要用于處理從文件系統(tǒng)拖入瀏覽器的文件爽锥。
types:儲存在DataTransfer對象的數(shù)據(jù)的類型涌韩。

dataTransfer對象的方法:
**setData(format, data):**在dataTransfer對象上儲存數(shù)據(jù)。第一個參數(shù)format用來指定儲存的數(shù)據(jù)類型氯夷,比如text臣樱、url、text/html等腮考。
**getData(format):**從dataTransfer對象取出數(shù)據(jù)雇毫。
**clearData(format):**清除dataTransfer對象所儲存的數(shù)據(jù)。如果指定了format參數(shù)踩蔚,則只清除該格式的數(shù)據(jù)棚放,否則清除所有數(shù)據(jù)。
**setDragImage(imgElement, x, y):**指定拖動過程中顯示的圖像馅闽。默認情況下飘蚯,許多瀏覽器顯示一個被拖動元素的半透明版本。參數(shù)imgElement必須是一個圖像元素福也,而不是指向圖像的路徑局骤,參數(shù)x和y表示圖像相對于鼠標的位置。

dataTransfer對象允許在其上存儲數(shù)據(jù)暴凑,這使得在被拖動元素與目標元素之間傳送信息成為可能峦甩。

4.實例講解

1.網(wǎng)頁元素拖放

<!DOCTYPE html>
<html>
<head>
    <title>Video step2</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<style>
ul{
    min-height:100px;
    background-color:#EEE;
    margin:20px;
}
ul li{
    background-color:#CCC;
    padding:10px;
    margin-bottom:10px;
}
</style>
<body>
    <ul id="drag-elements">
        <li draggable="true">A</li>
        <li draggable="true">B</li>
        <li draggable="true">C</li>
    </ul>
    <ul id="drop-target"></ul>
<script>
    //獲取目標元素
    var target = document.querySelector('#drop-target');
    //獲取需要拖放的元素
    var dragElements = document.querySelectorAll('#drag-elements li');
    //臨時記錄被拖放的元素
    var elementDragged = null;
    //循環(huán)監(jiān)聽被拖放元素的開始拖放和結束拖放事件
    for (var i = 0; i < dragElements.length; i++) {
        //開始拖放事件監(jiān)聽
        dragElements[i].addEventListener('dragstart', function(e) {
            //設置當前拖放元素的數(shù)據(jù)參數(shù)
            e.dataTransfer.setData('text', this.innerHTML);
            //保存當前拖放對象
            elementDragged = this;
        });
        //結束拖放事件監(jiān)聽
        dragElements[i].addEventListener('dragend', function(e) {
            //注銷當前拖放對象
            elementDragged = null;
        });
    }
    //目標元素監(jiān)聽被拖放元素進入事件
    target.addEventListener('dragover', function(e) {
        //阻止瀏覽器默認行為
        e.preventDefault();
        //設置鼠標樣式
        e.dataTransfer.dropEffect = 'move';
        return false;
    });
    //目標元素監(jiān)聽當被拖放元素落下時刻事件
    target.addEventListener('drop', function(e) {
        //阻止默認行為
        e.preventDefault();
        //阻止默認行為
        e.stopPropagation();
        //獲取當前被拖放元素的存放數(shù)據(jù)參數(shù)
        this.innerHTML = 'Dropped ' + e.dataTransfer.getData('text');
        //刪除被拖放元素    
               document.querySelector('#dragelements').
               removeChild(elementDragged); 
        return false;
    });
</script>
</body>
</html>

2.拖動本地文件

假定我們要從文件系統(tǒng)拖動一個txt文本,在瀏覽器中展示內(nèi)容现喳。
首先凯傲,獲取拖動的目標元素和內(nèi)容展示區(qū)域犬辰。

var target = document.querySelector('#target');var contentDiv = document.querySelector('#content');

然后,定義目標元素的dragover事件泣洞,主要是為了當文件進入目標元素后忧风,改變鼠標形狀。

target.addEventListener('dragover', function(e) { e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = 'copy';});

接著球凰,定義目標元素的drop事件,展示文件內(nèi)容腿宰。

target.addEventListener('drop', function(e) { 
   e.preventDefault(); 
   e.stopPropagation(); v
   var fileList = e.dataTransfer.files; 
   if (fileList.length > 0) { 
       var file = fileList[0]; 
       var reader = new FileReader(); 
       reader.onloadend =function(e) { 
       if (e.target.readyState == FileReader.DONE) { 
        var content = reader.result; contentDiv.innerHTML = "File: " + file.name + "\n\n" + content; } } 
       reader.readAsBinaryString(file); 
      }
});

具體代碼:

<!DOCTYPE html>
<html>
<head>
    <title>Video step2</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<style>
#target{
    margin:10px;
    min-height:100px;
    max-height:600px;
    background-color:#EEE;
    border-radius:5px;
    overflow:auto;
}
#content{
    padding:10px;
    font-size:18px;
    line-height:25px;
}
</style>
<body>
    <div id="target" title="拖動文件到這里">
    <div id="content"></div>
</div>
<script>
    //目標元素監(jiān)聽被拖放文件進入元素區(qū)域事件
    target.addEventListener('dragover', function(e) {
        //阻止默認行為
        e.preventDefault();
        //阻止默認行為
        e.stopPropagation();
        //改變鼠標樣式
        e.dataTransfer.dropEffect = 'copy';
        return false;
    });
    //目標元素監(jiān)聽被拖放文件落下一刻的事件
    target.addEventListener('drop', function(e) {
        //阻止默認行為
        e.preventDefault();
        e.stopPropagation();
        
        //獲取所拖放的文件
        var fileList = e.dataTransfer.files;
        
        if (fileList.length) {
            //獲取第一個文件
            var file = fileList[0];
            //創(chuàng)建文件輸入流
            var reader = new FileReader();
            //文件讀取回調(diào)函數(shù)
            reader.onloadend = function(e) {
                if (e.target.readyState == FileReader.DONE) {
                    var content = reader.result;
                    contentDiv.innerHTML = 'File: ' + file.name + '\n\n' + content;
                }
            }
            //讀取文件
            reader.readAsBinaryString(file);
        }
    });
</script>
</body>
</html>

謝謝觀看呕诉,如有任何疑問,歡迎評論交流吃度!

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末甩挫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子椿每,更是在濱河造成了極大的恐慌伊者,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件间护,死亡現(xiàn)場離奇詭異亦渗,居然都是意外死亡,警方通過查閱死者的電腦和手機汁尺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門法精,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痴突,你說我怎么就攤上這事搂蜓。” “怎么了辽装?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵帮碰,是天一觀的道長。 經(jīng)常有香客問我拾积,道長殉挽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任殷勘,我火速辦了婚禮此再,結果婚禮上,老公的妹妹穿的比我還像新娘玲销。我一直安慰自己输拇,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布贤斜。 她就那樣靜靜地躺著策吠,像睡著了一般逛裤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上猴抹,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天带族,我揣著相機與錄音,去河邊找鬼蟀给。 笑死蝙砌,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的跋理。 我是一名探鬼主播择克,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼前普!你這毒婦竟也來了肚邢?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拭卿,失蹤者是張志新(化名)和其女友劉穎骡湖,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體峻厚,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡响蕴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了目木。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片换途。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖刽射,靈堂內(nèi)的尸體忽然破棺而出军拟,到底是詐尸還是另有隱情,我是刑警寧澤誓禁,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布懈息,位于F島的核電站,受9級特大地震影響摹恰,放射性物質(zhì)發(fā)生泄漏辫继。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一俗慈、第九天 我趴在偏房一處隱蔽的房頂上張望姑宽。 院中可真熱鬧,春花似錦闺阱、人聲如沸炮车。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘦穆。三九已至纪隙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扛或,已是汗流浹背绵咱。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留熙兔,地道東北人悲伶。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像黔姜,于是被迫代替她去往敵國和親拢切。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容