코드스피츠 css rendering 3회차 part2 (step 41) - style 클래스 생성
CSS 관련한 프레임워크를 만들어보기
목표
- vendor prefix 해결 => 웹브라우저 마다 prefix를 붙여야 그나마 다른 방식의 지원을 막을 수 있는 것 같다.
- css 동적 조정
vendor prefix란?
웹 브라우저 공급자가 새로운 실험적인 기능을 제공할 때 이전 버전의 웹 브라우저에 그 사실을 알려주기 위해 사용하는 접두사(prefix)를 의미
html과 다르게 css는 웹표준이 정해지지않아 브라우저에 따른 다른 방식이 지원된다.
따라서 css를 원활히 사용하기 위해 스타일 속성 앞에 prefix(접두사)를 붙여야한다.
(vendor는 노점상 이런뜻인데 브라우저를 고객에게처럼 prefix를 붙여서 해라 이런건가 개인적으로 혼자 생각)
프레임워크 구조
- style (cssStyleDeclare)
- rule (cssRule)
- css (styleSheet)
style
const Style = ((_) => {
const prop = new Map, prefix = 'webkt,moz,ms,chrome,o,khtml'.split(',');
const NONE = Symbol();
const BASE = document.body.style;
const getKey = (key) => {
if(prop.has(key)) return prop.get(key);
if(key in BASE) prop.set(key, key);
else if(!prefix.some(v =>{
// prefix를 붙인 속성은 존재하는가?를 알아볼 차례
// 메소드 some의 인수인 callback 함수 부분이다.
// webkitBackground 이런식으로 속성명 첫글자가 대문자이므로 표준 key인 background의 앞에 vendor prefix를 붙이고 대문자로 바꾸고 나머지 뒤인 'ackground'를 붙여주는 작업이 필요하다.
const newKey = v + key[0].toUpperCase() + key.substr(1);
if(newKey in BASE){ // prefix붙인 속성이 body에 있다면,
prop.set(key, newKey); // border-radius 부르면 prefix를 붙인 진짜 이름을 캐시에 저장
key = newKey; // 리턴할 key는 더이상 원래 키가 아니라 newKey
return true; // 진짜 이름을 찾았으니 여기서 끊어 라는것. some을 더 돌지 않아도 된다고 끊어버리는 것이다.
}
else return false;
})){
// some의 결과가 false일 경우에만 여기에 들어온다.
prop.set(key, NONE);
key = NONE;
}
return key; // 그냥 key가 리턴되든지, newKey가 리턴되든지, NONE이 리턴될 것임
}; // end of getKey()
return class {
constructor(style) {
this._style = style;
} // 생성자에 style객체를 준다. 이 클래스는 style 객체를 안고 태어난다.
// 키를 얻기(스타일 시트에 있는 background라는 값을 얻고싶다면?)
get(key) {
key = getKey(key); // 반드시 getKey에 보내서 진짜 이름을 얻어야 한다.
if (key === NONE) return null; // 브라우저가 지원하지 않는 경우 부드럽게 null을 리턴하기 // Unsupported Property 문제 해결!
return this._style[key]; // 이름이 있다면 진짜 이름으로 style객체에 해당 속성값을 가져오자
}
set(key, val) {
key = getKey(key);
// key가 NONE이 아니면
if (key !== NONE) this._style[key] = val; // 값을 설정
// NONE이면 스타일을 아예 건들지 않는다(Graceful Fail)
return this; // set을 계속 호출하는 경우가 많아서 set을 쓸 수 있게 this를 리턴
}
};
})();
getKey : prop에 이미 key가 있다면 get을 통해 가져오고 document.body.style에서 해당 style과 관련한 것이 있다면 이를 set메소드로 적용시키고 둘다 아니라면 해당 prefix를 붙인 것이 존재하는가를 확인하여 있다면 set메소드를 작동시키고 true를 리턴하고 아니라면 false를 리턴한다. 그후 최종 key를 리턴
const BASE = document.body.style;
을 통해 비교해야할 대상을 정하는데 모든 브라우저가 가지고 있는 document 의 body 의 style을 통해 vendor prefix가 있는지를 확인할 수 있다.
style class 적용해보기
<html>
<head lang="en">
<meta charset="UTF-8">
<style id='s'>
.test{background:#ff0; width:200px;}
</style>
<body>
<div class="test">a</div>
</body>
<script>
const Style = (...) //위의 내용 참조
const el = document.querySelector('#s');
const sheet = el.sheet;
const rules = sheet.cssRules;
const rule = rules[0];
const style = new Style(rule.style);
style.set('borderRadius','200px')
.set('boxShadow','0 0 0 10px red')
</script>
</html>
-
결과
기존에 있었던 rule에서의 style부분을 적용한
style
변수를 만들어 내고 해당 변수에set
메소드를 적용시켜 모서리를 둥글게 하였고 10px의 빨간 테두리를 적용시켰다.
출처
210619 추가내용
const prop = new Map, prefix = 'webkt,moz,ms,chrome,o,khtml'.split(',');
const NONE = Symbol();
const BASE = document.body.style;
const getKey = (key) => {
if(prop.has(key)) return prop.get(key);
if(key in BASE) prop.set(key, key);
else if(!prefix.some(v =>{
const newKey = v + key[0].toUpperCase() + key.substr(1);
if(newKey in BASE){
prop.set(key, newKey);
key = newKey;
return true;
} else return false;
})){
prop.set(key, NONE);
key = NONE;
}
return key;
};
class Style {
constructor(style) {
this._style = style;
} // 생성자에 style객체를 준다. 이 클래스는 style 객체를 안고 태어난다.
// 키를 얻기(스타일 시트에 있는 background라는 값을 얻고싶다면?)
get(key) {
key = getKey(key); // 반드시 getKey에 보내서 진짜 이름을 얻어야 한다.
if (key === NONE) return null; // 브라우저가 지원하지 않는 경우 부드럽게 null을 리턴하기 // Unsupported Property 문제 해결!
return this._style[key]; // 이름이 있다면 진짜 이름으로 style객체에 해당 속성값을 가져오자
}
set(key, val) {
key = getKey(key);
// key가 NONE이 아니면
if (key !== NONE) this._style[key] = val; // 값을 설정
// NONE이면 스타일을 아예 건들지 않는다(Graceful Fail)
return this; // set을 계속 호출하는 경우가 많아서 set을 쓸 수 있게 this를 리턴
}
};
위와같이도 가능은 한다.
Author And Source
이 문제에 관하여(코드스피츠 css rendering 3회차 part2 (step 41) - style 클래스 생성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@khw970421/코드스피츠-css-rendering-3회차-part2-step-41저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)