Dieser Artikel stellt hauptsächlich die relevanten Informationen zum Anpassen der Vue-Anweisung v-selectable ähnlich wie jQuery UI Selectable vor. Ich hoffe, dass er allen helfen kann.
Schauen wir uns ohne weitere Umschweife zunächst die Wirkung an.
Tatsächlich handelt es sich um eine Funktion, mit der Sie die Maus gedrückt halten können, um Elemente in einem Bereich auszuwählen. Ich glaube, jeder, der die Jquery-Benutzeroberfläche verwendet hat, weiß, dass dies eine ist Wenn wir jedoch Vue verwenden, gibt es natürlich kein ähnliches Plug-In für die Entwicklung, aber ich möchte JQuery und JQuery UI nicht in mein Projekt einführen, also habe ich versucht, es zu implementieren Ähnliche Funktionen habe ich selbst.
Es gibt zwei Schritte, um diese Funktion zu implementieren. Der erste Schritt besteht darin, die Funktion des Mausauswahlbereichs zu implementieren, und der zweite Schritt besteht darin, dem ausgewählten Element in diesem Bereich eine aktive Klasse hinzuzufügen.
Schauen wir uns zunächst an, wie man einen gepunkteten Rahmen zeichnet, indem man die Maus gedrückt hält. Die Idee besteht darin, zunächst die Positionierung des Containerelements in „relativ“ zu ändern und dann zu bestimmen, wann die Maus gedrückt wird (Mousedown), um sich das zu merken Position des Klickpunkts (e.layerX, e.layerY) und überwachen Sie dann die Mausposition (e.layerX, e.layerY) in Echtzeit, wenn sich die Maus bewegt (mousemove). Mit diesen beiden Positionen können Sie dynamisch erstellen a p und seine Positionierung Für absolut, fügen Sie es dann dem Containerfeld hinzu und löschen Sie jedes Mal das vorherige Feld. Warum e.layerX e.layerY verwenden,
layerX layerY
Wenn der Positionsstil des Elements nicht der standardmäßige statische Stil ist, sagen wir Diese Elemente haben Positionierungsattribute.
Suchen Sie das nächstgelegene Element mit Positionierungsattribut zwischen dem Element, das derzeit das Mausereignis auslöst, und seinem Vorgängerelement, berechnen Sie den Versatzwert der Maus dazu und ermitteln Sie den diplomatischen Punkt der oberen linken Ecke der Grenze des Elements als relativer Punkt. Wenn kein Element mit einem Positionierungsattribut gefunden wird, wird der Offset relativ zur aktuellen Seite berechnet, was pageY entspricht. Befolgen Sie diese Idee, um den folgenden Code zu vervollständigen:
export default (Vue, options = {}) =>{ const listener = (ele, binding) =>{ let reactArea = { startX: 0, startY: 0, endX: 0, endY: 0 } //是否一直按下鼠标 let isMouseDown = false let areaSelect = {} //将元素定位改为relative ele.style.position = 'relative' ele.addEventListener('mousedown', function(e) { reactArea.startX = e.layerX; reactArea.startY = e.layerY; isMouseDown = true }) ele.addEventListener('mousemove', function(e) { if(isMouseDown){ let preArea = ele.getElementsByClassName('v-selected-area') if(preArea.length){ ele.removeChild(preArea[0]) } reactArea.endX = e.layerX reactArea.endY = e.layerY let leftValue = 0 let topValue = 0 let widthValue = Math.abs(reactArea.startX - reactArea.endX) let heightValue = Math.abs(reactArea.startY - reactArea.endY) if(reactArea.startX >= reactArea.endX){ leftValue = reactArea.endX }else{ leftValue = reactArea.startX } if(reactArea.startY > reactArea.endY ){ topValue = reactArea.endY }else{ topValue = reactArea.startY } //判断同时有宽高才开始画虚线框 if(reactArea.startX != reactArea.endX && reactArea.startY !=reactArea.endY){ areaSelect = document.createElement('p') areaSelect.classList.add("v-selected-area") areaSelect.style.position = "absolute"; areaSelect.style.left = leftValue + 'px' areaSelect.style.top = topValue + 'px' areaSelect.style.width = widthValue + 'px' areaSelect.style.height = heightValue + 'px' areaSelect.style.border = "1px dashed grey" ele.append(areaSelect) } } }) ele.addEventListener('mouseup', function(e) { isMouseDown = false //每次鼠标点击完了areaSelect if(areaSelect && areaSelect.childNodes && ele.contains(areaSelect)){ ele.removeChild(areaSelect) } areaSelect = null }) } Vue.directive('selectable',{ inserted:listener, updated:listener }) }
Zu diesem Zeitpunkt können Sie den Effekt des Zeichnens eines gepunkteten Rahmens erzielen
Der nächste Schritt Hier erfahren Sie, wie jedes Element ausgewählt wird. Die Idee besteht darin, alle untergeordneten Elemente li dieses Containers ul zu durchlaufen und dann zu bestimmen, ob sich jedes li innerhalb der ausgewählten Box befindet. Schauen Sie sich dann offsetLeft und offsetTop jedes Elements an, um die Position des Elements relativ zum übergeordneten Element zu berechnen, und bestimmen Sie dann die Breite und Höhe des untergeordneten Elements über getBoundingClientRect().height und getBoundingClientRect().width. Diese können die Position und Größe des Elements berechnen und dann feststellen, ob sich das Element innerhalb des Auswahlbereichs befindet. Meine Regel lautet: Wenn sich eine der vier Ecken dieses Elements innerhalb des Auswahlbereichs befindet oder der Auswahlbereich innerhalb dieses Bereichs liegt, gilt das Element als ausgewählt (diese Beurteilungsmethode fühlt sich nicht perfekt an). Folgen Sie dieser Idee und vervollständigen Sie unseren Code:
export default (Vue, options = {}) =>{ const listener = (ele, binding) =>{ let reactArea = { startX: 0, startY: 0, endX: 0, endY: 0 } //是否一直按下鼠标 let isMouseDown = false let areaSelect = {} //将元素定位改为relative ele.style.position = 'relative' ele.addEventListener('mousedown', function(e) { reactArea.startX = e.layerX; reactArea.startY = e.layerY; isMouseDown = true }) ele.addEventListener('mousemove', function(e) { if(isMouseDown){ let preArea = ele.getElementsByClassName('v-selected-area') if(preArea.length){ ele.removeChild(preArea[0]) } reactArea.endX = e.layerX reactArea.endY = e.layerY let leftValue = 0 let topValue = 0 let widthValue = Math.abs(reactArea.startX - reactArea.endX) let heightValue = Math.abs(reactArea.startY - reactArea.endY) if(reactArea.startX >= reactArea.endX){ leftValue = reactArea.endX }else{ leftValue = reactArea.startX } if(reactArea.startY > reactArea.endY ){ topValue = reactArea.endY }else{ topValue = reactArea.startY } //判断同时有宽高才开始画虚线框 if(reactArea.startX != reactArea.endX && reactArea.startY !=reactArea.endY){ areaSelect = document.createElement('p') areaSelect.classList.add("v-selected-area") areaSelect.style.position = "absolute"; areaSelect.style.left = leftValue + 'px' areaSelect.style.top = topValue + 'px' areaSelect.style.width = widthValue + 'px' areaSelect.style.height = heightValue + 'px' areaSelect.style.border = "1px dashed grey" ele.append(areaSelect) } let children = ele.getElementsByTagName('li') for(let i =0 ; i < children.length ; i ++ ){ let childrenHeight = children[i].getBoundingClientRect().height let childrenWidth = children[i].getBoundingClientRect().width //每个li元素的位置 let offsetLeft = children[i].offsetLeft let offsetTop = children[i].offsetTop //每个li元素的宽高 let endPositionH = childrenHeight + offsetTop let endPositionW = childrenWidth + offsetLeft //五个条件满足一个就可以判断被选择 //一是右下角在选择区域内 let require1 = endPositionH > topValue && endPositionW > leftValue && endPositionH < topValue + heightValue && endPositionW < leftValue + widthValue //二是左上角在选择区域内 let require2 = offsetTop > topValue && offsetLeft > leftValue && offsetTop < topValue + heightValue && offsetLeft < leftValue + widthValue //三是右上角在选择区域内 let require3 = offsetTop > topValue && offsetLeft + childrenWidth > leftValue && offsetTop < topValue + heightValue && offsetLeft + childrenWidth< leftValue + widthValue //四是左下角在选择区域内 let require4 = offsetTop + childrenHeight > topValue && offsetLeft > leftValue && offsetTop + childrenHeight < topValue + heightValue && offsetLeft < leftValue + widthValue //五选择区域在元素体内 let require5 = offsetTop < topValue && offsetLeft < leftValue && offsetTop + childrenHeight > topValue + heightValue && offsetLeft + childrenWidth > leftValue + widthValue if(require1 || require2 || require3 || require4 || require5){ children[i].classList.add('active') }else{ children[i].classList.remove('active') } } } }) ele.addEventListener('mouseup', function(e) { isMouseDown = false if(areaSelect && areaSelect.childNodes && ele.contains(areaSelect)){ ele.removeChild(areaSelect) } areaSelect = null }) } Vue.directive('selectable',{ inserted:listener, updated:listener }) }
Nach Abschluss sehen wir uns an, wie man ihn verwendet. HTML-Struktur:
<ul v-selectable > <li class="square"> item1 </li> <li class="oval"> item2 </li> <li class="triangle"> item3 </li> <li class="triangle-topleft"> item4 </li> <li class="curvedarrow"> item5 </li> <li class="triangle-topleft"> item6 </li> </ul>
Beachten Sie, dass die V-Auswahl von ul ist Unser benutzerdefinierter Befehl, aber Sie müssen Vue.use
import Vue from 'vue' import Selectable from '@/components/vue-selectable/vue-selectable.js' //这个修改为你的js路径 Vue.use(Selectable);
verwenden, bevor Sie ihn verwenden. Beachten Sie, dass unser ausgewähltes Element mit einer aktiven Klasse hinzugefügt wird, über die wir Änderungen vornehmen können der Stil des ausgewählten Artikels
<style scoped> ul{ margin: 40px 40px 40px 40px; border: 1px solid red; width: 300px; padding-bottom: 20px; } ul li { width: 200px; height: 30px; list-style: none; border: 1px solid black; margin-left: 10px; margin-top: 30px; text-align: center; line-height: 30px; user-select:none; } ul li.active{ background-color: red; } </style>
Auf diese Weise kann der Effekt am Anfang erzielt werden. Tatsächlich gibt es immer noch viele kleine Fehler im laufenden Code. Dieser Artikel bietet nur eine einfache Idee und Code. Sie können den Code selbst ändern und weitere Funktionen hinzufügen. Wenn Sie nicht verstehen, warum diese benutzerdefinierte Anweisung so geschrieben ist, können Sie meinen anderen Artikel zum Anpassen des Lazy-Loading-Image-Plug-Ins v-lazyload lesen.
Verwandte Empfehlungen:
Yii Framework-Entwicklungs-Tutorial Zii-Komponente – auswählbares Beispiel_PHP-Tutorial
Yii Framework-Entwicklungs-Tutorial Zii-Komponente – auswählbares Beispiel
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der benutzerdefinierten Vue-Anweisung v-selectable, ähnlich wie jQuery UI Selectable. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!