Contenteditable add/remove class if child id :focus

Contenteditable add/remove class if child id :focus

我有一个 div 设置为 contenteditable 并且 div 中的所有内容都可以编辑。现在,当我点击 div 时,我会自动添加一个 class 选择(如果在我删除它并将其添加到新选择之前可见),我有下一步和前进按钮,所以我可以更改我的选择,如果我我正在使用平板电脑或智能手机 phone。

这就是我需要帮助的地方。

所以我选择了中间的 div,当我将光标移动到 #dynamic-storage 的另一个 child 时,我遇到了删除所选 class 的问题并将其添加到所选的新 child 中。 (不是示例中的跨度,因为它的 parent 是 div。这就是我想要选择的,因为此示例中的 div 是 children 的 #dynamic-storage(例如 #dynamic-storage > div

此 post 底部提供的代码段不包含屏幕截图中提供的箭头或菜单栏和上面的 fiddle 链接,因为在 [=] 的给定时间不需要该代码60=]ing。我让这个 post 专注于一项任务,即处理 .selected class 的 #dynamic-storage 的 child。

$(document).ready(function() {
  // Select Elements
  var SelectElements = function() {
    $("#dynamic-storage").children().on("mouseup touchend", function() {
      if ( $(".selected").is(":visible") ) {
        $(".selected").removeClass("selected");
      }

      $(this).addClass("selected");
    });
  };
  // Clear Selection
  var ClearSelection = function() {
    $(".selected").removeClass("selected");
  };
  SelectElements();

  // Handles Hotkeys
  $(document).keyup(function(e) {
    // Up & Down Arrow Keys To Select/Deselect Element in Editable
    if (e.which === 38 || 40 )  {
      if ( $(".selected").is(":focus") ) {
        alert("correct");
      } else if ( $(".selected").is(":blur") ) {
        alert("incorrect");
      }
    }
  });

});
/* Body */
#dynamic-storage {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 0;
  outline: 0;
}

#dynamic-storage .selected {
  outline: 2px dotted #69f;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=9" />
    <link type='text/css' rel='stylesheet' href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/jquery-ui.css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
  </head>
  <body>
    <div id="dynamic-storage" contenteditable="true">
      <div class="header" align="center">
        <h1>Welcome</h1>
        <h5>My name is Michael.</h5>
        <span>Hello world</span>
      </div>
      <div class="header selected" align="left">
        <h1>Welcome</h1>
        <h5>My name is Michael.</h5>
      </div>
      <div class="header" align="right">
        <h1>Welcome</h1>
        <h5>My name is Michael.</h5>
      </div>
    </div>
  </body>
</html>

Fiddle: http://liveweave.com/uyz4VK
Fiddle: http://jsbin.com/kujuxofeju/1/edit?html,js,output

类似于(在您的 jQuery 主函数中尝试):

$("#dynamic-storage").children().each(function() {
    $(this).on("focus", function() {
        $(this).addClass("selected");
    });
    $(this).on("blur", function() {
        $(this).removeClass("selected");
    });
});

但是如果您编辑内容,您将失去绑定到它们的事件处理程序...

具有属性 contenteditable='true' 的元素的所有内容都可编辑,就像在 单个 文本区域中一样。这就是为什么当你移动光标时 focus/blur 事件不会发生的原因。在带有 contenteditable='true' 的元素内的任何地方,你仍然在同一个文本区域中,没有离开或进入它。

这里的解决办法是处理类似textarea的coursor定位

要获得表示当前选择的 object,我们使用函数:

var getSelection;
if (window.getSelection) {
    // IE 9 and non-IE
    getSelection = function() {
        var sel = window.getSelection(), ranges = [];
        if (sel.rangeCount) {
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                ranges.push(sel.getRangeAt(i));
            }
        }
        return ranges;
    };
} else if (document.selection && document.selection.createRange) {
    // IE <= 8
    getSelection = function() {
        var sel = document.selection;
        return (sel.type != "None") ? sel.createRange() : null;
    };
}

然后我们要做下面的操作:从#dynamic-storage的第一层children中移除class.selected,用游标获取元素,向上DOM 找到最接近 #dynamic-storage 的 parent 添加 class .selected:

// Handles Hotkeys
  $(document).keyup(function(e) {
    // Up & Down Arrow Keys To Select/Deselect Element in Editable
    if (e.which === 38 || 40 )  {
        $('#dynamic-storage > div').removeClass('selected');
        var selectedElem = getSelection()[0].commonAncestorContainer.parentElement;
        $(selectedElem).closest('#dynamic-storage > div').addClass('selected');
    }
  });

Here is the working fiddle