26 нояб. 2014 г.

HTML5 draggable and contenteditable

Handle for draggable element


var target, allowedHandleSelector = '.drag-handle';
var onmousedown = function(e) {
    target = e.target;
};
var ondragstart = function(e) {
    if (!target.matches(allowedHandleSelector) {
        // prevent drag when target does not match handle selector
        e.preventDefault();
        return;
    }
    ...
};

Make draggable element and its flying ghost look differently

http://farhadi.ir/posts/the-story-behind-html5-sortable/

var ondragstart = function(e) {
    var $element = $(e.target).closest('.draggable');
    $element.toggleClass('drag-ghost', true);
    // modify element after creation of flying ghost
    setTimeout(function() {
        $element.toggleClass('drag-ghost', false);
        $element.toggleClass('dragging', true);
    }, 0);
    ...
};

Disable spell checking for contenteditable element


<div spellcheck="false" contenteditable="true">Editable content</div>
<div spellcheck="false" contenteditable="false">This content could be made editable</div>

300px limit

At least on Windows browser clips width of ghost (drag image) to 300x and applies radial opacity gradient: opacity of the image drops from 1 directly under the mouse cursor to zero at 300px distance.

Avoid nesting draggable and contenteditable attributes

Here be dragons!

Upgrade React to 0.12


  1. Rename React.renderComponent to React.render and use React.createFactory:
    was in 0.11:
    React.renderComponent(ReactClass(props), container)
    should be in 0.12:
    React.render(React.createFactory(ReactClass)(props), container)
  2. Use displayName where possible - it will be used in console messages
  3. Use either JSX or React.createFactory to render children components:
    JSX:
    var Child = React.createClass(...);
    render: function() {
        return <Child name={this.props.name} />;
    }

    JS:
    var Child = React.createClass(...);
    var factory = React.createFactory(Child);
    render: function() {
        return factory({name: this.props.name});
    }
  4. Do not use transferPropsTo. Use explicit props object in JS code or spread operator in JSX:
    JS:
    render: function() {
        return childFactory(_.extend({}, this.props,
            {className: 'name ' + this.props.className});
    }

    or:
    render: function() {
        return React.createElement(Child, props);
    }

    JSX:
    render: function() {
        return <Child {...this.props} className={'name ' + this.props.className} />;
    }
  5. Do not use this.props.key in React class - it is removed from props.
    was in 0.11:
    var Child = React.createClass({
        render: function() {
            return <div data-uid={this.props.key} />;
        }
    });
    ...
    var children = items.map(item => <Child key={item.uid} />);

    should be in 0.12:
    var Child = React.createClass({
        render: function() {
            return <div data-uid={this.props.uid} />;
        }
    });
    ...
    var children = items.map(item => <Child key={item.uid} uid={item.uid} />);

5 нояб. 2014 г.

Повторное использование кода в React

В React отсутствует какое-либо наследование компонентов, так что если необходимо реализовать несколько компонентов с похожим функционалом (и одинаковым кодом), и избежать копирования общего кода, то для этого существует только два способа повторного использования кода:
  1. Mixin (docs)
  2. Компонент-обёртка