淘汰赛内容可编辑绑定 [英] knockout contentEditable binding

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

问题描述

我编写了一个自定义绑定处理程序,用于切换元素是否可编辑.我还希望在编辑元素内容时更新任何 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天全站免登陆