每当我将鼠标悬停在按钮上时,都会弹出一个隐藏层,即一个充满文本的div,但是当我移动按钮的位置(可拖动)后,我将鼠标悬停在按钮上时,没有弹出窗口,但是当我将鼠标悬停在没有按钮的过去位置上,弹出窗口出现,表明该弹出窗口没有移动并且没有固定在按钮上,这不是我想要的。
这是 HTML
代码:
<div class="bgCSS">
<section>
<div class="pos1">
<div data-draggable="target">
<button data-draggable="item">
<font size="+3"> ☺ </font>
</button>
</div>
</div>
<div class="pos2">
<div data-draggable="target">
</div>
</div>
data-draggable =“ target” 就像一个放置按钮的插槽,该按钮将归类为 data-draggable =“ item”
这是分配给按钮的div的 html
代码,只要悬停按钮,就会显示该代码:
<div class="layer55">
<h3> 1 </h3>
</div>
<div class="layer56">
<h3> 2 </h3>
</div>
只要将pos1的按钮悬停在pos2上,将显示第55层,
这是 pos1 和 pos2 的 CSS
代码:
section .pos1 {
position: absolute;
transform: translate(-50%, -50%);
z-index: 1;
top: 6.25%;
left: 30%;
}
section .pos2 {
position: absolute;
top: 6.25%;
left: 40%;
transform: translate(-50%, -50%);
z-index: 1;
}
// Don't mind the section, that's all good to go.
这是与悬停效果有关的 CSS
,我不知道这件事是否重要,仅供您参考:
section:hover button {
filter: blur(5px);
transition: all 0.05s ease-in-out;
}
section button:hover {
transition: background 0.25s;
filter: blur(0px);
box-shadow: 3px 5px 5px white;
border-radius: 7px;
background-color: #4d2800;
}
这是 layer55 和 layer56 的 CSS
:
section .layer55 {
position: fixed;
top: 20.5%;
left: 82.5%;
transform: translate(-50%, -50%);
width: 400px;
height: 235px;
border-radius: 10px;
border: 2px solid #d9f4f5;
background: rgb(232, 227, 240);
background-position: center;
z-index: 1;
visibility: hidden;
}
section .layer56 {
position: fixed;
top: 20.5%;
left: 82.5%;
transform: translate(-50%, -50%);
width: 400px;
height: 235px;
border-radius: 10px;
border: 2px solid #d9f4f5;
background: rgb(232, 227, 240);
background-position: center;
z-index: 1;
visibility: hidden;
}
这是 CSS
,用于将 pos1 和 pos2 上的按钮连接到 layer55 和< strong> layer56 分别:
.pos1:hover ~ .layer55 {
visibility: visible;
transition-delay: all 0.25s ease-in-out;
}
.pos2:hover ~ .layer56 {
visibility: visible;
transition-delay: all 0.25s ease-in-out;
}
最后,拖曳零件的 CSS
代码,我也不知道这是否也很重要:
[data-draggable="target"][aria-dropeffect="move"]
{
border-color:#68b;
background:#fff;
}
/* drop target focus and dragover state */
[data-draggable="target"][aria-dropeffect="move"]:focus,
[data-draggable="target"][aria-dropeffect="move"].dragover
{
outline:none;
box-shadow:0 0 0 1px #fff, 0 0 0 3px #68b;
}
/* draggable items */
[data-draggable="item"]
{
background-color: rgba(22, 19, 19, 1);
background-position: center;
display:block;
list-style-type:none;
width:135px;
height:40px;
}
/* items focus state */
[data-draggable="item"]:focus
{
outline:none;
box-shadow:0 0 0 2px #68b, inset 0 0 0 1px #ddd;
}
/* items grabbed state */
[data-draggable="item"][aria-grabbed="true"]
{
background: grey;
color:#fff;
}
这是 JS
代码,供您参考:
(function()
{
//exclude older browsers by the features we need them to support
//and legacy opera explicitly so we don't waste time on a dead browser
if
(
!document.querySelectorAll
||
!('draggable' in document.createElement('span'))
||
window.opera
)
{ return; }
//get the collection of draggable targets and add their draggable attribute
for(var
targets = document.querySelectorAll('[data-draggable="target"]'),
len = targets.length,
i = 0; i < len; i ++)
{
targets[i].setAttribute('aria-dropeffect', 'none');
}
//get the collection of draggable items and add their draggable attributes
for(var
items = document.querySelectorAll('[data-draggable="item"]'),
len = items.length,
i = 0; i < len; i ++)
{
items[i].setAttribute('draggable', 'true');
items[i].setAttribute('aria-grabbed', 'false');
items[i].setAttribute('tabindex', '0');
}
//dictionary for storing the selections data
//comprising an array of the currently selected items
//a reference to the selected items' owning container
//and a refernce to the current drop target container
var selections =
{
items : [],
owner : null,
droptarget : null
};
//function for selecting an item
function addSelection(item)
{
//if the owner reference is still null, set it to this item's parent
//so that further selection is only allowed within the same container
if(!selections.owner)
{
selections.owner = item.parentNode;
}
//or if that's already happened then compare it with this item's parent
//and if they're not the same container, return to prevent selection
else if(selections.owner != item.parentNode)
{
return;
}
//set this item's grabbed state
item.setAttribute('aria-grabbed', 'true');
//add it to the items array
selections.items.push(item);
}
//function for unselecting an item
function removeSelection(item)
{
//reset this item's grabbed state
item.setAttribute('aria-grabbed', 'false');
//then find and remove this item from the existing items array
for(var len = selections.items.length, i = 0; i < len; i ++)
{
if(selections.items[i] == item)
{
selections.items.splice(i, 1);
break;
}
}
}
//function for resetting all selections
function clearSelections()
{
//if we have any selected items
if(selections.items.length)
{
//reset the owner reference
selections.owner = null;
//reset the grabbed state on every selected item
for(var len = selections.items.length, i = 0; i < len; i ++)
{
selections.items[i].setAttribute('aria-grabbed', 'false');
}
//then reset the items array
selections.items = [];
}
}
//shorctut function for testing whether a selection modifier is pressed
function hasModifier(e)
{
return (e.ctrlKey || e.metaKey || e.shiftKey);
}
//function for applying dropeffect to the target containers
function addDropeffects()
{
//apply aria-dropeffect and tabindex to all targets apart from the owner
for(var len = targets.length, i = 0; i < len; i ++)
{
if
(
targets[i] != selections.owner
&&
targets[i].getAttribute('aria-dropeffect') == 'none'
)
{
targets[i].setAttribute('aria-dropeffect', 'move');
targets[i].setAttribute('tabindex', '0');
}
}
//remove aria-grabbed and tabindex from all items inside those containers
for(var len = items.length, i = 0; i < len; i ++)
{
if
(
items[i].parentNode != selections.owner
&&
items[i].getAttribute('aria-grabbed')
)
{
items[i].removeAttribute('aria-grabbed');
items[i].removeAttribute('tabindex');
}
}
}
//function for removing dropeffect from the target containers
function clearDropeffects()
{
//if we have any selected items
if(selections.items.length)
{
//reset aria-dropeffect and remove tabindex from all targets
for(var len = targets.length, i = 0; i < len; i ++)
{
if(targets[i].getAttribute('aria-dropeffect') != 'none')
{
targets[i].setAttribute('aria-dropeffect', 'none');
targets[i].removeAttribute('tabindex');
}
}
//restore aria-grabbed and tabindex to all selectable items
//without changing the grabbed value of any existing selected items
for(var len = items.length, i = 0; i < len; i ++)
{
if(!items[i].getAttribute('aria-grabbed'))
{
items[i].setAttribute('aria-grabbed', 'false');
items[i].setAttribute('tabindex', '0');
}
else if(items[i].getAttribute('aria-grabbed') == 'true')
{
items[i].setAttribute('tabindex', '0');
}
}
}
}
//shortcut function for identifying an event element's target container
function getContainer(element)
{
do
{
if(element.nodeType == 1 && element.getAttribute('aria-dropeffect'))
{
return element;
}
}
while(element = element.parentNode);
return null;
}
//mousedown event to implement single selection
document.addEventListener('mousedown', function(e)
{
//if the element is a draggable item
if(e.target.getAttribute('draggable'))
{
//clear dropeffect from the target containers
clearDropeffects();
//if the multiple selection modifier is not pressed
//and the item's grabbed state is currently false
if
(
!hasModifier(e)
&&
e.target.getAttribute('aria-grabbed') == 'false'
)
{
//clear all existing selections
clearSelections();
//then add this new selection
addSelection(e.target);
}
}
//else [if the element is anything else]
//and the selection modifier is not pressed
else if(!hasModifier(e))
{
//clear dropeffect from the target containers
clearDropeffects();
//clear all existing selections
clearSelections();
}
//else [if the element is anything else and the modifier is pressed]
else
{
//clear dropeffect from the target containers
clearDropeffects();
}
}, false);
//mouseup event to implement multiple selection
document.addEventListener('mouseup', function(e)
{
//if the element is a draggable item
//and the multipler selection modifier is pressed
if(e.target.getAttribute('draggable') && hasModifier(e))
{
//if the item's grabbed state is currently true
if(e.target.getAttribute('aria-grabbed') == 'true')
{
//unselect this item
removeSelection(e.target);
//if that was the only selected item
//then reset the owner container reference
if(!selections.items.length)
{
selections.owner = null;
}
}
//else [if the item's grabbed state is false]
else
{
//add this additional selection
addSelection(e.target);
}
}
}, false);
//dragstart event to initiate mouse dragging
document.addEventListener('dragstart', function(e)
{
//if the element's parent is not the owner, then block this event
if(selections.owner != e.target.parentNode)
{
e.preventDefault();
return;
}
//[else] if the multiple selection modifier is pressed
//and the item's grabbed state is currently false
if
(
hasModifier(e)
&&
e.target.getAttribute('aria-grabbed') == 'false'
)
{
//add this additional selection
addSelection(e.target);
}
//we don't need the transfer data, but we have to define something
//otherwise the drop action won't work at all in firefox
//most browsers support the proper mime-type syntax, eg. "text/plain"
//but we have to use this incorrect syntax for the benefit of IE10+
e.dataTransfer.setData('text', '');
//apply dropeffect to the target containers
addDropeffects();
}, false);
//keydown event to implement selection and abort
document.addEventListener('keydown', function(e)
{
//if the element is a grabbable item
if(e.target.getAttribute('aria-grabbed'))
{
//Space is the selection or unselection keystroke
if(e.keyCode == 32)
{
//if the multiple selection modifier is pressed
if(hasModifier(e))
{
//if the item's grabbed state is currently true
if(e.target.getAttribute('aria-grabbed') == 'true')
{
//if this is the only selected item, clear dropeffect
//from the target containers, which we must do first
//in case subsequent unselection sets owner to null
if(selections.items.length == 1)
{
clearDropeffects();
}
//unselect this item
removeSelection(e.target);
//if we have any selections
//apply dropeffect to the target containers,
//in case earlier selections were made by mouse
if(selections.items.length)
{
addDropeffects();
}
//if that was the only selected item
//then reset the owner container reference
if(!selections.items.length)
{
selections.owner = null;
}
}
//else [if its grabbed state is currently false]
else
{
//add this additional selection
addSelection(e.target);
//apply dropeffect to the target containers
addDropeffects();
}
}
//else [if the multiple selection modifier is not pressed]
//and the item's grabbed state is currently false
else if(e.target.getAttribute('aria-grabbed') == 'false')
{
//clear dropeffect from the target containers
clearDropeffects();
//clear all existing selections
clearSelections();
//add this new selection
addSelection(e.target);
//apply dropeffect to the target containers
addDropeffects();
}
//else [if modifier is not pressed and grabbed is already true]
else
{
//apply dropeffect to the target containers
addDropeffects();
}
//then prevent default to avoid any conflict with native actions
e.preventDefault();
}
//Modifier + M is the end-of-selection keystroke
if(e.keyCode == 77 && hasModifier(e))
{
//if we have any selected items
if(selections.items.length)
{
//apply dropeffect to the target containers
//in case earlier selections were made by mouse
addDropeffects();
//if the owner container is the last one, focus the first one
if(selections.owner == targets[targets.length - 1])
{
targets[0].focus();
}
//else [if it's not the last one], find and focus the next one
else
{
for(var len = targets.length, i = 0; i < len; i ++)
{
if(selections.owner == targets[i])
{
targets[i + 1].focus();
break;
}
}
}
}
//then prevent default to avoid any conflict with native actions
e.preventDefault();
}
}
//Escape is the abort keystroke (for any target element)
if(e.keyCode == 27)
{
//if we have any selected items
if(selections.items.length)
{
//clear dropeffect from the target containers
clearDropeffects();
//then set focus back on the last item that was selected, which is
//necessary because we've removed tabindex from the current focus
selections.items[selections.items.length - 1].focus();
//clear all existing selections
clearSelections();
//but don't prevent default so that native actions can still occur
}
}
}, false);
//related variable is needed to maintain a reference to the
//dragleave's relatedTarget, since it doesn't have e.relatedTarget
var related = null;
//dragenter event to set that variable
document.addEventListener('dragenter', function(e)
{
related = e.target;
}, false);
//dragleave event to maintain target highlighting using that variable
document.addEventListener('dragleave', function(e)
{
//get a drop target reference from the relatedTarget
var droptarget = getContainer(related);
//if the target is the owner then it's not a valid drop target
if(droptarget == selections.owner)
{
droptarget = null;
}
//if the drop target is different from the last stored reference
//(or we have one of those references but not the other one)
if(droptarget != selections.droptarget)
{
//if we have a saved reference, clear its existing dragover class
if(selections.droptarget)
{
selections.droptarget.className =
selections.droptarget.className.replace(/ dragover/g, '');
}
//apply the dragover class to the new drop target reference
if(droptarget)
{
droptarget.className += ' dragover';
}
//then save that reference for next time
selections.droptarget = droptarget;
}
}, false);
//dragover event to allow the drag by preventing its default
document.addEventListener('dragover', function(e)
{
//if we have any selected items, allow them to be dragged
if(selections.items.length)
{
e.preventDefault();
}
}, false);
//dragend event to implement items being validly dropped into targets,
//or invalidly dropped elsewhere, and to clean-up the interface either way
document.addEventListener('dragend', function(e)
{
//if we have a valid drop target reference
//(which implies that we have some selected items)
if(selections.droptarget)
{
//append the selected items to the end of the target container
for(var len = selections.items.length, i = 0; i < len; i ++)
{
selections.droptarget.appendChild(selections.items[i]);
}
//prevent default to allow the action
e.preventDefault();
}
//if we have any selected items
if(selections.items.length)
{
//clear dropeffect from the target containers
clearDropeffects();
//if we have a valid drop target reference
if(selections.droptarget)
{
//reset the selections array
clearSelections();
//reset the target's dragover class
selections.droptarget.className =
selections.droptarget.className.replace(/ dragover/g, '');
//reset the target reference
selections.droptarget = null;
}
}
}, false);
//keydown event to implement items being dropped into targets
document.addEventListener('keydown', function(e)
{
//if the element is a drop target container
if(e.target.getAttribute('aria-dropeffect'))
{
//Enter or Modifier + M is the drop keystroke
if(e.keyCode == 13 || (e.keyCode == 77 && hasModifier(e)))
{
//append the selected items to the end of the target container
for(var len = selections.items.length, i = 0; i < len; i ++)
{
e.target.appendChild(selections.items[i]);
}
//clear dropeffect from the target containers
clearDropeffects();
//then set focus back on the last item that was selected, which is
//necessary because we've removed tabindex from the current focus
selections.items[selections.items.length - 1].focus();
//reset the selections array
clearSelections();
//prevent default to to avoid any conflict with native actions
e.preventDefault();
}
}
}, false);
})();