Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Смена цвета div (https://javascript.ru/forum/misc/51697-smena-cveta-div.html)

Vladimir93 16.11.2014 13:58

Смена цвета div
 
Есть, допутсим три, дива. Нужно написать функцию которая будет менять их цвет через каждый интервалы времени. Эти интервалы, могут быть разными для разных дивов. Вот функция. Но, страница даже не грузится
function changeColor (a, id){
            document.getElementById("id").style.backgroundColor = getRandomColor();
            setTimeout(function() {changeColor(a, id)}, a);
        }

Здесь а - это параметр, задающей рандомное количество милисекунд(другой метод). getRandomColor() - метод создающий случайный цвет. Подскажите, что не так.

krutoy 16.11.2014 14:14

document.getElementById("id").style/document.getElementById(id).style

krutoy 16.11.2014 14:35

<html>
<head>
<meta charset="windows-1251" />
</head>
<body>
<div id="foo">foo</foo>
<script>
r=function(){return Math.round(Math.random())}
getRandomColor=function(){return r()? "grey":"black"}

changeColor=function (a, id){
            document.getElementById(id).style.background = getRandomColor()
            setTimeout(function() {changeColor(a, id)}, a);
        }

changeColor(1000, "foo")
</script>
</body>
</html>

Вообще, setInterval для таких вещей использовать логичней.

рони 16.11.2014 14:55

Цитата:

Сообщение от krutoy
setInterval для таких вещей использовать логичней

почему?

Vladimir93 16.11.2014 14:57

Да, я видел такой пример в интернете. Тут понятно. А вконтексте такой задачи
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
<body>

    <script type="text/javascript">
        var params = {
            lines: [
                {
                    background: getRandomColor(),
                    updateTime: randomNumber(1, 1000),
                    elements: [{
                        background: getRandomColor(),
                        width: 25
                    },
                        {
                            background: getRandomColor(),
                            width: 25
                        },
                        {
                            background: getRandomColor(),
                            width: 25
                        }]
                },
                {
                    background: getRandomColor(),
                    updateTime: randomNumber(1,800),
                    elements: [{
                        background: getRandomColor(),
                        width: 15
                    },
                        {
                            background: getRandomColor(),
                            width: 15
                        },
                        {
                            background: getRandomColor(),
                            width: 15
                        }]
                },
                {
                    background: getRandomColor(),
                    updateTime: randomNumber(1,1200),
                    elements: [{
                        background: getRandomColor(),
                        width: 15
                    },
                        {
                            background: getRandomColor(),
                            width: 15
                        },
                        {
                            background: getRandomColor(),
                            width: 15
                        }]
                }]
        };

        /*global document: false*/
        function getRandomColor() {
            var letters = '0123456789ABCDEF'.split('');
            var color = '#';
            for (var i = 0; i < 6; i++ ) {
                color += letters[Math.floor(Math.random() * 16)];
            }
            return color;
        }

        function randomNumber (a, b){
            a = parseInt(a);
            b = parseInt(b);
            return Math.floor( Math.random()* (b - a + 1)) + a;

        }
//        document.getElementById(id).style.backgroundColor = getRandomColor();
//        setInterval('changeColor(a, id)', a);
        function changeColor1 (a, id){
            document.getElementById(id).style.backgroundColor = getRandomColor();
            setTimeout(function() {changeColor(a, id)}, a);
        }
//        function changeColor (id){
//            document.getElementById(id).style.backgroundColor = getRandomColor();
//        }

        var a = 100/params.lines.length;
        var array = new Array();
        for (var i  = 0; i < params.lines.length; i++ ){
                 var d = document.createElement('div');
                 d.id = 'i';
                 d.style.width = 100 + '%';
                 d.style.height = a + '%';
                 d.style.backgroundColor = params.lines[i].background;
                 array.push(i);
//             changeColor1(params.lines[i].updateTime, i);
            for (var j =0; j < params.lines[i].elements.length; j++){
                     var div1 = document.getElementById('i');
                     var div2 = document.createElement('div');
                     div2.style.backgroundColor = params.lines[i].elements[j].background;
                     div2.style.float = 'left';
                     div2.style.width = params.lines[i].elements[j].width + '%';
                     div2.style.height = a + '%';
                     div2.innerHTML;
                     document.body.appendChild(div2);
                 }
                 document.body.appendChild(d);
//            setInterval(changeColor('i'),params.lines[i].updateTime);
        }

        for (var k = 0; k < array.length; k++){
            changeColor(params.lines[k].updateTime, array[k]);
        }


    </script>
    <link rel="stylesheet" type="text/css" href="CSS.css">
</body>
</head>

</html>


Нужно, чтобы нижние дивы полсе загрузки страницы меняли цвета. Пробовал и через setInterval - закомментированные. Но не выходит.

krutoy 16.11.2014 15:01

рони,
Потому что тут бесполезная рекурсия, имитирующая тупую итерацию

рони 16.11.2014 20:12

Vladimir93,
Вариант для современных браузеров ... меняет фон последних трёх div -- время из data - вопросы знатокам , почему не работает в хроме, почему не работает строка 44 без window.setTimeout и как заменить если можно window.setTimeout ... есть и ещё вопросы :) :write:
<!DOCTYPE HTML>

