首页 > 解决方案 > 如何将元素拆分为两个可连续的部分并在它们之间添加另一个元素

问题描述

可以将 html 元素按特定高度拆分为两个可连续的部分,并使用 javascript 自动在它们之间添加另一个元素,例如将图像拆分为两个部分并在它们之间添加其他图像。

例子 :

p {
  width: 300px;
}

.original-div {
  border: 1px solid black;
}

.div1 {
  border-bottom: none;
}

.div1 p {
  margin-bottom: 0;
}

.div2 {
  border-top: none;
}

.div2 p {
  margin-top: 0;
}

.new-elem {
  font-weight: bold;
  border: 2px solid red;
  background-color: blue;
  color: white;
}
<strong>Original</strong>
<hr/>
<div class="original-div">
  <p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
    survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
    software like Aldus PageMaker including versions of Lorem Ipsum.
  </p>
</div>
<br/>
<strong>Output</strong>
<hr/>
<div class="original-div div1">
  <p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen
  </p>
</div>
<div class="new-elem">
  INSERTED ELEMENT
</div>
<div class="original-div div2">
  <p>
    book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with
    desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  </p>
</div>

标签: javascriptjqueryhtmlcss

解决方案


这是一个可以帮助您入门的草稿。请务必检查解决方案中的所有不变量(移动绿色滑块):

function splitInsert(element, percentage, sibling) {
  let rect = element.getBoundingClientRect(); 
  let clone = element.cloneNode(true);
  let parent = element.parentNode;
  let inserted = parent.insertBefore(clone, element);
  
  let a_len = element.textContent.length * percentage;
  
  //should check invariants here
  //backup until word boundary
  let i = a_len - 1;
  while (i > 1 && !/\s/.test( inserted.textContent.charAt(i) )) {
    i--;
  }
  inserted.textContent = inserted.textContent.substring(0, i);
  element.textContent = element.textContent.substring(i);
  
  element.style.height  = rect.height * (1 - percentage) + 'px';
  inserted.style.height = rect.height * percentage + 'px';
  parent.insertBefore(sibling, element);
}

let p = document.querySelector('p');
let org_tc = p.textContent;
let org = p.cloneNode(true);
let new_p = document.createElement('p');
new_p.textContent = 'hello, world';
new_p.className = 'new-elem';

splitInsert(p, 0.05, new_p);

function reset() {
  let target = document.querySelector('.original-div');
  while (target.firstChild)
    target.removeChild(target.firstChild);
  org.textContent = org_tc;
  target.innerHTML = `
  <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
  `;
}
let slider = document.querySelector('input[type="range"]');
slider.onchange = function (event) {
  reset();
  let p = document.querySelector('p');
  splitInsert(p, event.target.value / 100, new_p);
};
p {
  width: 300px;
}

.original-div {
  border: 1px solid black;
}

.div1 {
  border-bottom: none;
}

.div1 p {
  margin-bottom: 0;
}

.div2 {
  border-top: none;
}

.div2 p {
  margin-top: 0;
}

.new-elem {
  font-weight: bold;
  border: 2px solid red;
  background-color: blue;
  color: white;
}
<div style="background-color: green">
<input type="range" min="1" max="100" value="1" step="1">
</div>
<strong>Original</strong>
<hr/>
<div class="original-div">
  <p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
    survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
    software like Aldus PageMaker including versions of Lorem Ipsum.
  </p>
</div>
<br/>
<strong>Output</strong>
<hr/>
<div class="original-div div1">
  <p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen
  </p>
</div>
<div class="new-elem">
  INSERTED ELEMENT
</div>
<div class="original-div div2">
  <p>
    book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with
    desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  </p>
</div>

  1. 分配高度
  2. 分配文本内容
    1. 确定文本分配规则(标点符号、不间断空格等)
  3. 拆分和插入

推荐阅读