如何在 div 和 Javascript 中的文本之间创建可点击范围

How to create a clickable span between the text in a div with Javascript

已有一个 html div,里面有文字。我希望用附加文本修改 div 的内容,但在现有文本 (A) 和我要插入的文本 (C) 之间有一段文本 (B)。该跨度还有一个由 id 实现的 css 样式,但已从代码片段中删除,因为它并不直接重要。

如果跨度要放在最后,我可以简单地将跨度附加为子级,这会将它放在 div 文本的末尾。但是,我后来添加到 div 的任何文本仍将出现在跨度之前。跨度永远在最后,至少据我所知。

假设现有 div 说 "Hello World. " 我希望使用 Javascript 添加以下内容:

var targetDiv = div;
div.textContent = 'Hello World! ';
var spanText = div.appendChild(document.createElement('span'));
spanText.innerHTML = 'Click Me!';
spanText.onclick = function(){
  perform task here;
};
div.textContent += ' Did you click it?';

div不会显示"Hello World. Click Me! Did you click it?"会显示"Hello World. Did you click it?Click Me!"

我尝试在附加文本时使用 innerHTML 在 div 内制作跨度,如下所示:

var targetDiv = div;
div.textContent = 'Hello World! ';
targetDiv.innerHTML += '<span>Click Me!</span> Did you click it?';
var spanText = div.span; //and variations such as div.children(1);
spanText.onclick = function(){
  perform task here;
};

这里的问题是我猜因为它在 innerHTML 中,javascript 没有 recognize/find 跨度,所以不能给它分配一个变量名。或者将 onclicks 和东西分配给它。此处,文本确实显示正确,如 "Hello World. Click Me! Did you click it?",但 onclick 不起作用。所以我尝试将 onclick 函数(是的,一行)放在 innerHTML 中,如下所示:

var targetDiv = div;
div.textContent = 'Hello World! ';
targetDiv.innerHTML += '<span onclick = "perform task here;">Click Me!</span> Did you click it?';

这也没有用。与第一次不同但与第二次尝试类似,文本显示正确但功能不起作用。

至于为什么我要做这样一个毫无意义的练习,这只是我正在做的一个抽象示例,我觉得在这种情况下上传实际代码只会让不必要的上下文陷入困境.但是,如果需要,我随时准备提供任何说明。

请使用香草 JS。目前我的项目中没有 JQuery,将它用于这样一小段代码似乎有些矫枉过正。

非常感谢您的帮助,谢谢!

不使用 textContent,而是使用 createTextNodeappendChild,参见 *** 行:

var targetDiv = div;
div.appendChild(document.createTextNode('Hello World! '));      // ***
var spanText = div.appendChild(document.createElement('span'));
spanText.innerHTML = 'Click Me!'; // Could use `createTextNode` here as well...
spanText.onclick = function(){
  // perform task here;
};
div.appendChild(document.createTextNode(' Did you click it?')); // ***

实例:

var div = document.createElement("div");

div.appendChild(document.createTextNode('Hello World! '));
var spanText = div.appendChild(document.createElement('span'));
spanText.innerHTML = 'Click Me!'; // Could use `createTextNode` here as well...
spanText.onclick = function(){
  console.log("Clicked!");
};
div.appendChild(document.createTextNode(' Did you click it?'));

document.body.appendChild(div);

当然,另一种方法是使用innerHTML,然后再获取跨度:

div.innerHTML = "Hello World! <span>Click Me!</span> Did you click it?";
div.querySelector("span").onclick = function(){
  console.log("Clicked!");
};

实例:

var div = document.createElement("div");

div.innerHTML = "Hello World! <span>Click Me!</span> Did you click it?";
div.querySelector("span").onclick = function(){
  console.log("Clicked!");
};

document.body.appendChild(div);

好消息!已经有一个 JavaScript 方法可以做到这一点。实际上有几个。

element.insertAdjacentHTML and element.insertAdjacentText 是允许您将 texthtml 定位在指定元素之前、之后以及作为指定元素的第一个或最后一个子元素的方法。

第一个参数取一个位置值。这些可以是以下任何一项:

'beforebegin': Before the element itself.
'afterbegin': Just inside the element, before its first child.
'beforeend': Just inside the element, after its last child.
'afterend': After the element itself.

第二个参数是您要在指定位置插入的 textHTML

作为一般情况下的示例:

 let element = document.querySelector("div"); //get a div element!

 element.insertAdjacentText("beforeend",
"this text node is the last child of the div");

 element.insertAdjacentHTML("beforeend", 
"<span>Just kidding, This span tag is now the last child of the div! </span>");

 element.insertAdjacentText("beforebegin", 
 "This text is inserted directly before the div!");

 element.insertAdjacentHTML("afterbegin", 
 "<span> This span tag is now the first child of the div!</span>");

 element.insertAdjacentText("afterend",
"This text is entered directly after the closing div tag!");

在您的用例中(尽管我同意 T.J Crowder 关于最好通过创建节点并附加它而不是使用 innerHTML 来插入 span 标记 - 原因是它具有更好的性能并且提供了更多的清晰度,我将由您自行决定),以下示例将让您了解如何将这些方法应用到您的代码中:

let div = document.querySelector("div");
div.innerHTML = "<span> click me </span>";
let span = div.querySelector("span");

span.addEventListener("click", function() {
alert("clicked span");
});


span.insertAdjacentText("beforebegin", " ::this is before the span tag::");
span.insertAdjacentText("afterend", " ::this is after the span tag:: ");

/*
'beforebegin': Before the element itself.
'afterbegin': Just inside the element, before its first child.
'beforeend': Just inside the element, after its last child.
'afterend': After the element itself.
*/
span {
color: red;
cursor: pointer;
}

div {
color: blue;
}
<div><span></span></div>