LoginSignup
0
0

More than 5 years have passed since last update.

良く忘れるDOMのdragAndDrop操作一式

Last updated at Posted at 2018-02-08

3つのイベントで受ける

;['ondragover','ondrop','ondragleave'].forEach(d=>el[d]=dnd)

.dragのクラスを用意してエフェクトを掛ける。

.drag{background-color:orange}
/*.drag:after{content:'....'}*/

ファイルはフィルター以外に最大数も決めておく。

.filter(f=>f.type.match('image.*')) 
.slice(0,10) //10 is limit

template

let fn={}
;
fn.ce=(d=>document.createElement(d))
let el=fn.ce('div'),style=fn.ce('style')
;
style.innerHTML=`*{box-sizing:border-box}body{width:100vw;height:100vh;margin:0}div{width:100%;height:100%}
.drag{background-color:orange}img{height:200px}`
;[style,el].forEach(d=>document.body.appendChild(d))
;['ondragover','ondrop','ondragleave'].forEach(d=>el[d]=dnd)
;
function caller(e){ let img =fn.ce('img');img.src= e.target.result;/*data:img...*/ el.appendChild(img) }
function dnd(ev){
  let type=ev.type,mark ='drag'  //mark is .drag the custom class
  ;
  ev.stopPropagation();
  ev.preventDefault();
  if(type==='drop'){
    ;[].slice.call( ev.target.files||ev.dataTransfer.files )
     .filter(f=>f.type.match('image.*')) 
     .slice(0,10) //10 is limit
     .map((f)=>{ let r=new FileReader();  r.onloadend=caller;  r.readAsDataURL(f)})
   ;
   this.classList.remove(mark)
   return;
  }   
  if(type==='dragover'){ this.classList.add(mark);ev.dataTransfer.dropEffect = 'copy';return}
  if(type==='dragleave'){ this.classList.remove(mark);return}
 }
 ;

発展。blobにする。

//e.target.result;
fn.toBlob =function(base64) {
    let ma = /^data:(.*);base64,(.*)$/
    ;
    if(!ma.test(base64)){ console.log('error base64 data'); return null}

    let ary = base64.match(ma)  //[0] base64, [1] type, [2] body
    ,type = ary[1]
    ,bin = atob(ary[2])
    ,buffer = new Uint8Array(bin.length).map( (d,i)=>{return bin.charCodeAt(i)})
    ,blob = new Blob([buffer.buffer], {type: type})
    ;
    return blob;
//var debug = {hello: "world"};
//var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
}

更新 screen shot対応版(chrome)

ドラッグ&ドロップとスクリーンショット>ペーストから画像を取り込む。

//add onpaste
;['onpaste','ondragover','ondrop','ondragleave'].forEach(d=>el[d]=dnd)
//clipboard use the getAsFile()
f.getAsFile()

template

let fn={}
;
fn.ce=(d=>document.createElement(d))
let el=fn.ce('div'),style=fn.ce('style')
;
style.innerHTML=`*{box-sizing:border-box}body{width:100vw;height:100vh;margin:0}div{width:100%;height:100%}
.drag{background-color:orange}img{height:200px}`
;[style,el].forEach(d=>document.body.appendChild(d))
;['onpaste','ondragover','ondrop','ondragleave'].forEach(d=>el[d]=dnd)
;
function caller(ev){ let img =fn.ce('img');img.src= ev.target.result;/*data:img...*/ el.appendChild(img) }
;
function dnd(ev){
  let type=ev.type,mark ='drag'  //mark is .drag the custom class
  ;
  ev.stopPropagation();
  ev.preventDefault();
  if(type==='drop'||type==='paste'){
    //this paste hack, allow the chrome only.
    const flg= (type==='paste')
    ,files=(flg)?ev.clipboardData.items:ev.target.files||ev.dataTransfer.files
    ;
    ;[].slice.call(files)
     .filter(f=>f.type.match('image.*')) 
     .slice(0,10) //10 is limit
     .map((f)=>{ let r=new FileReader(); r.onloadend=caller;  r.readAsDataURL((flg)?f.getAsFile():f); })
   ;
   this.classList.remove(mark)
   return;
  }     
  if(type==='dragover'){ this.classList.add(mark);ev.dataTransfer.dropEffect = 'copy';return}
  if(type==='dragleave'){ this.classList.remove(mark);return}
}
;
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0