【问题标题】:DOM manipulation while preserving previous handlersDOM 操作,同时保留以前的处理程序
【发布时间】:2015-09-25 20:53:58
【问题描述】:

问题:

假设我有一个带有这样文本的 div

<div id=”bla”>One Two Three Four Five</div>

我希望能够以编程方式获取任何子字符串并将其包装到 &lt;div&gt; 中,并附加一些处理程序(比如 onlick)。我希望能够多次对文本的不同部分执行此操作,所以最后我的 div 最终看起来像这样:

<div id=”bla”>One <div id=”bla2”>Two</div> Three <div id=”bla4”>Four</div> Five</div>

问题是怎么做?

一些想法:

如果我想将字符串 Two 包装到 div 中,那么如果我只使用 html() 获取整个 div 内容,在 Two 之前和之后执行 substring,然后在 div 上执行 .empty().append(beforeSubstring, &lt;Two wrapper with some handler&gt;, afterString) - 它看起来不错,但它会将 beforeSubstring 和 afterSubstring 放入“”并删除所有以前的处理程序。但我想保留以前的处理程序,我不需要“”,因为它会让我搞砸。

有什么想法吗? :)

【问题讨论】:

  • 您的 HTML 文档是否使用 (而不是 ")引号进行验证?
  • 另外...&lt;div id=”bla2”&gt;您自动获得了该 ID?
  • html 中是否存在事件处理程序,这些事件处理程序在任何此操作之前已经受到影响?如果是这样,则必须迭代文本节点,否则可以在新节点上使用事件委托
  • @Pinny 我认为如果你用代码编写算法而不是用英文编写算法,你会更容易理解。
  • @RokoC.Buljan。我出去了两天,现在我正在尝试应用我在这里的两个解决方案。我不想向该线程发送垃圾邮件。一旦我得到 pos/neg 答案 - 我会在这里发帖。

标签: javascript jquery html


【解决方案1】:

您首先需要缓存元素的内容,例如 var cont = $("#bla").text();
在插入包装器之前总是使用cont(我想使用RegExp......)并将结果放回该元素中,如$("#bla").html(regexModifiedCont);

示例:

var $contentEl = $("#bla");
var content = $contentEl.text(); // Cache the original content!

$("#query").on("input", function(){
  var reg = new RegExp("("+  $.trim(this.value) +")", "ig");
  $contentEl.html( content.replace(reg, "<span class='clickable'>$1</span>") );
});

$("body").on("click", ".clickable", function(){
  alert( $(this).text() );
});
.clickable{
  background:gold;
  cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Write a text to take <input id=query type=text>
<div id=bla>One Two Three Four Five</div>

【讨论】:

  • 此解决方案与我现在遇到的问题相同。 repro步骤:点击F12查看源码;键入“Tw”;查看
    的新“源”正如您所见,处理 text()/html() 会将 "" 放在拆分的部分周围。虽然这不会影响浏览器中的外观,但在我的情况下,我将根据开始和结束位置进行文本选择,由于“不可见”引号,这将是倾斜的。我的猜测是,我需要像下面的 Las 建议的那样做一些事情 - 将内容放入标签(可能是 )以避免此类问题。
  • @Pinny 是的,我的示例放置了&lt;span&gt; 标签,以便您可以使用 CSS 设置它们的样式并使其可点击(合乎逻辑,不是吗?)。现在为什么这是一个你没有解释的问题我不明白你在说什么隐形引号以及为什么在我的例子中这些是一个问题。
  • @Pinny 例如,您是否尝试过右键单击并复制父级的 HTML,然后将剪贴板粘贴到文本编辑器中?你能看到任何鬼语吗?如果你还没有尝试过,你真的应该。在您尝试之后,请回来告诉我上述示例的真正问题是什么。迫不及待想收到您的来信。
  • 老兄,我不确定你对这个帖子有什么问题,但如果它对你来说很烦人 - 你知道你可以停止回复它,对吧?你真的没有帮助,但恰恰相反。
  • @Pinny 不,这并不烦人,实际上恰恰相反 :)
【解决方案2】:

也许您正在寻找这样的东西? =)

  function wrapTag(string, tag) {
    return '<'+tag+'>' + string + '</'+tag+'>';
  }

  // http://stackoverflow.com/questions/5379120/get-the-highlighted-selected-text
  function getSelectionText() {
      var text = "";
      if (window.getSelection) {
          text = window.getSelection().toString();
      } else if (document.selection && document.selection.type != "Control") {
          text = document.selection.createRange().text;
      }
      return text;
  }      

  function highlightSelection(tag) {
    var highlighted = getSelectionText();
    var newContent = $('#paragraph').html()
                      .replace(/\s+/g,' ').trim()
                      .replace(highlighted, wrapTag(highlighted, tag));
    $('#paragraph').html(newContent);
  } 

工作示例: http://plnkr.co/edit/VCpGScPR9TEjuY3mtP2j?p=preview

【讨论】:

  • 您的解决方案更接近所需的解决方案,但我遇到的第二个问题是 - 在您进行下一次选择后,先前选择的文本的处理程序不见了。
猜你喜欢
相关资源
最近更新 更多
热门标签