Vor einigen Jahren war ich an der Gestaltung und Entwicklung eines Immobilien-Website-Projekts beteiligt. Da der Projektmanager relativ hohe Anforderungen stellt, habe ich auf viele hervorragende Eigenschaften von Immobilien verwiesen Websites und wollten die hervorragenden Designs und Ideen anderer Menschen sammeln. Der damalige Designentwurf und die Funktionsumsetzung müssen möglicherweise auf den nächsten Tag verschoben werden Reden wir nicht darüber. Reden wir über den Fall, den wir heute erklären werden. Ich weiß nicht, ob Sie Soufun.com besucht haben (es steht überhaupt nicht im Verdacht, Werbung zu machen). einige Werbegebühren?), gibt es eine Funktion, die dem Produktmanager besonders gut gefällt, nämlich die folgende:
Dies ist der aktuelle Effekt, möglicherweise gibt es einige Änderungen. Der ursprüngliche Effekt besteht darin, dass das Bild im Inneren nach oben, unten, links und rechts gezogen werden kann und sich dann auch die auf dem Haus angezeigte Gebäudenummer mitbewegt Zeit, js Die Fähigkeit war nicht gut genug und die Anforderungen des Projektmanagers wurden nicht erfüllt, aber später lehnte der Projektmanager diesen Effekt ab und ersetzte ihn durch einen anderen Effekt
Obwohl der Projektleiter diesen Effekt nicht wollte, hinterließ er damals einen Knoten in meinem Herzen, den ich bis heute nicht vergessen kann.
Okay, das ist meine ursprüngliche Absicht, diesen Blog heute zu schreiben. Ich hoffe, er kann Studenten, die diesen Drag-Effekt erzielen möchten, aber nicht wissen, wie sie ihn erreichen können, eine Idee geben, damit sie nicht gehen Natürlich gibt es viele Möglichkeiten, Drag & Drop zu implementieren. Hier werde ich nur eine Methode in JavaScript vorstellen und das Prinzip langsam verstehen!
Okay, die Witze sind vorbei, kommen wir zur Sache. Zuerst müssen wir verstehen, was Drag ist, und ich weiß es, aber ich möchte es trotzdem beschreiben:
Drag & Drop ist ein Container, den Sie mit der Maus auf der Seite ziehen können. Die genaue Beschreibung sollte lauten. Bewegen Sie die Maus zum Container und drücken Sie dann die Maus. Achten Sie darauf, dass Sie sie nicht loslassen. und dann ziehen Die Maus und der Container können der Maus folgen. Wenn Sie die Maus loslassen, bleibt der Container stehen. Ein Beispiel aus dem wirklichen Leben ist, dass ich meine Hand auf den Tisch lege Wenn meine Hand stehen bleibt, bleibt die Kiste stehen. Nimm sie weg, die Kiste bewegt sich nicht, hehe, ich verstehe!
Glauben Sie nicht, dass das oben Genannte viel Unsinn ist, wir können daraus viele Informationen gewinnen, die Zusammenfassung lautet wie folgt:
Ziehen = Maus nach unten + Mausbewegung + Maus nach oben
Damit ist eine Drag-and-Drop-Aufgabe abgeschlossen. Es stellt sich heraus, dass dies das Prinzip von Drag-and-Drop ist. Wenn Sie Drag-and-Drop implementieren möchten, können Sie natürlich die oben genannten drei Aktionen implementieren, um den Drag-and-Drop-Effekt zu simulieren . Nun, es entspricht der Syntax in JavaScript. Es müssen nur diese 3 Aktionen implementiert werden:
onmousedown, onmousemove, onmouseup
Der implementierte Code sollte sein:
obj.onmousedown = function(ev){ obj.onmousemove = function(ev){ } ; obj.onmouseup = function(ev){ }; }
Warum sollten die nächsten beiden Aktionen darin geschrieben werden? Okay, die allgemeine Idee des ersten Schritts besteht darin, zu überlegen, wie man das Objekt mit der Maus bewegt. Die Idee ist wahrscheinlich so:
Zuerst muss das Objekt positioniert werden, da wir seine linken und oberen Werte manipulieren müssen. Dann müssen wir die Mausverschiebung selbst berücksichtigen Wissen Sie, dass sich die Maus bewegt hat? Wie weit ist sie dann vom Objekt entfernt? Bewegt sich das Objekt um die gleiche Entfernung wie die Maus? Haha, ich habe ein paar Ideen und es fühlt sich süß an. Das Problem ist jetzt, wie man den Abstand der Maus ermittelt. Wenn Sie mehr wissen möchten, gehen Sie hier nicht näher darauf ein. Viele Meister haben auch verwandte Blogs. Hier ist ein Bild, um es zu zeigen:
Erklärung: Das blaue Kästchen ist die Breite und Höhe des Bildschirms, das dicke schwarze Kästchen ist die Breite und Höhe des sichtbaren Bereichs des Browsers (Browser-Reduktionseffekt), das dünne schwarze Kästchen ist das Objekt, das mit der Maus gezogen werden soll Wie in der Abbildung gezeigt, erhalten Sie die Koordinaten der Maus. Sie können event.clientX und event.clientY verwenden, um sie abzurufen, oh
Das allgemeine Berechnungsprinzip kann der folgenden Abbildung entnommen werden:
Erklärung: Links ist die Anfangsposition, rechts ist die Zielposition, der Ursprung ist die Mausposition, das große schwarze Kästchen ist die sichtbare Breite des Browsers, das kleine schwarze Kästchen ist das Ziehobjekt, siehe Status Ziehen Sie das Objekt an die Zielposition und ermitteln Sie die endgültige Position der Maus. Subtrahieren Sie dann die Differenz zwischen der Maus und dem Objekt und weisen Sie sie dann den oberen und linken Werten des Objekts zu Sie können auch die Positionsdifferenz der Maus ermitteln und diese dann zu den Anfangswerten oben und links addieren. Wir verwenden die erste. Die zweite Art ist auch möglich, probieren Sie es selbst aus:
obj.onmousedown = function(ev){ var ev = ev || event; var disX = ev.clientX - this.offsetLeft,disY = ev.clientY - this.offsetTop; document.onmousemove = function(ev){ var ev = ev || event; obj.style.left = ev.clientX - disX + 'px'; obj.style.top = ev.clientY - disY + 'px'; }; document.onmouseup = function(ev){ var ev = ev || event; document.onmousemove = document.onmouseup = null; }; }
这里说明一下:onmousemove和onmouseup之所以用document对象而不用obj对象,是因为如果用obj对象,鼠标在obj内部还好,如果在obj外面的话,拖拽会很怪异,你也可以改成obj体会一下,最后我们在鼠标弹起的时候将事件都清空;
上面的基本拖拽就算完成了,但是细心的同学一定会问,如果页面上有文字的话,拖拽物体会将文字选中,这效果岂不是怪怪的,没错,这是因为拖拽的时候触发了浏览器的默认选择事件,所以,在拖拽的时候,我们要清除这个默认事件,那怎么清除呢?
下面给一个兼容性写法:
if(ev.stopPropagation){ ev.stopPropagation(); }else{ ev.cancelBubble = true; //兼容IE } //简写成 ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true;
将上面的代码放在onmousedown下,鼠标按下就清除浏览器默认事件,文字就不会被选中了,好了,一个简单的拖拽效果就完成了,当然你现在是看不到效果,之所以不给demo链接是为了让你自己试着写一写,这样印象更深刻,
好了,那问题又来了,到这里就这样完了吗?。。。。。。按本人的风格,当然没有,干货还在后面!
如果我想实现这样一个效果,就是这一个大的容器里面(可以是box,也可以是document),怎么样能让我们的拖拽对象不跑出去呢,换句话说,拖到边缘就拖不动了,耶,是不是很多人想要实现的效果,哈哈,我们看看实现的原理是什么:
现实生活中,一个物体在一个盒子里跑不出去,是因为有堵墙,那我们只要能模拟出这堵墙,就可以把物体框起来,那这堵墙要怎么做呢?我们可以换个思路,当拖拽对象拖到边缘的时候,比如说拖到右边,我们将它的left固定住,是不是就不能再往右了,因为left值不能再加了,那么拖到底部,同理我们将top值固定住,就不能再往下拖了,理解吗?
最终的结果就是如下:
//左侧 if(obj.offsetLeft <=0){ obj.style.left = 0; }; //右侧 if(obj.offsetLeft >= pWidth - oWidth){ obj.style.left = pWidth - oWidth + 'px'; }; //上面 if(obj.offsetTop <= 0){ obj.style.top = 0; }; //下面 if(obj.offsetTop >= pHeight - oHeight){ obj.style.top = pHeight - oHeight + 'px'; };
说明:pWidth,pHeight 表示父级元素的宽高(这里是表示相对于父级的宽高限制),oWidth,oHeigt表示拖拽元素的宽高
最后,我将整个拖拽代码整理了一下:
/* 参数说明: 元素绝对定位,父级相对定位,如果父级为window,则可以不用 传一个参数,表示父级为window,物体相对于window范围拖动 传2个参数,则父级为第二个参数,物体相对于父级范围拖动 参数为id值 */ function drag(obj,parentNode){ var obj = document.getElementById(obj); if(arguments.length == 1){ var parentNode = window.self; var pWidth = parentNode.innerWidth,pHeight = parentNode.innerHeight; }else{ var parentNode = document.getElementById(parentNode); var pWidth = parentNode.offsetWidth,pHeight = parentNode.offsetHeight; } obj.onmousedown = function(ev){ var ev = ev || event; var disX = ev.clientX - this.offsetLeft,disY = ev.clientY - this.offsetTop; var oWidth = obj.offsetWidth,oHeight = obj.offsetHeight; //阻止冒泡时间 ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true; document.onmousemove = function(ev){ var ev = ev || event; obj.style.left = ev.clientX - disX + 'px'; obj.style.top = ev.clientY - disY + 'px'; //左侧 if(obj.offsetLeft <=0){ obj.style.left = 0; }; //右侧 if(obj.offsetLeft >= pWidth - oWidth){ obj.style.left = pWidth - oWidth + 'px'; }; //上面 if(obj.offsetTop <= 0){ obj.style.top = 0; }; //下面 if(obj.offsetTop >= pHeight - oHeight){ obj.style.top = pHeight - oHeight + 'px'; }; }; document.onmouseup = function(ev){ var ev = ev || event; document.onmousemove = document.onmouseup = null; }; } }
说明:我这里处理的效果是,如果传一个参数,表示相对的对象是window对象,如果传2个参数,第一个是拖拽对象,第二个为相对父级
开篇就说了,搜房网的那个图片拖拽效果是我的一个心结,我写了一个类似的效果,供大家参考,因为自己没有买服务器,所以效果我就不展示了,直接把代码贴出来,供大家参考:
css:
<style> .box{ width:600px; height:400px; margin:50px auto; position:relative; overflow:hidden; } #box{ width:1000px; height:800px; position:absolute; left:50%; top:50%; margin:-400px 0 0 -500px; } #pic{ width:800px; height:600px; background:url(images/pic1.jpg) no-repeat; position:absolute; left:100px; top:100px; } #pic:hover{ cursor:move; } </style>
html:
<div class="box"> <div id="box"> <div id="pic"></div> </div> </div>
javascript:
window.onload = function(){ drag("pic","box"); function drag(obj,parentNode){ var obj = document.getElementById(obj); if(arguments.length == 1){ var parentNode = window.self; var pWidth = parentNode.innerWidth,pHeight = parentNode.innerHeight; }else{ var parentNode = document.getElementById(parentNode); var pWidth = parentNode.offsetWidth,pHeight = parentNode.offsetHeight; } obj.onmousedown = function(ev){ var ev = ev || event; var disX = ev.clientX - this.offsetLeft,disY = ev.clientY - this.offsetTop; var oWidth = obj.offsetWidth,oHeight = obj.offsetHeight; //阻止冒泡时间 ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true; document.onmousemove = function(ev){ var ev = ev || event; obj.style.left = ev.clientX - disX + 'px'; obj.style.top = ev.clientY - disY + 'px'; //左侧 if(obj.offsetLeft <=0){ obj.style.left = 0; }; //右侧 if(obj.offsetLeft >= pWidth - oWidth){ obj.style.left = pWidth - oWidth + 'px'; }; //上面 if(obj.offsetTop <= 0){ obj.style.top = 0; }; //下面 if(obj.offsetTop >= pHeight - oHeight){ obj.style.top = pHeight - oHeight + 'px'; }; }; document.onmouseup = function(ev){ var ev = ev || event; document.onmousemove = document.onmouseup = null; }; } } }
效果完全是用的那个封装代码块,引用起来也挺方便,有人会问了,你这用的id获取DOM元素,一个页面只能用一次啊,如果页面多次使用呢,有道理,解决方案之一,那就命名不同的id呗,又不犯法,方案二,获取id的地方改成获取class,但是要注意的是,getElementsByClassName是获取的class集合,需要改写一下,这里我就不写了,有兴趣的同学自行改写一下,好了,到这里真的结束了!