Javascript - анимация останавливается при запуске новой - PullRequest
0 голосов
/ 27 октября 2010

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

Я настроил тестовую страницу, чтобы продемонстрировать это: http://anttears.co.uk/test (тестовая страница была протестирована только в FF)

Помещение console.log в функцию setOpacity для значения elem, похоже, показывает, что javascript работает должным образом - оба li достигают opacity = 1 Тем не менее, первый li кажется фрагментом, не связанным с фактическим DOM.

Я сознательно пытаюсь заставить это работать без обычных библиотек, как опыт обучения.

Любая помощь с благодарностью ... Ant

1 Ответ

1 голос
/ 27 октября 2010
this.prepend = function(string, elem) {
    var content = elem.innerHTML;
    content = string + content;
    elem.innerHTML = content;
}

Никогда не делай этого.

Вы берете содержимое DOM elem (growlList), сериализуете его в новую строку HTML, добавляете часть содержимого HTML и анализируете объединенный HTML обратно в совершенно новые узлы DOM. Это приводит к потере всего контента, не относящегося к сериализуемому HTML, например значений полей формы, обработчиков событий и ссылок JavaScript. Анимация по-прежнему имеет ссылку на старый узел HTMLElement, которого больше нет в DOM, поскольку он был заменен на элементы new-parsed-from- content.

В самом деле, вы обычно хотите вообще не генерировать строки HTML:

growl = '<li id="' + gid + '" class="' + className + ' growl" style="display: none"><span class="close" title="close">x</span><h2>' + heading + '</h2><div class="growlContent">' + content + '</div></li>',

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

Вместо этого используйте методы в стиле DOM, например:

var span= document.createElement('span');
span.className=span.title= 'close';
span.appendChild(document.createTextNode('x'));
var h2= document.createElement('h2');
h2.appendChild(document.createTextNode(heading));
var div= document.createElement('div');
div.className= 'growlContent';
div.appendChild(document.createTextNode(content))

var li= document.createElement('li');
li.id= gid;
li.className= className;
li.appendChild(span);
li.appendChild(h2);
li.appendChild(div);

gl.insertBefore(li, gl.firstChild);

Это довольно многословно, но легко написать вспомогательную функцию для сокращения при наборе текста, например:

gl.insertBefore(el('li', {id: gid, className: className), [
    el('span', {className: 'close', title: 'close'}, 'x'),
    el('h2', {}, heading),
    el('div', {className: 'growlContent'}, content)
]), gl.firstChild);


// Element creation convenience function
//
function el(tag, attrs, content) {
    var el= document.createElement(tag);
    if (attrs!==undefined)
        for (var k in attrs)
            if (attrs.hasOwnProperty(k))
                el[k]= attrs[k];
    if (content!==undefined) {
        if (typeof(content)==='string')
            el.appendChild(document.createTextNode(content));
        else
            for (var i= 0; i<content.length; i++)
                el.appendChild(content[i]);
    }
    return el;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...