Ошибка DOM 8 в removeChild для div

Я немного новичок и знаю, что мой код не самый лучший, но я учусь. Я собираю несколько анимаций последовательности изображений, которые запускаются как функции при возникновении событий. Нажмите кнопку, анимация. Наведите курсор на div, анимация. И Т. Д.

Я думаю, что проблема, с которой я сталкиваюсь, заключается в том, что анимация прерывается. Я получаю «Uncaught Error: NOT_FOUND_ERR: DOM Exception 8» во втором else if walk_div.removeChild(img);

Затем последовательность изображений начинает по существу мигать. Любая помощь?

function loadUp(){
var cyclenum = 175;
var folder = "animations/rollO/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

function animation(){
count++;
subCount = count - 1;

    if(count == cyclenum){
        clearInterval(walkAnimate);
    }
    else if(count == 1){
        subCount = 2;
        img.src = folder + subCount + imgType;
        walk_div.removeChild(initialImg);
        walk_div.appendChild(img);
        count = 2;      
    }
    else if (count < cyclenum){
        img.src = folder + subCount + imgType;
        walk_div.removeChild(img);      
        img.src = folder + count + imgType;
        walk_div.appendChild(img);
    }
}

var walkAnimate = setInterval(animation, 42);
}

function preAction(){   
var cyclenum = 30;
var folder = "animations/pre/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
//Clears out the walk div
var rmv = document.getElementById('begin');
if (rmv.hasChildNodes()){
    while (rmv.childNodes.length >= 1)
    {
        rmv.removeChild(rmv.firstChild);
    }
}
//end clear
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

    function animation(){
    count++;
    subCount = count - 1;

        if(count == cyclenum){
            clearInterval(walkAnimate);
        }
        else if(count == 1){
            subCount = 2;
            img.src = folder + subCount + imgType;
            walk_div.removeChild(initialImg);
            walk_div.appendChild(img);
            count = 2;      
        }
        else if (count < cyclenum){
            img.src = folder + subCount + imgType;
            walk_div.removeChild(img);      
            img.src = folder + count + imgType;
            walk_div.appendChild(img);
        }
    }

    var walkAnimate = setInterval(animation, 42);
}

function nextAction(){  
var cyclenum = 30;
var folder = "animations/next/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
//Clears out the walk div
var rmv = document.getElementById('begin');
if (rmv.hasChildNodes()){
    while (rmv.childNodes.length >= 1)
    {
        rmv.removeChild(rmv.firstChild);
    }
}
//end clear
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

    function animation(){
    count++;
    subCount = count - 1;

        if(count == cyclenum){
            clearInterval(walkAnimate);
        }
        else if(count == 1){
            subCount = 2;
            img.src = folder + subCount + imgType;
            walk_div.removeChild(initialImg);
            walk_div.appendChild(img);
            count = 2;      
        }
        else if (count < cyclenum){
            img.src = folder + subCount + imgType;
            walk_div.removeChild(img);      
            img.src = folder + count + imgType;
            walk_div.appendChild(img);
        }
    }

    var walkAnimate = setInterval(animation, 42);
}

function galleryRightIn(){  
var cyclenum = 15;
var folder = "animations/galleryRIn/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
//Clears out the walk div
var rmv = document.getElementById('begin');
if (rmv.hasChildNodes()){
    while (rmv.childNodes.length >= 1)
    {
        rmv.removeChild(rmv.firstChild);
    }
}
//end clear
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

    function animation(){
    count++;
    subCount = count - 1;

        if(count == cyclenum){
            clearInterval(walkAnimate);
        }
        else if(count == 1){
            subCount = 2;
            img.src = folder + subCount + imgType;
            walk_div.removeChild(initialImg);
            walk_div.appendChild(img);
            count = 2;      
        }
        else if (count < cyclenum){
            img.src = folder + subCount + imgType;
            walk_div.removeChild(img);      
            img.src = folder + count + imgType;
            walk_div.appendChild(img);
        }
    }

    var walkAnimate = setInterval(animation, 42);
}

function galleryRightOut(){ 
var cyclenum = 15;
var folder = "animations/galleryROut/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
//Clears out the walk div
var rmv = document.getElementById('begin');
if (rmv.hasChildNodes()){
    while (rmv.childNodes.length >= 1)
    {
        rmv.removeChild(rmv.firstChild);
    }
}
//end clear
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

    function animation(){
    count++;
    subCount = count - 1;

        if(count == cyclenum){
            clearInterval(walkAnimate);
        }
        else if(count == 1){
            subCount = 2;
            img.src = folder + subCount + imgType;
            walk_div.removeChild(initialImg);
            walk_div.appendChild(img);
            count = 2;      
        }
        else if (count < cyclenum){
            img.src = folder + subCount + imgType;
            walk_div.removeChild(img);      
            img.src = folder + count + imgType;
            walk_div.appendChild(img);
        }
    }

    var walkAnimate = setInterval(animation, 42);
}

function galleryBackIn(){   
var cyclenum = 15;
var folder = "animations/galleryBIn/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
//Clears out the walk div
var rmv = document.getElementById('begin');
if (rmv.hasChildNodes()){
    while (rmv.childNodes.length >= 1)
    {
        rmv.removeChild(rmv.firstChild);
    }
}
//end clear
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

    function animation(){
    count++;
    subCount = count - 1;

        if(count == cyclenum){
            clearInterval(walkAnimate);
        }
        else if(count == 1){
            subCount = 2;
            img.src = folder + subCount + imgType;
            walk_div.removeChild(initialImg);
            walk_div.appendChild(img);
            count = 2;      
        }
        else if (count < cyclenum){
            img.src = folder + subCount + imgType;
            walk_div.removeChild(img);      
            img.src = folder + count + imgType;
            walk_div.appendChild(img);
        }
    }

    var walkAnimate = setInterval(animation, 42);
}

