knockout contentEditable binding

前端 未结 3 1340
再見小時候
再見小時候 2020-12-24 09:50

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 e

相关标签:
3条回答
  • 2020-12-24 09:52

    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>

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

    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.

    0 讨论(0)
  • 2020-12-24 09:59

    In previous I have problem with bdo that resolve it by this code. also this code is usable for other contentEditable. so I suggest the following:

     ko.bindingHandlers.bdoValue =
     ko.bindingHandlers.contentEditable = {
          'init': function(element, valueAccessor) {
              var updateHandler = function() {
                  var modelValue = valueAccessor(),
                      elementValue = element.innerHTML;
                  modelValue(elementValue);
              };
              ko.utils.registerEventHandler(element, "keyup", updateHandler);
              ko.utils.registerEventHandler(element, "input", updateHandler);
          },
          'update': function(elem, valueAccessor) {
              var value = ko.utils.unwrap(valueAccessor())||"";
              var current = elem.innerHTML;
              if (value !== current) {
                  elem.innerHTML = value;    
              }
          }
       };
    
    0 讨论(0)
  • 2020-12-24 10:17

    @Tomalak's answer is perfect, hence my upvote.

    But for those arriving here, like myself:

    • looking for a one-and-done custom binding
    • that assumes the content is always editable
    • is ok with value:-esque updates (ie: on blur)

    I suggest the following:

    ko.bindingHandlers.contentEditable = {
        init: function(element, valueAccessor) {
            var value = valueAccessor();
    
            function onBlur(){
                if (ko.isWriteableObservable(value)) {
                    value(this.innerHTML);
                }
            };                
    
            element.innerHTML = value(); //set initial value
            element.contentEditable = true; //mark contentEditable true
            element.addEventListener('blur', onBlur); //add blur listener
        }
    };
    
    0 讨论(0)
提交回复
热议问题