1. Punca & Idea
Saya sentiasa mahu menulis kesan seret dan lepas js asli, dan saya seronok belajar bertindak balas baru-baru ini. Jadi saya menggunakan tindak balas untuk mencapai kesan seret dan lepas ini.
Pertama sekali, idea kesan seretan sebenarnya sangat mudah. Terdapat terutamanya tiga langkah:
1. Apabila tetikus dihidupkan, mulakan acara boleh seret dan rekod parameter koordinat asal unsur yang diseret.
2. Apabila onmousemove, rekod jarak yang digerakkan oleh tetikus dalam masa nyata dan hitung serta tetapkan nilai koordinat baharu berdasarkan parameter koordinat peringkat pertama elemen yang diseret.
3 Semasa onmouseup, tutup acara boleh seret dan rekod nilai koordinat baharu.
Nota: Kedudukan elemen ditentukan terutamanya oleh kedudukan mutlak atas dan kiri, jadi css elemen yang diseret mesti ditetapkan kepada kedudukan mutlak.
2. Alat bantu
Alat tambahan terutamanya menjadikan proses pembangunan cekap dan sejuk. Dalam demo ini, saya ingin mengesyorkan alat pembangunan penyegerakan gulp+pelayar kepada semua orang Gulp mempunyai banyak fungsi Dalam demo ini, fungsi utama gulp adalah untuk menyediakan kompilasi masa nyata bagi fail jsx , jika anda menulis css, Ia adalah sass, dan anda juga boleh menyediakan kompilasi masa nyata sass. Menggunakan penyegerakan penyemak imbas, perkara utama ialah memuat semula halaman secara automatik dalam masa nyata Apabila kami biasanya membuat halaman dan melihat kesannya, kami biasanya menyegarkan penyemak imbas melalui F5, dan kemudian melihat halaman tersebut. Tetapi dengan pemalam ini, apabila anda selesai menulis kod, hanya tekan ctrl+s untuk menyimpan, dan kesan baharu akan dimuat semula secara automatik dalam penyemak imbas, dan kemudian anda boleh melihatnya.
Penjelasan terperinci tentang penggunaan:
Pemasangan:
1. Pasang gulp dalam persekitaran nod Saya tidak akan menerangkan butiran di sini, sila rujuk catatan blog saya "Perkara yang Anda Mesti Tahu untuk Bermula dengan React.js"
2. Untuk memasang gulp-livereload, pada baris arahan atau git bash, masukkan npm install --save-dev gulp-livereload
3. Pasang gulp-watch, pada baris arahan atau git bash, masukkan npm install --save-dev gulp-watch
4. Untuk memasang penyegerakan penyemak imbas, pada baris arahan atau git bash, masukkan npm install --save-dev browser-sync
Tatarajah dan penjelasan adalah seperti yang ditunjukkan dalam rajah:
3. Tentukan halaman pembinaan komponen
Nota: Arahan kod di sini semuanya selepas modul berkaitan tindak balas dipasang untuk proses pemasangan, sila lihat catatan blog saya "Perkara yang Anda Mesti Tahu untuk Bermula dengan react.js".
Rendering:
Idea pembahagian komponen:
Saya fikir adalah lebih baik untuk membahagikan komponen kepada bahagian yang lebih kecil, jadi saya membuat input dan butang menjadi satu komponen masing-masing:
var React=require('react'); var MyInput=React.createClass({ render:function(){ return ( <div className="form-group"> <label htmlFor={this.props.labelId} className="col-sm-2 control-label{this.props.labelTip</label> <div className="col-sm-10"> <input name={this.props.name} type={this.props.type} onChange={this.props.onChange} className="form-control" id={this.props.labelId} placeholder={this.props.placeholder}/> </div> </div> ); } }); module.exports=MyInput;
var React=require('react'); var Button=React.createClass({ render:function(){ return ( <button type={this.props.type} className="loginButton">{this.props.ButtonTip}</button> ); } }) module.exports=Button;
Memandangkan terdapat banyak input yang perlu dinyatakan, dalam kes ini, jika anda mentakrifkannya seperti saya, anda perlu melepasi terlalu banyak parameter, dan sebenarnya, kebanyakan input yang dilog masuk adalah tetap dan tidak perlu untuk menggunakannya semula, jadi ini sebenarnya bukan idea yang baik. Adalah lebih baik untuk menulis input di sini secara langsung.
Komponen induk selepas menulis:
render:function(){ return ( <form className="form-horizontal" id="form" ref="dragBox" onSubmit={this.submitHandler} onMouseMove={this.move} onMouseUp={this.endDrag}> <DragArea callbackParent={this.onChildChanged} /> <div id="form-wrap"> <MyInput name="username" labelId={"userId"} labelTip={"用户名"} type={"text"} placeholder={"请输入用户名"} value={this.state.username} onChange={this.handleChange}/> <MyInput name="password" labelId={"pw"} labelTip={"密码"} type={"password"} placeholder={"请输入密码"} value={this.state.password} onChange={this.handleChange}/> <div className="form-group"> <div className="col-sm-offset-2 col-sm-10"> <div className="checkbox"> <label> <input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange} /> 记住我 </label> </div> </div> </div> <MyButton type={"submit"} ButtonTip={"登陆"}/> </div> </form> );
Nota: Oleh kerana nod dom sebenar perlu diperolehi dalam demo, ref ditakrifkan.
Tambah gaya css dan halaman selesai! Akhirnya, inilah titiknya! ! !
4. Komunikasi antara komponen ibu bapa dan anak untuk melaksanakan seret dan lepas
Nota: Memandangkan kesan yang saya ingin capai ialah apabila tetikus ditekan pada subkomponen DragArea, keseluruhan borang diseret, jadi DragArea memulakan penyeretan dan borang bertindak balas. Oleh itu, beberapa sifat keadaan komponen induk mesti diserahkan kepada komponen anak pada permulaan Kemudian apabila tetikus ditekan pada DragArea, parameter koordinat asal komponen induk mesti ditemui melalui DragArea komponen anak, dan kemudiannya. nyatakan sifat dalam komponen induk mesti dikemas kini dan Memberitahu komponen induk bahawa penyeretan tersedia. Parameter yang dihantar daripada komponen induk kepada komponen anak dihantar terus. Komponen anak perlu menghantar peristiwa untuk menghantar parameter kepada komponen induk. Jadi tentukan fungsi sedemikian dalam komponen induk:
onChildChanged:function(newState){ //因为参数过多,所以把参数放到对象里面,通过对象来传 this.setState(newState); },
Subkomponen perlu mengikat fungsi ini, seperti kod di atas: callbackParent={this.onChildChanged}
Dalam komponen kanak-kanak, fungsi tindak balas ialah:
startDrag:function(e){ var dragBox=document.getElementById('form'); var newState={}; var event=e||window.event; event.preventDefault(); var computedStyle=document.defaultView.getComputedStyle(dragBox,null); newState.left=computedStyle.left; newState.top=computedStyle.top; newState.currentX=event.clientX; newState.currentY=event.clientY; newState.flag=true; <span style="color: #0000ff;"> this.props.callbackParent(newState);</span> }
Dengan cara ini, suis seret diaktifkan dalam sub-komponen, dan parameter yang berkaitan dari dari telah dikemas kini Dua peristiwa lain dari, bergerak dan endDrag, ialah:
move:function(event){ var e = event ? event : window.event; //兼容IE的写法 if (this.state.flag) { var nowX = e.clientX, nowY = e.clientY; var disX = nowX - this.state.currentX, disY = nowY - this.state.currentY; ReactDOM.findDOMNode(this.refs.dragBox).style.left = parseInt(this.state.left) + disX + "px"; ReactDOM.findDOMNode(this.refs.dragBox).style.top = parseInt(this.state.top) + disY + "px"; } }, endDrag:function(){ var computedStyle=document.defaultView.getComputedStyle(ReactDOM.findDOMNode(this.refs.dragBox),null); this.setState({ left:computedStyle.left, top:computedStyle.top, flag:false }); }
Pada ketika ini, seret dan lepas dilaksanakan!
5. Refleksi dan Tinjauan
1. Secara teorinya, kesan seretan boleh direalisasikan dalam mana-mana elemen, dan idea seret adalah sama, jadi secara teorinya, fungsi setiap proses seretan boleh diekstrak dan dijadikan Mixin, dan kemudian Boleh dipanggil berulang kali. Ini adalah idea awal saya, tetapi saya sentiasa membuat kesilapan apabila menghantar parameter, bertindak balas dan elemen mengikat. Selepas mencari maklumat, saya tidak dapat mencari maklumat tentang kaedah penulisan mudah bertindak balas dan seret dan lepas Hanya terdapat beberapa pemalam khas untuk bertindak balas, dan ia ditulis dalam ES6 saya tidak dapat memahaminya tahap. Jadi saya tinggalkan cara penulisan ini buat sementara waktu. Saya harap pakar yang mempunyai idea yang berkaitan boleh berkongsi dengan saya.
2. Apabila subkomponen dalam artikel memperoleh parameter daripada, ia menggunakan var dragBox=document.getElementById('form'); Tetapi saya tidak begitu biasa dengan cara mendapatkan dom komponen induk daripada komponen anak. Saya telah cuba mentakrifkan refs=this.refs.dragBox dalam komponen induk. Kemudian ia dihantar kepada sub-komponen, tetapi saya tidak tahu mengapa penyemak imbas terus melaporkan ralat yang mengatakan bahawa ini bukan nod dom. Minta petunjuk kepada Allah.
3. Cara umum untuk menulis peristiwa seretan adalah dengan mentakrifkan peristiwa pergerakan tetikus dan naik tetikus pada dokumen, tetapi kedua-dua peristiwa ini dikaitkan dengan parameter dari dalam kes ini, jika saya mentakrifkannya dalam dokumen dalam tindak balas, I tidak boleh menjejaki peristiwa yang berkaitan. Jadi saya mentakrifkannya dari. Adakah terdapat cara yang lebih baik? Sila kongsi!
4. Revolusi masih belum berjaya, rakan-rakan masih perlu bekerja keras!
Demo ini telah dimuat naik ke: https://github.com/LuckyWinty/dragDemo
Di atas adalah keseluruhan kandungan artikel ini, saya harap ia akan membantu kajian semua orang.