2016-05-29 1 views
-1

Я хочу, чтобы функция Jquery была преобразована в JS, и у меня возникли проблемы с ее реализацией. Код JQuery закомментирован, он работает точно так, как должен. Основная функция принимает параметр с выбранным параметром в меню выбора (обязательно выберите параметр LeftAndZoom), а затем примените выбранную анимацию к контейнеру.Преобразование кода JQuery в ванильный JS, метод выделения значения параметра и метод 'один' не работает

Это основная функция, я просто не могу понять, как преобразовать ее в JS.

$('#imageContainer').removeClass().addClass(x + ' animation').one 
('webkitAnimationEnd mozAnimationEnd MSAnimationEnd 
oanimationend animationend', function(){ 
    $(this).removeClass(); 
}); 

Это JS Я до сих пор пробовал много вещей, но пока не помог.

function testAnim(x) { 
var container = document.getElementById("imageContainer"). 
container.className = ""; 
container.classList.add(x + ' animation'); 
this.container.className = ""; 
} 

Я знаю, что это не может работать, но это все же лучше, чем я пробовал.

И это функция accompaigning, чтобы извлечь значение параметра из списка опций:

$(document).ready(function(){ 
$('.triggerAnimation').click(function(e){ 
    e.preventDefault(); 
    var anim = $('.jsanimations').val(); 
    testAnim(anim); 
}); 

$('.js--animations').change(function(){ 
    var anim = $(this).val(); 
    testAnim(anim); 
}); 
}); 

My JS для этого:

var trigger = document.querySelector(".triggerAnimation"); 
var JSanimation = document.querySelector(".js--animations"); 

trigger.addEventListener('click', function(e){ 
e.preventDefault(); 
var anim = JSanimation.options[this.selectedIndex].innerText; 
testAnim(anim); 
JSanimation.addEventListener("change", function(){ 
var anim = this.options[this.selectedIndex].innerText; 
}); 

});

Главная проблема здесь есть, я не знаю, как реализовать эквивалентный метод JS «один», как сохранить «этот» контекст и как добавить функцию обратного вызова в «один» метод

А В верхней части этого, я получаю сообщение об ошибке «Некопать TypeError: Невозможно прочитать свойства» «null»

Похоже, что выбор значения параметра также не работает.

Ссылка на перо:

http://codepen.io/damianocel/pen/KdobyK

+0

Пожалуйста, разместите ваш код ошибки непосредственно в этом вопросе. –

+0

Есть ли причина, по которой у вас есть два дефиса в классе для второго вызова 'querySelector'? 'js - animations', похоже, не в вашем HTML, а' jsanimations' есть. Это будет учитывать TypeError. –

+0

@squint, я нашел этот код в другом месте давным-давно, и ... никогда не имел смысла для меня, но он работал с кодом jquery. Я знаю, это странно. Но изменение этого не помогает. –

ответ

1

Что касается создания "один" типа функции, вот один из способов:

function bindOne(el, evtTypes, callback, captures) { 
    var allEvents = evtTypes.trim().split(/\s+/) 

    allEvents.forEach(function(evtType) { 
    el.addEventListener(evtType, function boundFn() { 
     this.removeEventListener(evtType, boundFn, captures) 

     callback.call(this, event) 
    }, captures) 
    }) 
} 

Функция определяет параметры 4 ...

  • el является связанным элементом
  • evtTypes пространство строка с разделителями типов событий, которые будут связаны
  • callback Ваш обработчик события
  • captures указывает, если вы хотите барботирования или захвата для этого события. Обычно вы можете просто оставить это.

Пути он держит правильное this значения в том, что он вызывает ваш обратный вызов с помощью .call(), который позволяет вручную установить значение this в вызываемой функции.

Итак, вы используете его так:

function testAnim(x) { 
    var el = document.querySelector("#imageContainer") 
    el.className = "" 
    el.classList.add(x + ' animation') 

    bindOne(el, 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd' + 
            ' oanimationend animationend', function() { 
    this.className = "" 
    }); 
} 

Ваш TypeError просто потому, что нет js--animations класса в вашем HTML. Должно быть jsanimations.


Кроме того, я бы, вероятно, сделать ваши bindOne ручка браузера префиксы для вас. Таким образом вам нужно пройти только 'animationend', и ваша функция также может отменить их все.

var needsPrefixes = { 
    animationend: true 
    // can add others as needed 
} 

var prefixes = ["webkit", "moz", "ms", "o"] 

function bindOne(el, evtTypes, callback, captures) { 
    var allEvents = evtTypes.trim().split(/\s+/) 

    allEvents.forEach(function(evtType) { 
    var doPrefixes = needsPrefixes[evtType.toLowerCase()] 

    if (doPrefixes) { 
     prefixes.forEach(function(prefix) { 
     el.addEventListener(prefix + evtType, boundFn, captures) 
     }) 
    } 

    el.addEventListener(evtType, boundFn, captures) 

    function boundFn() { 
     if (doPrefixes) { 
     prefixes.forEach(function(prefix) { 
      this.removeEventListener(prefix + evtType, boundFn, captures) 
     }, this) 
     } 

     this.removeEventListener(evtType, boundFn, captures) 

     callback.call(this, event) 
    } 
    }) 
} 
+0

Это красивый код, спасибо большое. Однако есть проблема, я получаю «Не могу прочитать свойство« innerText »неопределенного». Да, я пробовал как js - анимацию, так и jsanimations. Когда я меняю это на правильное, я получаю «Невозможно прочитать свойства» «null». Это потому, что «это» может быть вне контекста? –

+0

@damianocelent: в обработчике событий, связанном с 'trigger', значением' this' будет кнопка 'triggerAnimations', а не список выбора. '.selectedIndex' должен поступать из' JSanimation', например ... 'JSanimation.options [JSanimation.selectedIndex]' –

+0

... не уверен, почему '' .js - анимация '' работает и '. .jsanimations" ' не делает. Пожалуй, используйте тот, который работает. –

Смежные вопросы