Javascript 转换css单位
我正在尝试以所有有效的“长度”和“百分比”单位从该属性的原始值集转换回来一个样式属性 e、 例如,如果我有一个将style.width设置为20%的div,我希望返回一个对象,该值以百分比(当然是20%)、像素(不管实际像素宽度是多少)、em、pt、ex等为单位 我意识到“百分比”不是“长度”值,并且不是所有接受长度值的属性都接受百分比,但也希望包括百分比 当然,某些值将具体取决于元素,并且可能取决于元素在DOM中的位置(例如,获取em值也需要元素的父计算字体大小) 我可以假设样式是为元素显式设置的——我知道如何检索元素的当前计算样式——我只是希望不要重复其他人可能已经完成的工作。我也知道,但它依赖于style.pixelWidth或node.clientWidth,在Chrome中失败(我假设它在Safari中也失败了……可能还有其他) 我已经计算出了颜色值(rgb、rgba、十六进制、名称)-这当然要简单得多。我使用的值在数学上是可变的,因此实际上只需要“length”和“percent”值(如果对具有非长度、非percent值的属性集(如“font size:larger”)调用,函数可能会失败或抛出错误) 如果按程序编写,这样的内容将是理想的:Javascript 转换css单位,javascript,css,Javascript,Css,我正在尝试以所有有效的“长度”和“百分比”单位从该属性的原始值集转换回来一个样式属性 e、 例如,如果我有一个将style.width设置为20%的div,我希望返回一个对象,该值以百分比(当然是20%)、像素(不管实际像素宽度是多少)、em、pt、ex等为单位 我意识到“百分比”不是“长度”值,并且不是所有接受长度值的属性都接受百分比,但也希望包括百分比 当然,某些值将具体取决于元素,并且可能取决于元素在DOM中的位置(例如,获取em值也需要元素的父计算字体大小) 我可以假设样式是为元素显式设
function getUnits(target, prop){
var value = // get target's computed style property value
// figure out what unit is being used natively, and it's values - for this e.g., 100px
var units = {};
units.pixel = 100;
units.percent = 50; // e.g., if the prop was height and the parent was 200px tall
units.inch = 1.39; // presumably units.pixel / 72 would work, but i'm not positive
units.point = units.inch / 72;
units.pica = units.point * 12;
// etc...
return units;
}
我不是要求有人为我写代码,但我希望有人以前已经做过,并且它可以在一些开源库、框架、博客文章、图坦卡蒙(tut)中找到。如果失败了,如果有人有一个聪明的想法如何简化流程,那也太好了(上面链接的作者创建了一个临时div,并计算了一个值来确定其他单位的比率——这是一个方便的想法,但不是一个我完全相信的想法,而且肯定需要补充逻辑来处理我希望接受的一切)
提前感谢您提供的任何见解或建议。可以做到这一点,特别是在其解析
功能中:
function parse(prop){
var p = parseFloat(prop), q = prop.replace(/^[\-\d\.]+/,'');
return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q };
}
prop
参数是某个元素的computedStyle。返回的对象有一个v
属性(值)、一个f
方法(以后仅用于动画)和一个u
属性(值的单位,如有必要)
这并不能完全回答这个问题,但这可能是一个开始。编辑:更新以允许用户选择要返回的单个单元(例如,存在为%,返回px)-当这足够时,性能会有很大的提高-可能最终会将其更改为只接受一个单位进行转换,并消除循环。多亏了Epileless的帮助。/EDIT 这就是我所想到的——经过初步测试,它似乎起了作用。我从原始问题中提到的链接中借用了临时div的概念,但这就是从另一个类中获得的全部内容 如果有人有任何意见或改进,我很乐意听到
(function(){
// pass to string.replace for camel to hyphen
var hyphenate = function(a, b, c){
return b + "-" + c.toLowerCase();
}
// get computed style property
var getStyle = function(target, prop){
if(prop in target.style){ // if it's explicitly assigned, just grab that
if(!!(target.style[prop]) || target.style[prop] === 0){
return target.style[prop];
}
}
if(window.getComputedStyle){ // gecko and webkit
prop = prop.replace(/([a-z])([A-Z])/, hyphenate); // requires hyphenated, not camel
return window.getComputedStyle(target, null).getPropertyValue(prop);
}
if(target.currentStyle){ // ie
return target.currentStyle[prop];
}
return null;
}
// get object with units
var getUnits = function(target, prop, returnUnit){
var baseline = 100; // any number serves
var item; // generic iterator
var map = { // list of all units and their identifying string
pixel : "px",
percent : "%",
inch : "in",
cm : "cm",
mm : "mm",
point : "pt",
pica : "pc",
em : "em",
ex : "ex"
};
var factors = {}; // holds ratios
var units = {}; // holds calculated values
var value = getStyle(target, prop); // get the computed style value
var numeric = value.match(/\d+/); // get the numeric component
if(numeric === null) { // if match returns null, throw error... use === so 0 values are accepted
throw "Invalid property value returned";
}
numeric = numeric[0]; // get the string
var unit = value.match(/\D+$/); // get the existing unit
unit = (unit == null) ? "px" : unit[0]; // if its not set, assume px - otherwise grab string
var activeMap; // a reference to the map key for the existing unit
for(item in map){
if(map[item] == unit){
activeMap = item;
break;
}
}
if(!activeMap) { // if existing unit isn't in the map, throw an error
throw "Unit not found in map";
}
var singleUnit = false; // return object (all units) or string (one unit)?
if(returnUnit && (typeof returnUnit == "string")) { // if user wants only one unit returned, delete other maps
for(item in map){
if(map[item] == returnUnit){
singleUnit = item;
continue;
}
delete map[item];
}
}
var temp = document.createElement("div"); // create temporary element
temp.style.overflow = "hidden"; // in case baseline is set too low
temp.style.visibility = "hidden"; // no need to show it
target.parentNode.appendChild(temp); // insert it into the parent for em and ex
for(item in map){ // set the style for each unit, then calculate it's relative value against the baseline
temp.style.width = baseline + map[item];
factors[item] = baseline / temp.offsetWidth;
}
for(item in map){ // use the ratios figured in the above loop to determine converted values
units[item] = (numeric * (factors[item] * factors[activeMap])) + map[item];
}
target.parentNode.removeChild(temp); // clean up
if(singleUnit !== false){ // if they just want one unit back
return units[singleUnit];
}
return units; // returns the object with converted unit values...
}
// expose
window.getUnits = this.getUnits = getUnits;
})();
tyia签出,一个进行这些转换的JavaScript库
作者描述代码。晚会迟到了,我认为这不一定能完全回答这个问题,因为我没有包括百分比的转换。但是,我确实认为这是一个很好的开始,可以根据您的具体用途轻松修改 Javascript函数
/**
*将绝对CSS数值转换为像素。
*
*@linkhttps://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#numbers_lengths_and_percentages
*
*@param{string}cssValue
*@param{null | HTMLElement}目标用于相对单位。
*@return{*}
*/
window.convertCssUnit=函数(CSS值,目标){
target=target | | document.body;
const supportedUnits={
//绝对尺寸
“px”:值=>value,
“cm”:值=>值*38,
“mm”:值=>值*3.8,
“q”:值=>值*0.95,
“in”:值=>值*96,
“pc”:值=>值*16,
“pt”:值=>值*1.333333,
//相对尺寸
“rem”:value=>value*parseFloat(getComputedStyle(document.documentElement.fontSize),
“em”:value=>value*parseFloat(getComputedStyle(target).fontSize),
“vw”:值=>value/100*window.innerWidth,
“vh”:值=>value/100*window.innerHeight,
//时代
'ms':值=>value,
“s”:值=>值*1000,
//角度
“度”:值=>值,
“rad”:value=>value*(180/Math.PI),
“梯度”:值=>值*(180/200),
“转动”:值=>值*360
};
//将正数和负数(包括小数)与以下单位匹配
const pattern=new RegExp(`^([\-\+]?(?:\\d+(?:\\\.\\d+)))(${Object.keys(supportedUnits.join('\-\+')})$`i');
//如果是匹配项,则返回示例:[“-2.75rem”、“-2.75”、“rem”]
const matches=String.prototype.toString.apply(cssValue.trim().match(pattern);
如果(匹配){
常量值=数量(匹配[1]);
const unit=匹配[2]。toLocaleLowerCase();
//健全性检查,确保单位转换功能存在
if(支持单元中的单元){
返回支持的单位[单位](值);
}
}
返回css值;
};
示例用法
//将rem值转换为像素
const remExample=convertCssUnit('2.5rem');
//将时间单位(秒)转换为毫秒
const speedExample=convertCssUnit('2s');
//将角度单位(梯度)转换为度
常量emExample=convertCssUnit('200grad');
//将vw值转换为像素
const vw示例=convertCssUnit('80vw');
//将css变量转换为像素
康斯特瓦
10rem
10.2em
-0.34cm
+10.567s