Javascript 如何在contenteditable div中禁用元素选择和调整大小?

Javascript 如何在contenteditable div中禁用元素选择和调整大小?,javascript,html,css,internet-explorer,contenteditable,Javascript,Html,Css,Internet Explorer,Contenteditable,例如,我的布局如下: <div contenteditable="true"> <span class="text-block" contenteditable="false"> <span contenteditable="false">Name</span> <a href="javascript:void(0)"> <i class="small-icon-remove"&g

例如,我的布局如下:

<div contenteditable="true">
   <span class="text-block" contenteditable="false">
      <span contenteditable="false">Name</span>
      <a href="javascript:void(0)">
          <i class="small-icon-remove"></i>
      </a>
   </span>
​</div>

名称
​
那么,如何禁用此功能:

这是:


我自己花了很多时间在这方面,试图在的中完全隐藏控件选择(这就是它们的调用方式)。不幸的是,我没有好消息

解决方案1 首先,有一个事件。当我发现它时(而且它的名字有一个
ms
前缀),我非常高兴,因为它应该是可以预防的

但事实证明它是完全不稳定的。有时会被解雇,有时不会。它在IEs版本、DOM结构、属性、您单击的元素、它是块元素等方面都有所不同。这通常是MS的废话。但你可以试试:

function controlselectHandler(evt) {
    evt.preventDefault();
}
document.body.addEventListener('mscontrolselect', controlselectHandler);
但是,这将完全阻止选择(如果有效)。因此,您将使这些元素完全不可选择

解决方案2 然后还有第二个选项,更可靠——在单击这些元素后将选择移动到其他地方。实现这一点的方法很少。在CKEditor中,我们正在修复
mousedown
上的选择。。。还有
mouseup
,因为(再次)有时候IE还不够,这取决于十几个条件。您还可以收听
selectionchange
事件并在那里修复所选内容

然而,同样,我们也在讨论阻止选择这样的元素

解决方案3 因此,第三个选项不是阻止选择,而是阻止
resizestart
事件。CKEditor将此与
启用objectresizing
命令结合使用:。此解决方案将阻止调整大小,但当然不会隐藏这些丑陋的边界

解决方案4 正如我提到的,我在CKEditor中研究过这个问题。我们设法使不可编辑的元素在可编辑的内部成为可能,但是浏览器之间的行为是完全可控和统一的。完整的解决方案太复杂,无法在StackOverflow上解释,我们花了几个月的时间来实现它。我们称此功能为小部件。看看吧。如您所见,当选择不可编辑元素时,没有控件选择。选择仅在
mousedown
mouseup
之间的短时间内出现,但仅在特定情况下出现。除此之外,一切都是本地的(尽管这完全是假的)


在和中阅读更多信息。

解决方案5


当焦点移动到子控件时,将“内容可编辑元素”属性值更改为false,并且在焦点离开子控件后,以相同的方式再次将“内容可编辑”设置为true

这篇文章在为我解决这个问题时非常关键(在tinyMCE工作):

通过将contenteditable DIV放置在非contenteditable DIV中,句柄不会出现在IE或FF中,但您仍然可以编辑内容


我对IE11中的CKEditor 4.4.7也有同样的问题。作为一种解决方法,我将元素的当前尺寸保存在“mousedown”上,并将“min-width”、“max-width”、“min-height”和“max-height”样式属性设置为其当前尺寸。这样,在调整大小期间,元素将以其原始大小显示。在“mouseup”中,我恢复了修改过的元素的样式属性。这是我的密码:

