使用 Javascript 将图像拖放到无序列表中

Using Javascript to drag-and-drop an image into an unordered list

所以,我被警告说我过去的一些问题没有得到很好的回应,而且我有被禁止再提问的危险。我希望这个问题得到很好的接受,并且不会导致我无法提出更多问题!我会尽最大努力将其表述为一个清晰且有用的问题。

我想做的是创建 javascript 以将图像单击并拖动到嵌套列表中。我读过 and How to drag and drop into an html unordered list,但都没有解决我想做的事情。

我要单击并拖动的图像代表项目——一些项目可以包含其他项目,而另一些则不能。例如,单管霰弹枪可以装霰弹枪弹药,但霰弹枪弹药不能装任何东西。

我创建了一个 jsfiddle,https://jsfiddle.net/pjamesnorris25/9f0y8edz/76/,以方便某些 javascript 向导帮助我完成此操作。因为我有,所以我不会 post 到 javascript 除非有人要求我这样做。

我的 javascript 如果您单击并拖动霰弹枪到“霰弹枪弹药”和“单管霰弹枪”图像下方普通人图像中的“左肩”,我的 javascript 就可以使用右上角。也就是说,当您这样做时,文本“Single Barrel Shotgun”会出现在“Left Shoulder”下方,由文本周围的框表示——该框表示“Single Barrel Shotgun”是一个容器,其中您可以拖动其他项目,在本例中为“Shotgun Ammo”。

在将“Single-Barrel Shotgun”图形拖到“Left Shoulder”容器之前,我的 HTML 看起来像这样:

<span id="leftshoulder-span" style="border:black solid 1px; left:387px; height:30px; width:173px; overflow:hidden; position:absolute; top:96px; " ondrop="drop(event)" ondragover="allowDrop(event)"></span>
<ul id="leftshoulder-ul" style="left:387px; position:absolute; top:126px; z-index:101; "></ul>

将“单管霰弹枪”拖到“左肩”后,HTML看起来像这样:

<ul id="leftshoulder-ul" style="left:387px; position:absolute; top:126px; z-index:101; ">
  <li id="Single_Barrel_Shotgun_1-li" style="margin-top:2px;">
    <span id="Single_Barrel_Shotgun_1-span" ondrop="drop(event)" ondragover="allowDrop(event)" style="border:1px solid black;">
      <div class="tooltip">
        Single Barrel Shotgun
        <span class="tooltipimage">
          <img src="https://i.postimg.cc/sGCvntKs/Single-Barrel-Shotgun.gif" id="Single_Barrel_Shotgun_1" class="zoom_small card" draggable="true" ondragstart="drag(event)">
        </span>
      </div>
    </span>
    <span id="Single_Barrel_Shotgun_1-contents-span" ondrop="drop(event)" ondragover="allowDrop(event)"></span>
    <ul id="Single_Barrel_Shotgun_1-ul"></ul>
  </li>
</ul>

这正是我想要的。但是当我将“Shotgun Ammo”图像拖到“Single Barrel Shotgun”文本时,我得到:

<ul id="leftshoulder-ul" style="left:387px; position:absolute; top:126px; z-index:101; ">
  <li id="Single_Barrel_Shotgun_1-li" style="margin-top:2px;">
    <span id="Single_Barrel_Shotgun_1-span" ondrop="drop(event)" ondragover="allowDrop(event)" style="border:1px solid black;">
      <div class="tooltip">
        Single Barrel Shotgun
        <span class="tooltipimage">
          <img src="https://i.postimg.cc/sGCvntKs/Single-Barrel-Shotgun.gif" id="Single_Barrel_Shotgun_1" class="zoom_small card" draggable="true" ondragstart="drag(event)">
        </span>
      </div>
    </span>
    <img id="Shotgun_Shell_4" class="zoom_small card" src="https://i.postimg.cc/N28LZpPT/Shotgun-Shell.gif" draggable="true" ondragstart="drag(event)">
    <span id="Single_Barrel_Shotgun_1-contents-span" ondrop="drop(event)" ondragover="allowDrop(event)"></span>
    <ul id="Single_Barrel_Shotgun_1-ul">
    </ul>
  </li>
</ul>

请注意 <img src="https://i.postimg.cc/sGCvntKs/Single-Barrel-Shotgun.gif" ...</span> 之后关闭 <span class="tooltipimage"> 而不是在 <li> 里面 <ul id="Single_Barrel_Shotgun_1-ul"></ul>.

