Tam DOM kontrolü ile React için esnek bir HTML5 sürükle ve bırak karışımı olan react-dnd'yi uyguladım .
Mevcut sürükle ve bırak kitaplıkları kullanım durumuma uymuyordu, bu yüzden kendim yazdım. Stampsy.com'da yaklaşık bir yıldır çalıştırdığımız koda benziyor, ancak React ve Flux'tan yararlanmak için yeniden yazıldı.
Sahip olduğum temel gereksinimler:
- Kendi başına sıfır DOM veya CSS yayınlayarak onu tüketen bileşenlere bırakır;
- Bileşenleri tüketmeye mümkün olduğunca az yapı uygulayın;
- HTML5 sürükle ve bırak özelliğini birincil arka uç olarak kullanın, ancak gelecekte farklı arka uçlar eklemeyi mümkün kılın;
- Orijinal HTML5 API'sinde olduğu gibi, yalnızca "sürüklenebilir görünümler" yerine verileri sürüklemeyi vurgulayın;
- HTML5 API tuhaflıklarını tüketen koddan gizleyin;
- Farklı bileşenler, farklı veri türleri için "sürükleme kaynakları" veya "bırakma hedefleri" olabilir;
- Bir bileşenin birkaç sürükleme kaynağı içermesine izin verin ve gerektiğinde hedefi bırakın;
- Uyumlu veriler sürükleniyorsa veya üzerinde geziniliyorsa, bırakma hedeflerinin görünümlerini değiştirmesini kolaylaştırın;
- Tarayıcı tuhaflıklarını atlatarak öğe ekran görüntüleri yerine küçük resimleri sürüklemek için resimleri kullanmayı kolaylaştırın.
Bunlar size tanıdık geliyorsa, okumaya devam edin.
Kullanım
Basit Sürükle Kaynağı
İlk olarak, sürüklenebilecek veri türlerini belirtin.
Bunlar sürükle kaynaklarının ve bırakma hedeflerinin "uyumluluğunu" kontrol etmek için kullanılır:
module.exports = {
BLOCK: 'block',
IMAGE: 'image'
};
(Birden fazla veri türünüz yoksa, bu kitaplık size göre olmayabilir.)
Ardından, sürüklendiğinde aşağıdakileri temsil eden çok basit bir sürüklenebilir bileşen yapalım IMAGE
:
var { DragDropMixin } = require('react-dnd'),
ItemTypes = require('./ItemTypes');
var Image = React.createClass({
mixins: [DragDropMixin],
configureDragDrop(registerType) {
registerType(ItemTypes.IMAGE, {
dragSource: {
beginDrag() {
return {
item: this.props.image
};
}
}
});
},
render() {
return (
<img src={this.props.image.url}
{...this.dragSourceFor(ItemTypes.IMAGE)} />
);
}
);
Belirterek configureDragDrop
, DragDropMixin
bu bileşenin sürükle bırak davranışını anlatıyoruz . Hem sürüklenebilir hem de bırakılabilir bileşenler aynı karışımı kullanır.
İçeride configureDragDrop
, bileşenin desteklediği registerType
her özelliğimizi aramamız gerekiyor ItemTypes
. Örneğin, uygulamanızda resimlerin birkaç temsili olabilir ve her biri birdragSource
için ItemTypes.IMAGE
.
A dragSource
, sadece sürükleme kaynağının nasıl çalıştığını belirleyen bir nesnedir. beginDrag
Sürüklediğiniz verileri temsil eden öğeyi döndürmek için ve isteğe bağlı olarak, sürükleme kullanıcı arayüzünü ayarlayan birkaç seçenek uygulamanız gerekir . İsteğe bağlı olarak canDrag
sürüklemeyi yasaklamak için uygulayabilir veya endDrag(didDrop)
bırakma gerçekleştiğinde (veya olmadığında) bazı mantık yürütebilirsiniz. Ve paylaşılan bir karışımın oluşturulmasına izin vererek bu mantığı bileşenler arasında paylaşabilirsiniz.dragSource
, onlar için .
Son olarak, sürükleme işleyicileri eklemek {...this.dragSourceFor(itemType)}
için bazı (bir veya daha fazla) öğe üzerinde kullanmanız gerekir render
. Bu, tek bir öğede birkaç "sürükleme tutamacına" sahip olabileceğiniz ve hatta farklı öğe türlerine karşılık gelebilecekleri anlamına gelir. ( JSX Spread Attributes sözdizimine aşina değilseniz , kontrol edin).
Basit Düşürme Hedefi
Diyelim ki s ImageBlock
için bir düşme hedefi olmak istiyoruz IMAGE
. Hemen hemen aynıdır, ancak registerType
bir dropTarget
uygulama vermemiz gerekir :
var { DragDropMixin } = require('react-dnd'),
ItemTypes = require('./ItemTypes');
var ImageBlock = React.createClass({
mixins: [DragDropMixin],
configureDragDrop(registerType) {
registerType(ItemTypes.IMAGE, {
dropTarget: {
acceptDrop(image) {
DocumentActionCreators.setImage(this.props.blockId, image);
}
}
});
},
render() {
return (
<div {...this.dropTargetFor(ItemTypes.IMAGE)}>
{this.props.image &&
<img src={this.props.image.url} />
}
</div>
);
}
);
Kaynağı Sürükle + Hedefi Bir Bileşene Bırak
Diyelim ki, kullanıcının bir görüntüyü dışarı sürükleyebilmesini istiyoruz ImageBlock
. Sadece buna uygun dragSource
ve birkaç işleyici eklememiz gerekiyor :
var { DragDropMixin } = require('react-dnd'),
ItemTypes = require('./ItemTypes');
var ImageBlock = React.createClass({
mixins: [DragDropMixin],
configureDragDrop(registerType) {
registerType(ItemTypes.IMAGE, {
dragSource: {
canDrag() {
return !!this.props.image;
},
beginDrag() {
return {
item: this.props.image
};
}
}
dropTarget: {
acceptDrop(image) {
DocumentActionCreators.setImage(this.props.blockId, image);
}
}
});
},
render() {
return (
<div {...this.dropTargetFor(ItemTypes.IMAGE)}>
{/* Add {...this.dragSourceFor} handlers to a nested node */}
{this.props.image &&
<img src={this.props.image.url}
{...this.dragSourceFor(ItemTypes.IMAGE)} />
}
</div>
);
}
);
Başka Ne Mümkün?
Her şeyi ele almadım, ancak bu API'yi birkaç şekilde daha kullanmak mümkündür:
- Kullanım
getDragState(type)
vegetDropState(type)
sürükleyerek aktiftir ve CSS sınıflarını veya özelliklerini değiştirmek için kullanırsanız öğrenmek için;
- Görüntüleri sürükleme yer tutucusu olarak kullanmak
dragPreview
için belirtin Image
( ImagePreloaderMixin
bunları yüklemek için kullanın );
- Diyelim ki yeniden düzenlenebilir hale getirmek
ImageBlocks
istiyoruz. Onlara sadece uygulamak için ihtiyacımız var dropTarget
vedragSource
ItemTypes.BLOCK
.
- Başka tür bloklar eklediğimizi varsayalım. Yeniden sıralama mantığını bir mixin içine yerleştirerek yeniden kullanabiliriz.
dropTargetFor(...types)
aynı anda birkaç tür belirtmeye izin verir, böylece bir bırakma bölgesi birçok farklı türü yakalayabilir.
- Daha ayrıntılı kontrole ihtiyaç duyduğunuzda, çoğu yöntem, onlara son parametre olarak neden olan sürükleme olayından geçer.
Güncel dokümantasyon ve kurulum talimatları için Github'da react-dnd deposuna gidin .