You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用原生JavaScript限制拖拽元素在指定容器Div内移动?

实现拖拽元素限制在指定容器内的原生JS方案

核心思路

要禁止拖拽元素移出.fill_in_the_gaps--container容器,关键要做到两点:

  • 仅允许容器内的合法目标区域(答案填空位、答案备选容器)接受拖拽放置
  • 容器外区域不响应拖拽放置操作,拖拽到外部时元素自动返回原位置

修改后的完整代码

JavaScript 部分

// const gapFillAnswers = ["goods & services","opportunities","water","sports car","tangible","intangible","entrepreneurs"];
const answerSpaces = document.querySelectorAll(".fill_in_the_gaps--answer_space");
const answerContainer = document.querySelector(".fill_in_the_gaps--answers_container");
const mainContainer = document.querySelector(".fill_in_the_gaps--container");
const answerWords = document.querySelectorAll(".fill_in_the_gaps--answers");

// 给合法区域绑定事件
answerContainer.addEventListener('drop', dropHandler);
answerContainer.addEventListener('dragover', dragOverHandler);

answerWords.forEach(element => {
    element.addEventListener('dragstart', dragStartHandler);
    element.addEventListener('dragend', dragEndHandler);
});

answerSpaces.forEach(element => {
    element.addEventListener('drop', dropHandler);
    element.addEventListener('dragover', dragOverHandler);
    element.addEventListener('dragenter', dragEnterHandler);
    element.addEventListener('dragleave', dragLeaveHandler);
});

// 给主容器绑定dragover,确保容器内空白区域可拖过
mainContainer.addEventListener('dragover', dragOverHandler);

// 全局阻止外部区域的drop默认行为,确保外部无法放置
document.addEventListener('dragover', (e) => {
    if (!mainContainer.contains(e.target)) {
        e.preventDefault();
    }
});

function dropHandler(e) {
    e.preventDefault();
    const elementId = e.dataTransfer.getData("text");
    const elementToDrop = document.getElementById(elementId);
    if (!elementToDrop) return;

    // 目标不在主容器内,直接返回,元素自动回原位
    if (!mainContainer.contains(e.target)) {
        return;
    }

    let target = e.target;
    // 处理拖到主容器空白处的情况,放回答案容器
    if (target === mainContainer) {
        answerContainer.append(elementToDrop);
        return;
    }

    // 处理答案填空位的放置逻辑
    if (target.classList.contains("fill_in_the_gaps--answer_space")) {
        target.style.border = "none";
        // 如果填空位已有元素,先将其放回答案容器
        if (target.firstChild) {
            answerContainer.append(target.firstChild);
        }
        target.append(elementToDrop);
    } 
    // 处理答案容器的放置逻辑
    else if (target.classList.contains("fill_in_the_gaps--answers_container")) {
        target.append(elementToDrop);
    }
}

function dragOverHandler(e) {
    e.preventDefault();  
}

function dragStartHandler(e) {
    e.target.style.opacity = "0.5";
    e.dataTransfer.setData("text", e.target.getAttribute("id"));
}

function dragEndHandler(e) {
    e.target.style.opacity = "1";
}

function dragEnterHandler(e) {
    e.target.style.border = "2px dotted green";
}

function dragLeaveHandler(e) {
    e.target.style.border = "none";
}

CSS 部分(保留原样式)

*{
    box-sizing: border-box;
}

:root{
    --blue: #000724;
    --pink: #DC398D;
    --yellow:#FEBD31;
    --green:#36F906;
}

body{
    background-color: var(--blue);
}

.fill_in_the_gaps--container{
    padding: 1rem;
    border-radius: 0.5rem;
    border-color: var(--pink);
    border-width: 5px;
    border-style: solid;
    background-color: whitesmoke;
}

.fill_in_the_gaps--answers_container{
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
    overflow-y: scroll;
    padding: 1rem;
    border:2px dotted gray;
}

.fill_in_the_gaps--answers{
    display: inline-block;  
    white-space:nowrap;
    margin-left: 15px;
    margin-right: 15px; 
}

.fill_in_the_gaps--answer_space{
    display: inline-block;
    background-color: var(--yellow);
    width:8rem;
    height: 1rem;
    margin-top: 2px;
    margin-left: 2px;
    margin-right: 2px;;
    text-align: center;
    padding-bottom:2px;
    vertical-align:middle;
}

HTML 部分(保留原结构)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽填空游戏</title>
    <script src="app.js" defer></script>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div data-board="aqa" data-level="gcse" data-subject="business" data-unit="1.1" data-type="fill_in_the_gaps" class="fill_in_the_gaps--container">
        <p class="fill_in_the_gaps--main_text">
            A business is an organisation that produces<span id="answer_space_0" class="fill_in_the_gaps--answer_space"></span>.Often businesses are setup to take advantage of business
            <span id="answer_space_1" class="fill_in_the_gaps--answer_space"></span>. Many businessess sell items that people need, some businesses sell items that people want. An example of a need is 
            <span id="answer_space_2" class="fill_in_the_gaps--answer_space"></span>. An example of a want is a <span id="answer_space_3" class="fill_in_the_gaps--answer_space"></span>. Goods are an example of 
            <span id="answer_space_4" class="fill_in_the_gaps--answer_space"></span>items. Services are an example of <span id="answer_space_5" class="fill_in_the_gaps--answer_space"></span>items. People who start up a business are known as 
            <span id="answer_space_6" class="fill_in_the_gaps--answer_space"></span>their reward for taking a risk is profit.
        </p>
        <div class="fill_in_the_gaps--answers_container">
            <span id="answer_0" draggable="true" class="fill_in_the_gaps--answers">goods & services</span>
            <span id="answer_1" draggable="true" class="fill_in_the_gaps--answers">opportunities</span>
            <span id="answer_2" draggable="true" class="fill_in_the_gaps--answers">water</span>
            <span id="answer_3" draggable="true" class="fill_in_the_gaps--answers">sports car</span>
            <span id="answer_4" draggable="true" class="fill_in_the_gaps--answers">tangible</span>
            <span id="answer_5" draggable="true" class="fill_in_the_gaps--answers">intangible</span>
            <span id="answer_6" draggable="true" class="fill_in_the_gaps--answers">entrepreneurs</span>
        </div>
    </div>
</body>
</html>

关键修改点说明

  1. 添加主容器引用:获取.fill_in_the_gaps--container元素,用于后续判断目标区域是否在容器内
  2. 全局拖拽事件控制:给document绑定dragover事件,阻止容器外区域的默认拖拽行为,确保外部无法接受放置
  3. 完善放置逻辑:
    • 检查放置目标是否在主容器内,不在则直接返回,元素自动回到原位置
    • 处理拖到容器空白处的情况,将元素放回答案备选容器
    • 增加填空位的元素替换逻辑,避免一个空位放多个元素

内容的提问来源于stack exchange,提问作者jon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 02:54:51