$('textarea').ckeditor().on('instanceReady.ckeditor', function(event, editor) {
    var $doc = $(editor.document.$);
    $doc.on("mousedown", "table,img", function() {
        var $this = $(this);
        var widthAttrValue = $this.attr("width");
        if (widthAttrValue) {
            $this.data("widthAttrValue", widthAttrValue);
        }
        var widthStyleValue = this.style.width;
        if (widthStyleValue) {
            $this.data("widthStyleValue", widthStyleValue);
        }
        var width = widthStyleValue || widthAttrValue || String($this.width())+"px";
        var height = this.style.height || $this.attr("height") || String($this.height())+"px";
        $this.css({
            "min-width": width,
            "max-width": width,
            "min-height": height,
            "max-height": height,                                       
        });
        $doc.data("mouseDownElem",$this);
    }).on("mouseup", function() {
        var $elem = $doc.data("mouseDownElem");
        if ($elem) {
            $elem.removeAttr("height").css("height","");
            var widthAttrValue = $elem.data("widthAttrValue");
            if (widthAttrValue) {
                $elem.attr("width", widthAttrValue);
                $elem.removeData("widthAttrValue");
            } else {
                $elem.removeAttr("width");
            }
            var widthStyleValue = $elem.data("widthStyleValue");
            if (widthStyleValue) {                                      
                $elem.removeData("widthStyleValue");
            } 
            $elem.css({
                "min-width":"",
                "max-width":"",
                "min-height":"",
                "max-height":"",
                "width": widthStyleValue || ""
            });
            if (!$.trim($elem.attr("style"))) {
                $elem.removeAttr("style");
            }
            $doc.removeData("mouseDownElem");
        }
    });
});

下面是我为解决这个问题所做的。对我来说,只有当
contenteditable
元素为空时才会发生这种情况,当有内容时,调整大小的句柄就会消失,因此我创建了以下CSS唯一的解决方案:

[contenteditable]:empty:after {
  content: " ";
}
该解决方案背后的思想是,每当
contenteditable
字段为空时,它就会应用一个空格伪元素,从而在用户选择
contenteditable
字段时删除显示的调整大小标记。一旦用户输入了任何内容,伪元素就会消失


请注意,由于使用了伪元素,此修复仅适用于IE9及以上版本。

解决问题的方法是删除
最大宽度:100%!重要的contenteditable
DIV中DOM元素的CSS属性的code>line。希望有帮助


顺便说一句,这不会发生在MS Edge上。。。祈求好运,这表明MS朝着正确的方向移动:)

我也有同样的问题。从前面的文章中可以看出,IE可以识别某些行为,并将此段落添加为焦点/调整大小。对我来说,这是因为我在contenteditable div中有一种段落风格

删除:

div[contenteditble="true"] p{
   min-height:1em;
}

为我修复了它。

我也遇到了同样的问题,因为我将最大宽度的CSS规则放在contenteditable中的所有子元素上。删除它或将其限制在图像上就可以了

[contenteditable] * { max-width: 100%; } // causes the issue
[contenteditable] img { max-width: 100%; } // works fine for me

确保没有
元素受“最大宽度”属性的影响。

溢出:隐藏也可能导致此问题,例如:

ul, ol {
  overflow: hidden;
}

要禁用调整大小句柄,我只需为IE11添加以下内容:

div {
    pointer-events: none;
}
对于firefox,在插入contenteditable元素后执行这一行可以工作:

document.execCommand("enableObjectResizing", false, false);

在这里或其他帖子中,没有任何其他人推荐的东西真正适合我,但我通过以下方式解决了这个问题:

[contenteditable="true"] p:empty {
    display: inline-block;
}
这样,调整大小框消失了,但我仍然可以将光标设置在p块下方或p块中来编辑它们。

解决了! 将不可编辑内容的span放置在可编辑内容的主体中时,它开始显示一个可调整大小的span容器。刚刚解决我的问题的是一个简单的单行CSS样式 指针事件:无位于内部SPAN标记上

最小宽度:1.5cm;
显示:内联块;
指针事件:无

示例文本

我不确定您是否已将span设置为不可编辑。我无法从您提供的html元素在ie11中重现此问题,但由于contentedita,我在应用程序中遇到了相同的问题
[contenteditable="true"] p:empty {
    display: inline-block;
}