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屬性重新命名或者刪掉,這樣,我們就統一了從視覺化編輯到原始碼所使用的尺寸,這樣就可以解決尺寸無法儲存的問題。