지금까지 JavaScript를 사용하다 보면 html 파일안에 <script>태그를 <head>에 넣었는데 


해외 예제를 보던중 지금까지 했던 방식으로 했더니 동작이 안되는것이였다.


예제는 [Automatically Maximize Text Contrast On A Page] 였는데, ColorPicker를 이용 background를 비동기적으로 변경하는 예제였다.


소스참조


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script>
        function splitComponent(color) {
            var rgbColors = new Object();
            color = color.substring(color.indexOf('(') + 1, color.indexOf(')'));
            var result = color.split(',', 3);
            return result ? {
                r: parseFloat(result[0] / 255),
                g: parseFloat(result[1] / 255),
                b: parseFloat(result[2] / 255)
            } : null;
        }
        var gamma = 2.2,
        test = document.getElementById("test");
        function changeBG(colorValue) {
            test.style.backgroundColor = colorValue;
            var computedStyle = getComputedStyle(test, null);
            var bgColor = computedStyle.backgroundColor;
            var luminosity = 0.2126 * Math.pow(splitComponent(bgColor).r, gamma) + 0.7152 * Math.pow(splitComponent(bgColor).g, gamma) + 0.0722 * Math.pow(splitComponent(bgColor).b, gamma);
            if (luminosity < 0.5) { test.style.color = "#fff" } else { test.style.color = "#000" }
        }
    </script>
    <style>
        #test { background-color: #332; color: #fff; font-family: Avenir, sans-serif; padding: 2rem; text-align: center; }
    </style>
</head>
<body>
    <div id="test">
        <h1>I SHALL ALWAYS REMAIN LEDGIBLE</h1>
        <label for="bgcolor" >Set the background color for this element:</label>
        <input type="color" value="#777777" id="testbg" name="testbg" oninput="changeBG(testbg.value)" />
    </div>
</body>
</html>


이렇게 하고 돌렸는데 안먹힌다... 크롬에서는 요렇게!

 


test가 null 이라고 뜬다. 함수를 못불러오는거다. html 이 로딩이 안된것처럼 받아들인다는것...


한참동안 끙끙거리고 있다가 문득 책에서 <script>태그의 위치는 html파일의 로딩이 끝난뒤 불러오는 </body>의 바로 윗쪽에 위치시키는것이 좋은 습관이다 라는걸 생각해내서 위치를 바꿔봤다!



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    
    
    <style>
        #test { background-color: #332; color: #fff; font-family: Avenir, sans-serif; padding: 2rem; text-align: center; }
    </style>
</head>
<body>
    <div id="test">
        <h1>I SHALL ALWAYS REMAIN LEDGIBLE</h1>
        <label for="bgcolor" >Set the background color for this element:</label>
        <input type="color" value="#777777" id="testbg" name="testbg" oninput="changeBG(testbg.value)" />
    </div>
</body>
    <script>
        function splitComponent(color) {
            var rgbColors = new Object();
            color = color.substring(color.indexOf('(') + 1, color.indexOf(')'));
            var result = color.split(',', 3);
            return result ? {
                r: parseFloat(result[0] / 255),
                g: parseFloat(result[1] / 255),
                b: parseFloat(result[2] / 255)
            } : null;
        }
        var gamma = 2.2,
        test = document.getElementById("test");
        function changeBG(colorValue) {
            test.style.backgroundColor = colorValue;
            var computedStyle = getComputedStyle(test, null);
            var bgColor = computedStyle.backgroundColor;
            var luminosity = 0.2126 * Math.pow(splitComponent(bgColor).r, gamma) + 0.7152 * Math.pow(splitComponent(bgColor).g, gamma) + 0.0722 * Math.pow(splitComponent(bgColor).b, gamma);
            if (luminosity < 0.5) { test.style.color = "#fff" } else { test.style.color = "#000" }
        }
    </script>
</html>


정상적으로 동작한다.

<script>의 위치가 <body>를 모두 읽어온 후에 읽어야 제대로 동작하던데...

페이지의 로딩 속도 측면에서도 <script>태그를 하단에 위치시켜야 속도향상에도 도움이 된다.

그 이유인즉슨... 보통 <script>외부 태그나 외부적으로 다운로드하게 되는데 <script>파일의 크기가 크거나 혹은 정상 다운로드가 되지 않으면 html 파일이 정상적으로 로딩되지않게되어 화면이 뜨지 않거나 늦게 뜨게 된다. 

이런 점을 고려해 속도 향상을 하려면 <script>태그(html 내용이 전부 읽히고 나서 후에 실행되는 함수내용들)는 </html>의 바로 윗부분에 위치시키는게 좋다.


하지만 html태그가 읽히기전에 수행되어야하는 <script>태그들은 윗부분에 위치시켜야 한다.또한 jQuery같이 여러 페이지에서 같이 동작해야 하는 것들도 <head>태그에 놓는게 좋다.


추가로 <css>는 항상 <head>태그 사이에 위치시켜야 한다. 하단에 위치시키게되면 html 파일을 두번 읽어서 적용시킨다.