【问题标题】:HTML - Reproducing and applying unique ID's for a <div> within a <div>HTML - 为 <div> 中的 <div> 复制和应用唯一 ID
【发布时间】:2018-12-21 19:41:33
【问题描述】:

我创建了一个 ID 为“Card”的自定义 div 项。

卡片还有另一个 ID 为“可折叠”的 div,其中包含需要可折叠 ID 的自定义文本。

卡片和可折叠卡片都需要自己的自定义 ID,因为我想根据要求复制“卡片”项目并使其正常运行。

老实说,我对此完全陌生,所以我很难让它按要求工作。

我目前正在使用以下 JS 代码来生成一个新的“卡片”元素:

var myDiv = document.getElementById("Card");
document.body.appendChild(myDiv.cloneNode(true));
document.body.appendChild(myDiv.cloneNode(true));

问题在于,即使“卡片”正确复制,“可折叠”不是,它仍然指的是以前的“可折叠”对象。如果我手动重命名每个卡片元素中的“可折叠”ID,它就可以工作。谁能指出我正确的方向?

我研究过的所有内容都指向我使用某种 Javascript 函数,但我没有产生关于如何将自定义 ID 应用于另一个 DIV 中的 DIV 以及如何引用这些唯一 ID 的结果。

如果其中有任何令人困惑的地方,请告诉我,我会尽力消除任何误解。谢谢大家!

var myDiv = document.getElementById("Card");

document.body.appendChild(myDiv.cloneNode(true));
document.body.appendChild(myDiv.cloneNode(true));
.wrap-collabsible {
  /* Controls the base label's size and appearance */
  margin-bottom: 1.2rem 0;
  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.65) 70%, rgba(0, 0, 0, 0.9) 100%), url("https://help.opera.com/wp-content/uploads/sites/2/2018/03/Help_thumb_security@1x.png");
  height: 200px;
  width: 300px;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  border-radius: 15px;
  position: relative;
  
}

input[type='checkbox'] {
  /* Checkbox flags and enables content from CSS */
  display: none;
}

.lbl-toggle {
  /* Controls the "More Info" label */
  display: block;
  width: 100%;
  height: 100%;
  font-weight: bold;
  font-family: monospace;
  font-size: 1.2rem;
  text-transform: uppercase;
  position: relative;
  bottom: 5px;
  right: 5px;
  text-align: bottom;
  color: #FFFFFF;
  cursor: pointer;
  border-radius: 7px;
  transition: all .25s ease-out;
}

.lbl-toggle:hover {
  /* Changes color of labels if mouse hovers */
  color: #808080;
}

.lbl-toggle::before {
  /* Arrow location, size, and base transformation */
  content: ' ';
  
  position: absolute;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 5px solid currentColor;
  vertical-align: bottom;
  margin-right: 0.5rem;
  transform: translateY(-2px);
  transition: transform .2s ease-out;
  bottom: 11px;
  right: 105px;
  text-align: right;
}

.toggle:checked+.lbl-toggle::before {
  /* Rotates the arrow. */
  transform: rotate(180deg) translateX(-3px) translateY(2px);
}

.collapsible-content {
  width: 0px;
  overflow: hidden;
  transition: width .5s ease-in-out;
  
  position: absolute;
  left: 290px;
  top: 0px;
  z-index:-1;
}

.toggle:checked+.lbl-toggle+.collapsible-content {
  width: 400px;
}

.toggle:checked+.lbl-toggle {
  border-top-right-radius: 0px;
  border-bottom-right-radius: 0px;
}

.collapsible-content .content-inner {
  /* Controls the Content inside the popup */
  height: 183px;
  background: rgb(128, 128, 128);
  background-image: linear-gradient(to right, rgba(128, 128, 128), rgba(50, 50, 50));
  border-bottom: 1px solid rgba(250, 224, 66, .45);
  border-top-right-radius: 7px;
  border-bottom-right-radius: 7px;
  padding: 0.5rem 1rem;
  padding-left: 30px;
  box-shadow: inset 0 0 15px #000000;
  
}

.bottomright {
  /* Positions any text to the bottom right */
  position: absolute;
  bottom: 8px;
  right: 16px;
  font-size: 18px;
}
<div id="Card" class="wrap-collabsible">
  <input id="collapsible" class="toggle" type="checkbox">
  <label for="collapsible" class="lbl-toggle"> 
      <div class="bottomright">
        More Info
      </div>
    </label>
  <div class="collapsible-content">
    <div class="content-inner">
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
      </p>
    </div>
  </div>
</div>

【问题讨论】:

  • Card 和 Collapsible 都需要自己的自定义 ID,因为我希望能够根据请求复制“Card”项目并使其正常运行。 这是一个常见的问题为 JavaScript 新手准备的方法,因为 ids 很容易让你理解,但是一旦你遇到像你这样的用例,你就会开始看到 ids 的使用是多么脆弱。不要使用它们。相反,这可以通过依赖 CSS 类和 DOM 中的元素分层位置来更简单地解决

标签: javascript jquery html css


【解决方案1】:

你可以做的是克隆节点并给它一个新的ID,然后附加它。像这样的:

var myDiv = document.getElementById("Card");
var clone = myDiv.cloneNode(true);
clone.id = "UniqueId";
document.body.appendChild(clone);

