Firefox在clone上清空documentFragment

时间:2014-12-15 19:38:23

标签: javascript firefox documentfragment mithril.js

我发现这种奇怪的情况,Firefox在克隆它之后似乎松开了documentFragment的内容(深度标志设置为true)。这是一个Firefox错误,还是我错过了一个实现细节?

var n = ( function nScope(){
	'use strict';

	function isDom( x ){
		return x.nodeType > 0;
	}

	function notDom( x ){
		return !isDom( x );
	}

	return function n(){
		// Avoids conditional logic later by forcing a standard output.
		var args   = [].map.call( arguments, function wrapDom( x ){
			return isDom( x ) ? [ x ] : x;
		} );
		var dom    = [];
		var vdom   = [];
		// Render virtual DOM, then parse output.
		var view   = m.apply( void 0, args );
		var cfg    = view.attrs.config;

		if( view.children.forEach ){
			view.children.forEach( function divideChildren( x ){
				( isDom( x ) ? dom : vdom ).push( x );
			} );
		}

		if( dom.length === 0 ){
			return view; 
		}

		view.attrs.config = function appendDom( el, init, context ){
			// Only perform DOM insertion logic at config time:
			// Saves unnecessary execution during strategy none redraws.
            if( !init ){
                dom.forEach( function appendNode( node, index ){
                    // If a virtual DOM element occurs after the real node in the children list, grab it and find its
                    // index in the list of virtual elements as a reference point for inserting the real node.
                    var insertAt = vdom.indexOf( view.children.slice( view.children.indexOf( node ) ).filter( notDom )[ 0 ] );
                    // When a documentFragment is inserted into the document, the reference becomes empty.
                    // Therefore we need to insert clones of the original reference.
                    // Because this happens on every redraw, this means DOM nodes cannot be modified by prior reference
                    // between redraw cycles :(
                    console.log( 'Original node:', node );

                    var clone   = node.cloneNode( true );

                    console.log( 'Cloned node:', clone );

                    
                    if( insertAt ){
                        el.insertBefore( clone, el.childNodes[ insertAt ] );
                    }
                    else {
                        el.appendChild( clone );
                    }
                } );
            }

			if( cfg ){
				return cfg( el, init, context );
			}
		};

		// Make sure only the virtual elements are parsed by m.render.
		view.children = vdom;

		return view;
	};
}() );

// To stop jsfiddle breaking
m.route.mode = 'hash';

var links = document.createDocumentFragment();
var array = [ 1, 2 ];

array.forEach( function appendLink( index ){
    var a  = document.createElement( 'a' );
    
    a.innerText = 'Page ' + index;
    a.href      = '/route' + index;
    
    m.route( a );
    
    links.appendChild( a );
    links.appendChild( document.createTextNode( ' ' ) );
} );

var modules = array.map( function makeModule( index ){
    return {
        controller : function(){},
        view       : function(){
            return n(
                '.module',
                [
                    n( 'h1', {
                        onclick : function(){
                            alert( 'Redraw incoming...' );
                        }
                    }, 'Page ' + index ),
                    links 
                ]
            );
        }
    };
} );

m.route( document.body, '/route1', {
    '/route1' : modules[ 0 ],
    '/route2' : modules[ 1 ]
} );
<script src="https://rawgit.com/lhorie/mithril.js/master/mithril.js"></script>

1 个答案:

答案 0 :(得分:0)

您正在使用Firefox不支持的innerText:'innerText' works in IE, but not in Firefox

您可以使用textContent或innerHTML

array.forEach( function appendLink( index ){
    var a  = document.createElement( 'a' );

    a.textContent = 'Page ' + index; // <-- here
    a.href      = '/route' + index;

    m.route( a );

    links.appendChild( a );
    links.appendChild( document.createTextNode( ' ' ) );
} );