1. 程式人生 > >UEditor 解決拖拽視訊元素改變視訊尺寸時,無法儲存視訊尺寸問題的解決方法

UEditor 解決拖拽視訊元素改變視訊尺寸時,無法儲存視訊尺寸問題的解決方法

    UEditor雖然強大,但是bug還是蠻多的。比如插入視訊元素後,拖拽視訊去縮放尺寸,編輯器並沒有將實際的尺寸儲存下來。當你點選HTML按鈕檢視原始碼時,width和height還是原來的值,再次點選此按鈕回到正常狀態,縮圖又回到原來的大小了。

    翻原始碼翻了蠻久,終於把這個問題解決了。問題就出在插入視訊後建立視訊HTML字串和HTML字串與視覺化編輯層轉化的地方。

     當視訊上傳完成後,建立一個img用於視覺化編輯,將預設width和height設定到img的width和height的屬性中。當你拖動視覺化圖片時,就會改變這個img的style中的width和height來改變img的大小(注意,不是改變width和height屬性),將新的高和寬設定到。一直到這裡其實都沒什麼問題。

    看一下下面這段程式碼,在ueditor.all.js裡:

function creatInsertStr(url,width,height,id,align,classname,type){
        var str;
        switch (type){
            case 'image':
                str = '<img ' + (id ? 'id="' + id+'"' : '') + ' width="'+ width +'" height="' + height + '" _url="'+url+'" class="' + classname + '"'  +
                    ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')" />'
                break;
            case 'embed':
                str = '<embed type="application/x-shockwave-flash" class="' + classname + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
                    ' src="' +  utils.html(url) + '" width="' + width  + '" height="' + height  + '"'  + (align ? ' style="float:' + align + '"': '') +
                    ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
                break;
            case 'video':
                var ext = url.substr(url.lastIndexOf('.') + 1);
                if(ext == 'ogv') ext = 'ogg';
                str = '<video' + (id ? ' id="' + id + '"' : '') + ' class="' + classname + '" ' + (align ? ' style="float:' + align + '"': '') +
                    '" controls preload="none" width="' + width + '" height="' + height + '" src="' + url + '" data-setup="{}">' +
                    '<source src="' + url + '" type="video/' + ext + '" /></video>';
                break;
        }
        return str;
    }
function switchImgAndVideo(root,img2video){
        utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){
            var className = node.getAttr('class');
            var rWidth = node.getStyle("width");
            var rHeight = node.getStyle("height");
            if(className && className.indexOf('edui-faked-video') != -1){
                //here
                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr("width"),node.getAttr("height"),null,node.getStyle('float') || '',className,img2video ? 'embed':'image');
                node.parentNode.replaceChild(UE.uNode.createElement(html),node);
            }

            if(className && className.indexOf('edui-upload-video') != -1){
                //here
                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr("width"),node.getAttr("height"),null,node.getStyle('float') || '',className,img2video ? 'video':'image');
                node.parentNode.replaceChild(UE.uNode.createElement(html),node);
            }
        })
    }

    這段程式碼是用於控制html原始碼與視覺化編輯直接的轉換的,註釋here下一行就是呼叫上面的方法,問題就出在這裡。

這裡傳入creatInsertStr函式的width和height值是node.getAttr("width|height"),也就是說獲取的是標籤的width和height屬性,而不是style屬性裡面的width和height。但實際上我們拖動的時候是改變img的style屬性,img的width和height不會變,還是預設的值。所以你無論怎麼拖動,到最後建立的html程式碼中video的寬和高都還是預設的。

    ​所以,我們需要將其統一化,在這裡我使他們都用style來設定寬和高,不用width和height屬性。修改後的程式碼如下: ​

function creatInsertStr(url,width,height,id,align,classname,type){
        width += "";
        height += "";
        if(width.indexOf("px") == -1){
            width+="px";
        }
        if(height.indexOf("px") == -1){
            height+="px";
        }
        var str;
        switch (type){
            case 'image':
                str = '<img ' + (id ? 'id="' + id+'"' : '') + ' a="'+ width +'" b="' + height + '" _url="'+url+'" class="' + classname + '"'  +
                    ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')+' width:'+width+'; height:'+height+'" />'
                break;
            case 'embed':
                str = '<embed type="application/x-shockwave-flash" class="' + classname + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
                    ' src="' +  utils.html(url) + '" width="' + width  + '" height="' + height  + '"'  + (align ? ' style="float:' + align + '"': '') +
                    ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >';
                break;
            case 'video':
                var ext = url.substr(url.lastIndexOf('.') + 1);
                if(ext == 'ogv') ext = 'ogg';
                str = '<video' + (id ? ' id="' + id + '"' : '') + ' class="' + classname + '" ' + (align ? ' style="float:' + align + '"': '') +
                    'style="width:'+width+';height:'+height+'" controls preload="none" width="' + width + '" height="' + height + '" src="' + url + '" data-setup="{}">' +
                    '<source src="' + url + '" type="video/' + ext + '" /></video>';
                break;
        }
        return str;
    }

    function switchImgAndVideo(root,img2video){
        utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){
            var className = node.getAttr('class');
            var rWidth = node.getStyle("width");
            var rHeight = node.getStyle("height");
            if(className && className.indexOf('edui-faked-video') != -1){
                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),rWidth,rHeight,null,node.getStyle('float') || '',className,img2video ? 'embed':'image');
                node.parentNode.replaceChild(UE.uNode.createElement(html),node);
            }

            if(className && className.indexOf('edui-upload-video') != -1){
                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),rWidth,rHeight,null,node.getStyle('float') || '',className,img2video ? 'video':'image');
                node.parentNode.replaceChild(UE.uNode.createElement(html),node);
            }
        })
    }

​    ​我們在傳入給creatInsertStr引數時,使用node.getStyle方法獲得的元素style中的高和寬,而在creatInsertStr方法中,我們將高和寬設定到style中,並將width和height屬性重新命名或者刪掉,這樣,我們就統一了從視覺化編輯到原始碼所使用的尺寸,這樣就可以解決尺寸無法儲存的問題。