<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        .animated {
            transition: background-color 2s ease-out;
            width: 150px;
            height: 150px;
            margin: 10px;
            border: 1px solid black;
            display: inline-block;
            background-color: rgb(255, 255, 0);
        }
    </style>
</head>

<body>

    <div class="animated" data-duration="5s"></div>
    <div class="animated" data-duration="5s"></div>
    <div class="animated" data-duration=".7s"></div>
    <div class="animated" data-duration="8s"></div>

    <script> function randomRGBComponent() {
           return Math.round(Math.random() * 255);
       }

       function randomRGBColor() {
           return 'rgb(' + randomRGBComponent() + ', ' + randomRGBComponent() + ', ' + randomRGBComponent() + ')';
       }

       function setBackgroundColor(elem, s) {
           function go() {
               var color = randomRGBColor()
               elem.style.backgroundColor = color
           }
           elem.style.transitionDuration = s;
           elem.addEventListener('transitionend', go, false);
           go() //window.setTimeout(go, 0);
       }
       window.onload = function() {
           [].forEach.call(document.querySelectorAll('.animated:nth-last-child(-n + 4)'), function(elem, i) {
               setBackgroundColor(elem, elem.dataset.duration)
           })
       }
    </script>
</body>

</html>

Vlasenko Fedor 16.11.2014 22:29

еще вариант
<!DOCTYPE HTML>
<html>
  
  <head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
      div[id^=animated] {
        transition: background-color 0.5s ease-out;
        width: 150px;
        height: 150px;
        margin: 10px;
        border: 1px solid black;
        display: inline-block;
        background-color: rgb(255, 255, 0);
      }
    </style>
  </head>
  
  <body>
    <div id="animated1"></div>
    <div id="animated2"></div>
    <div id="animated3"></div>
    <script>
      function ColorDiv(params) {
        if (!(this instanceof ColorDiv)) {
          return new ColorDiv(params);
        }
        this.initialize.apply(this, arguments);
      }
      ColorDiv.prototype.initialize = function (params) {
        setInterval(function () {
          var letters = '0123456789ABCDEF';
          var color = '#';
          for (var i = 0; i < 6; i++) {
            color += letters.charAt(Math.floor(Math.random() * 16));
          }
          params.element.style.backgroundColor = color;
        }, params.interval);
      }

      ColorDiv({
        element: document.getElementById('animated1'),
        interval: 800
      });
      ColorDiv({
        element: document.getElementById('animated2'),
        interval: 1200
      });
      ColorDiv({
        element: document.getElementById('animated3'),
        interval: 2000
      });
    </script>
  </body>
</html>

Octane 17.11.2014 12:13

Цитата:

Сообщение от krutoy
Потому что тут бесполезная рекурсия, имитирующая тупую итерацию

Здесь нет длинного рекурсивного стека вызовов, каждый setTimeout вызывает функцию в новом стеке.

krutoy 17.11.2014 15:22

Octane,
однако это не повод писать через жопу.

Octane 17.11.2014 15:49

просроченные интервалы могут выполняться друг за другом без задержки, поэтому чаще всего используют таймауты

krutoy 17.11.2014 16:55

Octane,
Че то не верится. Какая разница? Можещь написать тестовый пример, простенький?

Octane 17.11.2014 17:05

это старая избитая тема, в интернете полно статей
Цитата:

Сообщение от John Resig
If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).

http://ejohn.org/blog/how-javascript-timers-work/
перевод: http://habrahabr.ru/post/138062/

ну и еще до кучи
http://alljs.ru/articles/timeout/setinterval

krutoy 17.11.2014 18:51

Octane,
Почему же тогда тут setInterval не перекрывает setTimeout?
st=function(){return setTimeout(function(){console.log("setTimeout"); timeoutId=st()}, 3)}
si=function(){return setInterval(function(){console.log("setInterval")}, 3)}


stop=function(){setTimeout(function() {clearTimeout(timeoutId); clearInterval(intervalId)}, 3000)}
     
stop()
timeoutId=st()
intervalId=si()
i=100000000
console.time("cycle")
while(i--){}
console.timeEnd("cycle")

//     cycle: 1796ms
//     setTimeout
//     setInterval
//     setTimeout
//     setInterval
//     setTimeout
//     setInterval
//     ...

Octane 17.11.2014 20:12

мне лень писать test case)

Resig говорит про время исполнения колбека, наверное как-то так http://habrahabr.ru/post/138062/#comment_4604133 пример будет выглядеть

danik.js 17.11.2014 23:21

Цитата:

Сообщение от krutoy
однако это не повод писать через жопу.

Да оба варианта через жопу))
В идеале тут нужно использовать requestAnimationFrame. К слову, схема его использования схожа именно с setTimeout.

danik.js 17.11.2014 23:39

Цитата:

Сообщение от рони
почему не работает в хроме

В хроме не отрабатывает такой селектор внутри ноды пока не завершится парсинг ноды. А скрипт, как известно, приостанавливает процесс парсинга.
Вообще, выглядит как баг. Видимо, побочный эффект от оптимизаций.

