剔除内容可编辑绑定 [英] knockout contentEditable binding

查看:85
本文介绍了剔除内容可编辑绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个自定义绑定处理程序,该处理程序可切换元素是否为contentEditable.我还希望在编辑元素的内容时更新所有html绑定,以便它侦听输入事件并更新html绑定(如果可用).

I've written a custom binding handler that toggles whether or not an element is contentEditable. I also want any html bindings to update when the element's contents are edited, so it listens for input events and updates the html bindings if available.

ko.bindingHandlers.contentEditable = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.unwrap(valueAccessor());
        element.contentEditable = value;

        var $element = $(element);

        if (value) {
            var allBindings = allBindingsAccessor();
            var htmlBinding = allBindings.html;

            if (ko.isWriteableObservable(htmlBinding)) {
                $element.on("input", function (event) {
                    htmlBinding(element.innerHTML);
                });
            }
        } else {
            $element.off("input");
        }
    }
};

但是,这里有问题:

  • 用户在元素中输入内容
  • 触发输入事件
  • html绑定已更新
  • 该元素的innerHTML已更新
  • 元素中的光标位置返回到开头

一个jsfiddle说了一千个单词... http://jsfiddle.net/93eEr/1/

A jsfiddle says a thousand words... http://jsfiddle.net/93eEr/1/

我对如何处理这个问题感到有些困惑.

I'm a bit stumped as to how exactly to handle this.

推荐答案

ko.bindingHandlers.htmlLazy = {
    update: function (element, valueAccessor) {
        var value = ko.unwrap(valueAccessor());
        
        if (!element.isContentEditable) {
            element.innerHTML = value;
        }
    }
};
ko.bindingHandlers.contentEditable = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.unwrap(valueAccessor()),
            htmlLazy = allBindingsAccessor().htmlLazy;
        
        $(element).on("input", function () {
            if (this.isContentEditable && ko.isWriteableObservable(htmlLazy)) {
                htmlLazy(this.innerHTML);
            }
        });
    },
    update: function (element, valueAccessor) {
        var value = ko.unwrap(valueAccessor());
        
        element.contentEditable = value;
        
        if (!element.isContentEditable) {
            $(element).trigger("input");
        }
    }
};

var viewModel = {
    editable: ko.observable(false),
    content: ko.observable("<i>This</i> is the initial content!")
};

ko.applyBindings(viewModel);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<label>Editable: <input type="checkbox" data-bind="checked: editable"/></label>
<hr>
<div data-bind="contentEditable: editable, htmlLazy: content"></div>
<hr>
<pre data-bind="text: content"></pre>

以最少的花费即可完成任务.参见 http://jsfiddle.net/93eEr/3/

do the trick with minimal change. See http://jsfiddle.net/93eEr/3/

您可以将绑定处理程序称为htmlEditable,也许这比称其为惰性"更好.由你决定.

You could call the binding handler htmlEditable, maybe that's better than calling it "lazy". Up to you.

请注意,输入"事件并非每次都真正需要解除绑定.无论如何,当元素不可编辑时,它将不会触发.

Note that the "input" event does not really need to be unbound every time. It won't fire anyway when the element is not contenteditable.

这篇关于剔除内容可编辑绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