У меня возникли проблемы с преобразованием javascript из статического сайта в приложение rails.
Javascript изначально находился в файле main.js, расположенном в той же папке (app / assets / javascripts / channel), что и application.js
Когда произошла ошибка, я скопировал и вставил весь javascript в application.js, и ошибка сохранилась.
Проблема в том, что «Компоненты вкладок» не работают должным образом.
Вот код для application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery-ui
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
console.log('apps')
$(function () {
const doc = document.documentElement
doc.classList.remove('no-js')
doc.classList.add('js')
// Reveal animations
if (document.body.classList.contains('has-animations')) {
/* global ScrollReveal */
const sr = window.sr = ScrollReveal()
sr.reveal('.hero-title, .hero-paragraph, .hero-cta', {
delay: 150,
duration: 1000,
distance: '60px',
easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
origin: 'bottom',
interval: 150
})
sr.reveal('.hero-right-decoration', {
duration: 1000,
distance: '40px',
easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
origin: 'top'
})
sr.reveal('.hero-left-decoration', {
duration: 1000,
distance: '40px',
easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
origin: 'bottom'
})
sr.reveal('.clients li', {
delay: 300,
duration: 1000,
rotate: {
y: 50
},
easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
interval: 150
})
sr.reveal('.feature, .tabs-links li, .testimonial, .pricing-table, .pricing-faqs, .cta-inner', {
duration: 600,
distance: '40px',
easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
interval: 100,
origin: 'bottom',
viewFactor: 0.2
})
}
// Accordion component
const accordionEl = document.getElementsByClassName('accordion-title')
if (accordionEl.length) {
for (let i = 0; i < accordionEl.length; i++) {
accordionEl[i].addEventListener('click', function () {
this.parentNode.classList.toggle('is-open')
const panel = this.nextElementSibling
if (panel.style.maxHeight) {
panel.style.maxHeight = null
} else {
panel.style.maxHeight = `${panel.scrollHeight}px`
}
})
}
}
// Tabs component
const tabLinksAll = document.getElementsByClassName('tab-link')
if (tabLinksAll.length) {
for (let i = 0; i < tabLinksAll.length; i++) {
tabLinksAll[i].addEventListener('click', function (e) {
e.preventDefault()
let tabLinksContainer = tabLinksAll[i].parentNode.parentNode
let tabPanels = tabLinksContainer.nextElementSibling.getElementsByClassName('tab-panel')
let tabLinks = tabLinksContainer.getElementsByClassName('tab-link')
// Remove is-active class from all links and panels
for (let i = 0; i < tabLinks.length; i++) {
tabLinks[i].classList.remove('is-active')
}
for (let i = 0; i < tabPanels.length; i++) {
tabPanels[i].classList.remove('is-active')
}
// Get the ID of panel to display
let tabID = this.getAttribute('href')
// Add is-active class to matching link and panel
tabLinksAll[i].classList.add('is-active')
document.querySelector(tabID).classList.add('is-active')
})
}
}
}())
А вот код для application.html.erb:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><%= yield(:title) %> | Time to Solve</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<link href="https://fonts.googleapis.com/css?family=Lato:400,400i|PT+Serif:700" rel="stylesheet">
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body class="is-boxed has-animations">
<div class="body-wrap boxed-container">
<%= render 'header' %>
<main>
<%= yield %>
</main>
<%= render 'footer' %>
</div>
<script type='text/javascript'>
window.__lo_site_id = 131080;
(function() {
var wa = document.createElement('script'); wa.type = 'text/javascript'; wa.async = true;
wa.src = 'https://d10lpsik1i8c69.cloudfront.net/w.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(wa, s);
})();
</script>
</body>
</html>
Вот видео, показывающее ожидаемую функциональность (JavaScript работает на статическом сайте) по сравнению с ошибкой в приложении rails:
https://gfycat.com/dopeyseveralarawana
Вы также можете увидеть разницу в реальном времени.
Рабочая версия (статический сайт): https://www.timetosolve.com/
Разбитая версия (приложение rails): http://157.230.113.47
Когда приложение live rails загружается, оно создает консоль Javascript:
Uncaught TypeError: Невозможно прочитать свойство 'classList' из null
at application-caea9b4f287ad158d308b89377798bc0c94901b3964f77d10250a2f29eadd1d6.js: 481
Консоль также выдает следующие сообщения при нажатии на один из компонентов вкладки:
[Нарушение] Обработчик requestAnimationFrame занял ms 1619: 04: 56.916 [Нарушение] Добавлен непассивный прослушиватель событий для
событие блокировки прокрутки. Рассмотрим маркировку обработчика событий как
«пассивный», чтобы сделать страницу более отзывчивой. Смотри
819: 05: 05.362 [Нарушение] Обработчик setTimeout занял мс
Не очень опытный здесь (этот код javascript напрямую взят из статического шаблона html / css / js), поэтому любая помощь и руководство будут высоко оценены.