【问题标题】:contentEditable and lastChild IE, Firefox & Chrome LastChildcontentEditable 和 lastChild IE、Firefox 和 Chrome LastChild
【发布时间】:2015-02-19 09:42:42
【问题描述】:

抱歉,问题很长,但我已经尝试了很多事情并进行了一些研究,但还没有找到很多解决方案。我有一个内容可编辑的 div。

  <div contentEditable=true onkeyup='showResult(this.lastChild.textContent)'></div>

当用户在这个 div 中输入内容时,会运行 showResult javascript,这基本上是一个 ajax 请求,它返回匹配项的列表。当用户点击其中一个建议时,说出名字“John”,带有建议的 span 会添加到这个 contentEditable div 中,如下所示:

<div contentEditable=true onkeyup='showResult(this.lastChild.textContent)'>
  <span id='uniqueId1' class='SpanClass' contentEditable='false'>John</span>
</div>

选择了一个名称后,用户可能想要搜索另一个名称。它是 HTML 术语,这意味着他们将输入以下内容:

<div contentEditable=true onkeyup='showResult(this.lastChild.textContent)'>
  <span id='uniqueId1' class='SpanClass' contentEditable='false'>John</span>
New User Text Goes Here
</div>

在 Chrome 上,当用户继续尝试输入 div 时会发生正确的行为 - showResult 函数在用户输入的新文本上运行并忽略 span 元素。例如,如果用户键入“Fr”已经选择了 John,它会忽略第一个孩子 (John),并通过 ajax 发送用户键入的内容并返回 Fred 和 Frankie 等建议。

但是,在 IE 中,跨度仍然是内容可编辑的,并且用户不能在跨度内添加任何文本,这似乎没有任何意义,因为它显然是 contentEditable=false ajax 请求因此在“ John" 文本加上用户接下来输入的任何内容,这不是我想要实现的。

最后,在 Firefox 中,span 不是 contentEditable 但 lastChild 位只拾取 span 内的文本,并忽略用户输入的文本。

我已经通过控制台记录了 showResult(this.lastChild.textContent) 的结果,以查看发送到 ajax 请求的内容。

在 Chrome 中,在“John”跨度后的框中输入“Fr”将“Fr”发送到 ajax 并返回正确的结果。

在 IE 中,在框中输入“Fr”会发送“JohnFr”

在 Firefox 中,输入“Fr”只会发送“John”。

由于这个 lastChild 和 span 存在问题,我还包含了创建 span 元素的 Javascript。这仅在返回成功结果并单击结果后才会激活。 (请原谅非常混乱的 Javascript/Jquery)

$('body').on("click", '.TagHints', function(){
//Once you click on the suggestion
var ThisData = $(this).data("id");
var ThisId = $(this).attr("id");
var ThisTag = $(this).data("tag");

//delete the text that the user typed in
elementToRemove = document.getElementById("FakeInput").lastChild;
document.getElementById("FakeInput").removeChild(elementToRemove);

var TagDiv = document.createElement('span');
TagDiv.className = 'SpanClass';
TagDiv.id = ThisId;
TagDiv.innerHTML = ThisTag;
TagDiv.contentEditable=false;

//append the Span to the contentEditable div
document.getElementById("FakeInput").appendChild(TagDiv);

var TagHints = document.getElementsByClassName("TagHints");
    while(TagHints.length > 0){
    TagHints[0].parentNode.removeChild(TagHints[0]);
    }

});

为什么这三种浏览器的行为完全不同,如何让它们都像 Chrome 一样? 有没有更好的方法让文本不在跨度中?

我读到另一个答案,firefox 喜欢输入,而 IE 喜欢在这种情况下中断,但两者似乎都不适合我。 :-(。

一个好的解决方案的一大障碍是 jQuery 在大约第 6 行之后停止工作,这也让我完全困惑。如果有人可以解释为什么它不起作用,那也很酷。也许与加载 jquery 后创建的 ajax 查询和内容有关?

感谢您的帮助!

【问题讨论】:

    标签: javascript ajax google-chrome internet-explorer firefox


    【解决方案1】:

    所以,虽然我没有收到任何回复,但我想出了一个解决方法。但是,lastChild 在三个浏览器之间的行为仍然不同,因此希望您能提供任何进一步的意见。

    答案是在文档就绪部分中有一个函数,它克隆了原始 div,剥离了它的子元素,并使用 Jquery 抓取了键上的文本。然后将结果传递给 showResult 函数,如下所示:

     $('#FakeInput').keyup(function(){
     var ThisClone =  $('#FakeInput').clone()
         .children()
           .remove()
           .end()
           .text();
      showResult(ThisClone);
    
      });
    

    同样,当用户进行选择时,我没有尝试从 div 中删除用户输入的文本,而是使用它们的类克隆了 span 中的项目,然后清空 div 的内容并重新附加这些克隆div。

    var TagItems = $('.TagItems').clone();
    $('#FakeInput').empty();
    $('#FakeInput').append(TagItems);
    

    此解决方案适用于三种浏览器。

    【讨论】:

    • 我在 IE 团队工作,对这个问题很感兴趣,所以我想办法进一步研究这三种主要方法。您可能会对the results 感兴趣。我没有立即看到规范说明浏览器应该采用哪种方法,但它确实看起来好像 IE 和 Chrome 正在融合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2017-03-22
    相关资源
    最近更新 更多