Firefox满足游标问题

时间:2014-11-23 19:13:43

标签: firefox contenteditable

我有一个contenteditable div,当空时(只有下面的CSS中存在占位符文本),用户可以点击div的右侧并放置光标在那里(见截图)。光标到达后,用户根本无法输入。这个问题只发生在Firefox(我在33.1.1中)。任何其他浏览器都不会出现此问题。

HTML:

<div class="content-editable form-textarea font-face-frank"
    placeholder="Type something here..." contenteditable="true"
    ng-model="form.message" ng-class="form.fontName" strip-br="true" required></div>

CSS:

.content-editable {
    outline-width: 0;
    min-height: 1em;
    max-height: 300px;
    line-height: 1em;
    overflow-y: scroll;
    display: inline-block;
    width: 100%;
    font-size: 44px;
    padding: 10px;
}
.content-editable:empty:before {
    content: attr(placeholder);
}

我尝试过的事情:

  • 在div中放置<br>空格 - 修复问题,但不会显示占位符文本;
  • 通过&nbsp;添加<br>.content-editable:empty {}; placholder文本仍然存在,但光标问题未得到解决。

重新讨论问题

Screencap of cursor position

更新

删除content: attr(placeholder); css指令可以解决问题,而不是这样做可以让我显示&#39;占位符&#39;满足要素中的文字。

9 个答案:

答案 0 :(得分:6)

这是您可能喜欢的小提琴:http://jsfiddle.net/e5gwc1gq/2/

我认为问题是因为:before psuedo元素不允许访问底层的parent-div。

我之所以这么认为,是因为如果您要将before替换为after,问题仍然存在,但会被翻转,即现在如果您点击左侧,则会赢得&#39;工作正常。

注意:您可能希望为word-wrap: break-word;添加.content-editable css规则,因为默认情况下firefox不会添加此项,但Chrome会这样做。

答案 1 :(得分:4)

这个CSS解决方案确实有效。插入位置设置到最后,文本可以选择,一切都按预期工作。

-moz-user-select: text;
-khtml-user-select: text;
-webkit-user-select: text;
-o-user-select: text;

在Firefox 35.0.1,Chrome 40.0.2214.94 m,IE 11上测试 这是一个小提琴:http://jsfiddle.net/yam9kkbL/

答案 2 :(得分:2)

我们遇到了原始问题中描述的相同问题。我们为&#34添加了一个处理程序;点击&#34;和&#34; keydown&#34;对于Firefox。如果该框为空并且用户试图单击或在框中键入,我们将其模糊,然后再次关注它。

if ($("body").hasClass("ff"))
{
    var box = $(".content-editable");
    box.on("keydown click", function(e){
        if(box.text().trim().length == 0){
            box.blur().focus();
        }
    });
}

答案 3 :(得分:1)

实际上,最简单的解决方案如下:

为contentEditable div设置height: 16px;

无需添加placeholder属性或任何其他复杂属性 CSS属性组合

此致

答案 4 :(得分:1)

问题是使用:之前。解决方案是在使用其他div之前模拟它。

这是我的解决方案,我也展示了:在相对和绝对的位置出现麻烦之前。

https://jsfiddle.net/oropesa/d8y1k7yd/