也就是我要的是:

<ul id="leftshoulder-ul" style="left:387px; position:absolute; top:126px; z-index:101; ">
  <li id="Single_Barrel_Shotgun_1-li" style="margin-top:2px;">
    <span id="Single_Barrel_Shotgun_1-span" ondrop="drop(event)" ondragover="allowDrop(event)" style="border:1px solid black;">
      <div class="tooltip">
        Single Barrel Shotgun
        <span class="tooltipimage">
          <img src="https://i.postimg.cc/sGCvntKs/Single-Barrel-Shotgun.gif" id="Single_Barrel_Shotgun_1" class="zoom_small card" draggable="true" ondragstart="drag(event)">
        </span>
      </div>
    </span>
    <span id="Single_Barrel_Shotgun_1-contents-span" ondrop="drop(event)" ondragover="allowDrop(event)"></span>
    <ul id="Single_Barrel_Shotgun_1-ul">
      <li id="Shotgun_Shell_4-li" style="margin-top:2px;">
      <div class="tooltip">
        Shotgun Shell
        <span class="tooltipimage">
          <img src="https://i.postimg.cc/sGCvntKs/Shotgun-Shell.gif" id="Shotgun_Shell_4" class="zoom_small card">
        </span>
      </div>
    </ul>
  </li>
</ul>

让我大吃一惊的是 javascript 将“单管霰弹枪”作为无序列表项正确地放置在“左肩”下,但没有将“霰弹枪”放置 Shell ”作为“单管霰弹枪”下的无序列表项,当两者的 HTML 具有完全相同的结构时。也就是说,“左肩”有一个独特的 id'd <span> 后面跟着一个独特的 id'd <ul>:

<span id="leftshoulder-span" style="border:black solid 1px; left:387px; height:30px; width:173px; overflow:hidden; position:absolute; top:96px; " ondrop="drop(event)" ondragover="allowDrop(event)"></span>
<ul id="leftshoulder-ul" style="left:387px; position:absolute; top:126px; z-index:101; "></ul>

并且“单管霰弹枪”也有一个独特的 id' 后面跟着一个独特的 id'd :

    <span id="Single_Barrel_Shotgun_1-contents-span" ondrop="drop(event)" ondragover="allowDrop(event)"></span>
    <ul id="Single_Barrel_Shotgun_1-ul"></ul>

我内置了一些错误检查警报——由于某些原因它们在 jsfiddle 中不起作用;任何可以向我解释这一点的人都可以获得额外奖励。当我 运行 我机器上的代码时,当我第一次单击并将“单管霰弹枪”拖到“左肩”时,我得到以下信息:

这告诉我 javascript 正确识别了“单管霰弹枪”被拖到的 <span>leftshoulder-span,代码知道被扔进 leftshoulder <ul> 的“单管霰弹枪”的 id 是“Single_Barrel_Shotgun_1”(“_1”表示这是第一个可以拖动的“单管霰弹枪”,并且该物品是“单管霰弹枪”。

但是当我点击并拖动“Shotgun Ammo”时,我收到的错误检查警报是:

,因为 eve.target.id 告诉我代码无法识别应该将“Shotgun Ammo”作为 <ul id="Single_Barrel_Shotgun_1-ul"> 中的第一个 <li>

所以我的问题是:如何修改我的 javascript 以便当我单击并拖动“Shotgun Ammo”到“Single Barrel Shotgun”时它显示为无序列表项“单管霰弹枪”?或者换句话说,为什么当我将“Shotgun Ammo”单击并拖动到“Single Barrel Shotgun”时,我的错误检查警报中的 eve.target.id 为空白?

所以,我不确定我的推理是否正确,但我认为我的 javascript 没有工作的原因是它正在寻找 id inner-most span 我试图将“Shotgun Shell”拖到其中,:

<span class="tooltipimage">

没有 id

所以,我写 javascript 为 id="Single_Barrel_Shotgun_1-span" 的每个 divspan 女儿添加一个 id,如下所示:

    <span id="Single_Barrel_Shotgun_1-span" ondrop="drop(event)" ondragover="allowDrop(event)" style="border:1px solid black;">
      <div id="Single_Barrel_Shotgun_1-tooltip" class="tooltip">
        Single Barrel Shotgun
        <span id="Single_Barrel_Shotgun_1-tooltipimage" class="tooltipimage">
          <img src="https://i.postimg.cc/sGCvntKs/Single-Barrel-Shotgun.gif" id="Single_Barrel_Shotgun_1" class="zoom_small card" draggable="true" ondragstart="drag(event)">
        </span>
      </div>
    </span>

而且,你瞧,“Shotgun Shell”现在以我想要的方式显示为“Shotgun”下的无序列表项。

有效的 javascript 是:

        function addContentsSpan(str_possession)
        {
            var str_item = str_possession.replace(/[0-9]/g, "").replace(/_/g, " ").slice(0, -(" ".length));
            var str_possession_li = str_possession + "-li";
            var str_possession_span = str_possession + "-span";

            var ele_span = document.getElementById(str_possession_span);
            ele_span.setAttribute("id", str_possession_span);
            ele_span.setAttribute("ondrop", "drop(event)");
            ele_span.setAttribute("ondragover", "allowDrop(event)");
            ele_span.setAttribute("style", "border:1px solid black;");
            var ele_li = document.getElementById(str_possession_li);

            var ele_ul = document.createElement("ul");
            ele_ul.setAttribute("id", (str_possession + "-ul"));
            ele_li.appendChild(ele_ul);
            
        } // function addContentsSpan(str_possession_li)

        function allowDrop(eve) { eve.preventDefault(); }
        
        function drag(eve) 
        { 
            eve.dataTransfer.setData("text", eve.target.id);
            console.log(eve.target.id);
        }
        
        function drop(eve) 
        {
            bool_debug = false;

            // identify the item being moved
            var str_possession = eve.dataTransfer.getData("text");
            var str_container = eve.dataTransfer.setData("text", eve.target.id);
            var str_item = str_possession.replace(/_/g, " ").replace(/[0-9]/g, "").slice(0, -(" ".length));
                
            // drop the item in the container           
            if (eve.target.id.slice(-("-tooltip").length) == "-tooltip") { eve.target.id = eve.target.id.slice(0, -("-tooltip").length) + "-span"; }

            var str_item_parent = eve.target.id.slice(0, -("-span").length) + "-ul";
            
            var str_location = eve.target.id.slice(0, -("-span").length) + "-ul";
            var ele_location = document.getElementById(str_location);

            eve.preventDefault();
            eve.target.appendChild(document.getElementById(str_possession));

            var ele_li = document.createElement("li");
            ele_li.setAttribute("id", (str_possession + "-li"));
            ele_li.setAttribute("style", "margin-top:2px;");
            ele_location.appendChild(ele_li);

            var ele_divTooltip = document.createElement("div");
            ele_divTooltip.setAttribute("class", "tooltip");
            ele_divTooltip.setAttribute("id", (str_possession + "-tooltip"));

            var ele_spanDrop = document.createElement("span");
            ele_spanDrop.setAttribute("id", (str_possession + "-span"));
            ele_li.appendChild(ele_spanDrop);

            ele_divTooltip.textContent = str_item;
            ele_spanDrop.appendChild(ele_divTooltip);

            var ele_spanTooltipImage = document.createElement("span");
            ele_spanTooltipImage.setAttribute("id", str_possession + "-tooltipimage");
            ele_spanTooltipImage.setAttribute("class", "tooltipimage");
            ele_divTooltip.appendChild(ele_spanTooltipImage);

            var ele_image = document.createElement("img");
            ele_image.setAttribute("src", ("img/cards/items/" + str_item + ".gif"));
            ele_image.setAttribute("id", str_possession);
            ele_image.setAttribute("class", "zoom_small card");
            ele_image.setAttribute("draggable", "true");
            ele_image.setAttribute("ondragstart", "drag(event)");
            ele_spanTooltipImage.appendChild(ele_image);
            
            // remove the item from "Possessions"
            document.getElementById(str_possession).remove()
            
            // remove item from previous container
            if (bool_debug) { alert("line " + 1366 + ":\n" + "str_item_parent = " + str_item_parent + "\n" + "possession list element = " + str_possession + "-li"); }
            if (str_item_parent.slice(-("-ul")) == "-ul") { document.getElementById(str_item_parent).removeChild(str_possession + "-li"); }
                        
            // update the Solo_Possession table with the new item
            str_target_id = eve.target.id;
            if (bool_debug) { alert("line " + 1371 +": str_target_id = \"" + str_target_id + "\"\n" + "str_possession = " + str_possession); }
            
            insertItem(str_possession);
            
            if (arr_space[str_item]['space'] > 0) { addContentsSpan(str_possession); }
            
            eve.dataTransfer.clearData();
                    
        } // function drop(eve)