danik.js 17.11.2014 23:51

function randomRGBColor() {
    return Math.round(Math.random() * 0xFFFFFF).toString(16);
}


Вот такой вот HEX вариант )

рони 17.11.2014 23:53

Цитата:

Сообщение от danik.js
Вот такой вот HEX вариант )

не катит

рони 17.11.2014 23:55

Цитата:

Сообщение от danik.js
В хроме не отрабатывает такой селектор внутри ноды пока не завершится парсинг ноды

ок добавил window.onload таймер стал ненужен, вот тебе и ставьте скрипт в конце body

danik.js 17.11.2014 23:58

Цитата:

Сообщение от рони
почему не работает строка 44 без window.setTimeout и как заменить если можно window.setTimeout

Если задать transition и тут же задать трансформируемое свойство - оно применится без трансформаций. Потому как стили, так сказать, обновляются транзакциями.

Чтобы завершить "транзакцию", нужно вызвать рекалькуляцию (вроде бы) стилей. Допустим обратившись к offsetWidth элемента. Честно говоря не знаю как правильно делать.

danik.js 17.11.2014 23:59

Цитата:

Сообщение от рони
не катит

Решетку забыл)
function randomRGBColor() {
return '#' + Math.round(Math.random() * 0xFFFFFF).toString(16);
}

рони 18.11.2014 00:02

Цитата:

Сообщение от danik.js
Решетку забыл)

не из - за этого -- я проверял этот вариант пришлось отказаться - при выдаче 5 цифр скрипт падает

danik.js 18.11.2014 00:04

Цитата:

Сообщение от рони
добавил window.onload таймер стал ненужен, вот тебе и ставьте скрипт в конце body

Во-первых, скрипты надо ставить туда не для того, чтобы обойтись без load события, а чтобы не блокировать отображение страницы.

Ну а во-вторых, покажи пожалуйста живой сайт, где применяется твой селектор для выборки в querySelector?

danik.js 18.11.2014 00:11

Цитата:

Сообщение от рони
не из - за этого -- я проверял этот вариант пришлось отказаться

Да, уже понял. Косяк конечно. Надо еще pad функцию, чтоб выравнивать нулями.


function randomRGBColor() {
    return '#' + ('000000' + Math.round(Math.random() * 0xFFFFFF).toString(16)).slice(-6);
}


:dance:

Был бы метод String.prototype.padLeft - получилось бы гораздо лучше.
Ну вот почему его нет? Почему методов встроенных - кот наплакал?

danik.js 18.11.2014 00:13

Цитата:

Сообщение от рони
вот тебе и ставьте скрипт в конце body

Репорть в багтреккер - посмотрим че скажут. Хотя возможно придется пару лет этого ждать )

рони 18.11.2014 00:21

danik.js,
может подскажешь как в firebug firefox редактировать скрипт есть ли вобще там такая возможность, чтоб увидеть изменения на лету -- чтоб обновил страницу и она подхватила внесённые изменения и как потом вернутся к исходному состоянию скрипта.
(в гугле да забанили, может со слов быстрее пойму)

danik.js 18.11.2014 00:25

Цитата:

Сообщение от рони
может подскажешь

нет.

рони 18.11.2014 00:26

Цитата:

Сообщение от danik.js
нет.

:cray: ок

krutoy 18.11.2014 00:28

рони,
почему бы тебе не редактировать локальную HTML-страницу, и после сохранения просто обновлять (в любом браузере). Чем это будет отличаться от того, что ты хочешь? Тем что между окнами надо переключаться?

рони 18.11.2014 00:41

krutoy,
не понял ??? работать с блокнотом я умею, но хотелось бы освоить консоль, чтоб там править.
ищу кнопку как в опере "Применить изменения"
в других браузерах firefox и Google Chrome

krutoy 18.11.2014 01:14

рони,
Я не понимаю, зачем править в консоли, если можно править исходник. Результат тот же самый, только без гемороя.

krutoy 18.11.2014 01:20

рони,
Вообще, в файерфоксе, в файербаге, в консоли, снизу, есть поле. Если туда ввести что-нибудь, например, переопределить функцию, и нажать энтер, то эти изменения применяются. До перезагрузки. В хроме, по-моему, тоже есть нечто подобное. Это не то что ты хочешь, конечно, но отчасти.

рони 18.11.2014 01:25

krutoy,
а я непонимаю вас - зачем мне копировать страницу из интернета чтоб узнать заработает ли она если гипотетически в 8 строке поставить запятую

рони 18.11.2014 01:26

krutoy,
Цитата:

Opera включает несколько инструментов, которые могут помочь веб-разработчикам.

Консоль разработчика - это инструмент для анализа и интерактивного изменения веб-страницы во время разработки или отладки, тогда как программа просмотра исходных текстов является более простым инструментом для проверки исходного кода веб-страницы и быстрого внесения небольших изменений.

мне это же нужно но в других браузерах

krutoy 18.11.2014 01:27

рони,
А, из интернета. Тогда понятно. Я думал, речь идет про локальные файлы.


Часовой пояс GMT +3, время: 21:35.