/* halara style-reset */
* { margin: 0; padding: 0; } body { margin: 1rem; background: #dfeaff; } h4 { margin: 1rem 0 0} p { font-size: .8em; color: darkgray; margin: .5rem 0 1rem; }

/* default content style */
.content-editable {
    min-height: 1.5rem;
    max-height: 4rem;
    padding: 1.5rem;
    background: white;
    border: 1px solid #bdc3c7;
}
.content-editable:focus { border-color: #3498db; outline: 0 }

/* specific content style, troubles 1 & 2 */
.content-editable.placeholder-relative:empty:before { position: relative; }
.content-editable.placeholder-absolute:empty:before { position: absolute; }

.content-editable.placeholder-relative:empty:before,
.content-editable.placeholder-absolute:empty:before {
    content: attr(placeholder);
    color: #bdc3c7;
}

.content-editable.placeholder-relative:focus:empty:before,
.content-editable.placeholder-absolute:focus:empty:before {
   color: #3498db;
   opacity: .5
}

/* solution style */
.content-wrapper {
   position: relative;
   background: white;
 }
 
.content-editable.with-ghost {
   position: relative;
   background: transparent;
   z-index: 1;
}

.ghost-placeholder {
   position: absolute;
   display: none;
   z-index: 0;
   top: 1.5rem; /*as padding*/
   left: 1.5rem; /*as padding*/
   color: #bdc3c7;
}

.content-editable.with-ghost:empty + .ghost-placeholder {
   display: block;
}
<h3>Only in firefox</h3>

<h4>Trouble 1: placeholder in before with position relative</h4>
<p>If you click several times inside the div (not on the placeholder-text), the cursor change between the left and right part of the div (and still focused). When the cursor is on the right, typing doesn't work.</p>
<div class="content-editable placeholder-relative" contenteditable="true" placeholder="Type something here..."></div>

<h4>Trouble 2: placeholder in before with position absolute</h4>
<p>When the div is focus and empty, the cursor ignores the padding of the div. And if you click on the text the focus event is ignored.</p>
<div class="content-editable placeholder-absolute" contenteditable="true" placeholder="Type something here..."></div>

<h4>Solution:</h4>
<p>Don't use <i>:before</i> and simulate the placeholder (see the <i>html</i> and <i>css</i> code).</p>
<div class="content-wrapper">
    <div class="content-editable with-ghost" contenteditable="true" placeholder="Type something here..."></div>
    <div class="ghost-placeholder">Type something here...</div>
</div>

<h4>Another trouble (more? damn firefox...)</h4>
<p>In all cases, when you write and remove all the text, the content-editable div isn't empty, inside it has <i>&lt;br&gt;&lt;br&gt;</i>, so if you want to show the placeholder you have to remove this rubbish with javascript (on the <i>blur</i> event).</p>

<p>Good luck! =)</p>

答案 5 :(得分:1)

-moz-user-select: text !important;

适合我...... Firefox将-moz-user-select: none;添加为内联样式

答案 6 :(得分:0)

我想出了一个似乎有用的小提琴......唯一的问题是文本需要手动清除。

Fiddle

HTML

<div class="content-editable" form-textarea font-face-frank
    placeholder="Type something here..." contenteditable="true"
    ng-model="form.message" ng-class="form.fontName" strip-br="true" required></div>

CSS

.content-editable {
    outline-width: 0;
    min-height: 1em;
    max-height: 300px;
    line-height: 1em;
    overflow-y: scroll;
    font-size: 44px;
    padding: 10px;
    border: 1px solid cyan;
}

的JavaScript

document.getElementsByClassName('content-editable')[0].innerHTML=document.getElementsByClassName('content-editable')[0].getAttribute('placeholder');

答案 7 :(得分:0)

:before(或:after)伪元素拦截FireFox中contenteditable焦点的问题可以通过简单地聚焦任何其他元素并将焦点恢复来解决:

if(/firefox/i.test(navigator.userAgent))                   // Fix FireFox only
    $('span[contenteditable]').on('click', function() {    // Patch affected controls
        $('input:visible')[0].focus();                     // Focus on any other control
        this.focus();                                      // Focus back
    });

您可能需要引入此模拟input以将焦点转移到。

答案 8 :(得分:0)

似乎FF无法正确使用::之前/之后的伪元素。如果我设置绝对定位,则会出现新的错误 - 顶部的插入符号位于占位符之上。

所以我的解决方案是使用跨度(在我的情况下 - 在contenteditable div之后),但你也可以把它放在里面。 css将是这样的:

//imitate placeholder
[contentEditable="true"] + .chat-placeholder {
  color: rgba(63, 52, 52, 0.5);
  position: absolute;
  display: none;
}

// show placeholder if the field is empty only 
[contentEditable="true"]:empty + .chat-placeholder {
  display: inline-block;
}