需求:因为有一段html需要传递到其他的地方,内联样式可能与其他的样式冲突,所以要将写在style标签中的内联样式转换为行内样式
思路:
/**
* 参数接收html字符串
* 将内联样式表里面的样式改为行内样式
* */
transStyle(html){
/**
* 检测有没有style标签
* */
const h = $(html)[0]
const style = h.getElementsByTagName('style')[0]
if(!style) return html
const shtml = style.innerHTML.replace(/\n\s*/g,'')
/**
* 解析类名,暂时只处理类名。
* */
let s1 = shtml.split('}')
s1 = s1.filter(item=>item!=="")
const styleMap = this.generateStyleMap(s1)
styleMap.forEach((val,key)=>{
/**
* 根据key类名获取元素
* 为元素添加val 行内样式
* */
const elements = h.getElementsByClassName(key)
let v = val.replace(/\s*/g,'')
if(v[v.length-1]==';')v = v.slice(0,-1)
Array.prototype.forEach.call(elements, function (element) {
const s = element.getAttribute('style')
if(!s){
element.setAttribute('style',v)
}else{
if(s[s.length-1]==';') element.setAttribute('style',s+v)
else element.setAttribute('style',s+";"+v)
}
});
})
style.parentNode.removeChild(style)
return h.outerHTML
}
generateStyleMap(arr){
const m = new Map()
arr.forEach(item=>{
let s2 = item.split('{')
if(!(/,/).test(s2[0])){
const k = s2[0].slice(1)
this.addStyleMapItem(m,k,s2[1])
}else{
let s3 = s2[0].split(',')
s3=s3.map(item=>item.slice(1))
s3.forEach(i=>{
this.addStyleMapItem(m,i,s2[1])
})
}
})
return m
}
addStyleMapItem(map,key,addItem){
if(map.has(key)){
let v = map.get(key).trim()
if(v[v.length-1]!==';') v=v+";"
v = map.get(key)+addItem
map.delete(key)
map.set(key,v)
}else{
map.set(key,addItem)
}
}