【讨论】:

    【解决方案2】:

    如果我理解正确,你可能想要这样的东西:

    function createCard(id) {
      const card = document.getElementById('card-prototype').cloneNode(true);
      card.id = `card-${id}`;
      return card;
    }
    
    [ createCard(1),
      createCard(2),
      createCard(3),
      createCard(4) ].forEach(card => {
        document.getElementById('cards-container').appendChild(card);
      });
    #card-1 {
      color: red;
    }
    #card-2 {
      color: green;
    }
    #card-3 {
      color: blue;
    }
    #card-4 {
      color: purple;
    }
    <div id="card-prototype">
      <div id="card-collapsible-prototype">
        This is a collapisble.
      </div>
      This is a card.
    </div>
    
    <div id="cards-container"></div>

    上面的代码会复制卡片并改变id。

    【讨论】:

      【解决方案3】:

      在追加之前更改labels 和checkbox 元素id 属性的for 属性! 这应该有效:

      var myDiv = document.getElementById("Card");
      var n=5
      
      for(i=2;i<=n;i++){
        node=myDiv.cloneNode(true)
        node.children[0].id="collapsible"+i
        node.children[1].setAttribute("for","collapsible"+i)
        document.body.appendChild(node);
      }
      .wrap-collabsible {
        /* Controls the base label's size and appearance */
        margin-bottom: 1.2rem 0;
        background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.65) 70%, rgba(0, 0, 0, 0.9) 100%), url("https://help.opera.com/wp-content/uploads/sites/2/2018/03/Help_thumb_security@1x.png");
        height: 200px;
        width: 300px;
        background-repeat: no-repeat;
        background-size: cover;
        background-position: center;
        border-radius: 15px;
        position: relative;
        
      }
      
      input[type='checkbox'] {
        /* Checkbox flags and enables content from CSS */
        display: none;
      }
      
      .lbl-toggle {
        /* Controls the "More Info" label */
        display: block;
        width: 100%;
        height: 100%;
        font-weight: bold;
        font-family: monospace;
        font-size: 1.2rem;
        text-transform: uppercase;
        position: relative;
        bottom: 5px;
        right: 5px;
        text-align: bottom;
        color: #FFFFFF;
        cursor: pointer;
        border-radius: 7px;
        transition: all .25s ease-out;
      }
      
      .lbl-toggle:hover {
        /* Changes color of labels if mouse hovers */
        color: #808080;
      }
      
      .lbl-toggle::before {
        /* Arrow location, size, and base transformation */
        content: ' ';
        
        position: absolute;
        border-top: 5px solid transparent;
        border-bottom: 5px solid transparent;
        border-left: 5px solid currentColor;
        vertical-align: bottom;
        margin-right: 0.5rem;
        transform: translateY(-2px);
        transition: transform .2s ease-out;
        bottom: 11px;
        right: 105px;
        text-align: right;
      }
      
      .toggle:checked+.lbl-toggle::before {
        /* Rotates the arrow. */
        transform: rotate(180deg) translateX(-3px) translateY(2px);
      }
      
      .collapsible-content {
        width: 0px;
        overflow: hidden;
        transition: width .5s ease-in-out;
        
        position: absolute;
        left: 290px;
        top: 0px;
        z-index:-1;
      }
      
      .toggle:checked+.lbl-toggle+.collapsible-content {
        width: 400px;
      }
      
      .toggle:checked+.lbl-toggle {
        border-top-right-radius: 0px;
        border-bottom-right-radius: 0px;
      }
      
      .collapsible-content .content-inner {
        /* Controls the Content inside the popup */
        height: 183px;
        background: rgb(128, 128, 128);
        background-image: linear-gradient(to right, rgba(128, 128, 128), rgba(50, 50, 50));
        border-bottom: 1px solid rgba(250, 224, 66, .45);
        border-top-right-radius: 7px;
        border-bottom-right-radius: 7px;
        padding: 0.5rem 1rem;
        padding-left: 30px;
        box-shadow: inset 0 0 15px #000000;
        
      }
      
      .bottomright {
        /* Positions any text to the bottom right */
        position: absolute;
        bottom: 8px;
        right: 16px;
        font-size: 18px;
      }
      <div id="Card" class="wrap-collabsible">
        <input id="collapsible" class="toggle" type="checkbox">
        <label for="collapsible" class="lbl-toggle"> 
            <div class="bottomright">
              More Info
            </div>
          </label>
        <div class="collapsible-content">
          <div class="content-inner">
            <p>
              Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
            </p>
          </div>
        </div>
      </div>

      我希望这会有所帮助!

      【讨论】:

      • 抱歉这么久才回复!我查看了代码以及您在技术上的工作原理,但是我仍然需要添加 Collapsible2、Collapsible3 等,以便所有副本都能正常工作。如果我根据要求想要 n 份副本怎么办? IE。真的能够生成我想要/需要的尽可能多的副本吗?应该有一种方法可以做到这一点,我不应该制作n个“CollapsibleN”实体并且能够为它们生成ID......我最终希望将信息放入这些卡片中的每一张并将需要一种方法来定位他们。
      • @Tsiaris 我编辑了我的答案,现在只需更改 n 变量的值来设置卡片数量! (以n=5为例)
      猜你喜欢
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 2014-08-30
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多