function galleryBackOut(){  
var cyclenum = 15;
var folder = "animations/galleryBOut/";
var imgType = '.png';
var count = 0;
var subCount = 1;
var initialImg = new Image();
initialImg.src = folder + '1.png';
//Clears out the walk div
var rmv = document.getElementById('begin');
if (rmv.hasChildNodes()){
    while (rmv.childNodes.length >= 1)
    {
        rmv.removeChild(rmv.firstChild);
    }
}
//end clear
var walk_div = document.getElementById('begin');
var img = new Image();
walk_div.appendChild(initialImg);

    function animation(){
    count++;
    subCount = count - 1;

        if(count == cyclenum){
            clearInterval(walkAnimate);
        }
        else if(count == 1){
            subCount = 2;
            img.src = folder + subCount + imgType;
            walk_div.removeChild(initialImg);
            walk_div.appendChild(img);
            count = 2;      
        }
        else if (count < cyclenum){
            img.src = folder + subCount + imgType;
            walk_div.removeChild(img);      
            img.src = folder + count + imgType;
            walk_div.appendChild(img);
        }
    }

    var walkAnimate = setInterval(animation, 42);
}

РЕДАКТИРОВАТЬ: Прежде всего, спасибо за ответ!

Часть проблемы с использованием setAnimationFrame заключается в том, что он ненадежен в IE. У меня также есть последовательности изображений не более 175 кадров, поэтому сопоставление одного гигантского изображения кажется большой работой, но, по крайней мере, теперь я знаю, что могу сделать даже это. Может пригодится для других проектов.

Эти анимации имеют очень специфический старт и остановку. Мультфильм указывает на различные элементы, когда пользователь взаимодействует с веб-страницей. В итоге я удалил firstChild из div. Я понял, что вызываю конкретное изображение, и поэтому, когда его не было, анимация прерывалась, поэтому я получил DOM 8. Теперь он работает намного лучше.

Что мне нужно сделать сейчас, так это остановить анимацию, когда начнется другая. Я обнаружил, что вы не можете сделать это с помощью Javascript. Я могу очистить интервал, но они должны быть глобальными, и я еще не понял, как это сделать. Моя единственная другая мысль - запустить их в отдельных div и скрыть или показать в зависимости от активной функции. Однако это означает, что анимация продолжает работать... только в фоновом режиме. За исключением вступительной анимации, это всего 30 кадров, и я сделал изображения крошечными по размеру файла, но этого много, чтобы продолжать работать. Я буду использовать его в крайнем случае, но я бы предпочел найти лучший способ.

РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ:

В итоге я использовал ту же практику с изображениями — добавлял и удалял div, в котором запускается анимация. Я понимаю, что это, вероятно, не самый элегантный способ сделать это, но пока все не станет немного более стандартным (кашель IE кашель) придется сделать. Он также работает во всех основных браузерах, даже с поддержкой IE7.

Я ценю, что вы все нашли время!


person Akexis    schedule 25.02.2013    source источник
comment
Просто чтобы вы знали, лучше всего не использовать setInterval(). На самом деле это не означает, что ваш код будет выполняться через эти промежутки времени. Прочтите мой ответ здесь: title="как я могу остановить вызов ajax, поддерживающий сеанс php"> stackoverflow.com/questions/6759058/   -  person Charles Addis    schedule 26.02.2013
comment
@CharlesAddis - лучшее относительно, по каким критериям оно измеряется?   -  person RobG    schedule 26.02.2013
comment
@RobG Потому что в данном случае целью является анимация, и setAnimationFrame был разработан для этой цели. Он превосходен тем, что позволяет браузеру узнать причину таймера, поэтому, когда анимация не требуется (например, вкладка не активна или мобильное приложение скрыто), ему не нужно запускать обратный вызов. Принимая во внимание, что setTimeout/Interval будет постоянно срабатывать (в некоторых случаях медленнее), даже если в этом нет необходимости. Кроме того, requestAnimationFrame правильно синхронизируется с обновлением кадра, что уменьшает проблемы, вызванные проблемами синхронизации, такими как задержка ввода.   -  person Nimphious    schedule 26.02.2013


Ответы (1)


Ошибка DOM 8 означает, что не удалось найти элемент, который вы пытаетесь удалить. Вы пытаетесь удалить несуществующий элемент.

Вам нужно либо определить необходимость удаления элемента другим способом, либо использовать другой метод для обнаружения самого элемента.

Однако все это даже не имеет значения, потому что то, что вы пытаетесь сделать, делается намного лучше другим способом. Вместо того, чтобы создавать и уничтожать такие элементы, вы должны либо использовать полосу изображения, либо изменить положение фона следующим образом:

// Wait for the window load event and start the animation.
window.addEventListener('load', init, false);

var frame = 0; // Current frame
var frames = 8; // Frame count
var frameWidth = 64; // Frame dimensions
var frameHeight = 64;
var element; // DOM element to animate

function init() {
    // Fetch the dom element.
    element = document.getElementById('anim');
    // Begin the animation. Ideally you would use requestAnimationFrame but I'm
    // using setInterval for simplicity.
    setInterval(animate, 120);
}

function animate() {
    // Increment the frame number.
    frame = (frame + 1) % frames;
    // Set the element's backgroundPosition to "0px -#px" according to the frame
    // number and size.
    element.style.backgroundPosition = '0px -' + (frame * frameHeight) + 'px';
    // You use negative dimensions here because it's an offset of the background
    // image, and moving the image up requires negative dimensions, since
    // positive on the Y-axis is down.
}

Вы можете увидеть, как это работает здесь: http://jsfiddle.net/xfYk6/

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

person Nimphious    schedule 26.02.2013