Я создал онлайн-курс с ruby on rails: https://www.lernkurs.philosophie.ch/courses/konsequentialismus
Версия Rails: Rails 5.2.3
Версия Ruby: ruby 2.5.1p57 (версия 20130-03-29 63029) [x86_64-linux]
Курс работает на всех моих устройствах и браузерах, но не для всех. Мне нужна помощь, чтобы найти причину, по которой курс иногда не работает.
Я предполагаю, что некоторые устройства или браузеры неправильно загружают javascript или jQuery.
Например, : в курсе имеются кнопки «назад» и «вперед» для смены слайдов в курсах. Для некоторых людей нажатие кнопки ничего не делает.
Если пользователь нажимает следующую кнопку:
<button type="button" id="get-next-slide" class="previous-next-button get-slide-button mx-2" slide="<%= current_slide + 1 %>">Weiter</button>
Тогда должно быть выполнено следующее действие:
function getNextSlide(){
var current_slide = $("#get-next-slide").attr('slide');
setCurrentSlide(course_id, current_slide);
//get next slide
$.ajax({
url: "/slide/" + course_id + "/" + current_slide + ".js",
method: 'GET',
async: true,
cache: false
}).done(function(response) {
animateCss('.slide', 'fadeOutLeft', function() {
$(".slide").empty().append(response);
animateCss('.slide', 'fadeInRight');
})
});
}
Это работает на всех моих устройствах и браузерах, но некоторые люди говорили мне, что кнопки ничего не делали, когда они использовали Safari на iPhone или Firefox на Android.
Код
Полный код на GitHub: https://github.com/Metaphysiker/lernkurs
application.js
//= require rails-ujs
//= require jquery
//= require turbolinks
//= require activestorage
//= require jquery3
//= require popper
//= require bootstrap-sprockets
//= require cookies_eu
//= animate
//= ajax
//= require_tree .
animate.js используется для анимации слайдов.
animate.js
console.log("animateCss loaded!");
function animateCss(element, animationName, callback) {
//const node = document.querySelector(element)
var node = document.querySelector(element)
node.classList.add('animated', animationName)
function handleAnimationEnd() {
node.classList.remove('animated', animationName)
node.removeEventListener('animationend', handleAnimationEnd)
if (typeof callback === 'function') callback()
}
node.addEventListener('animationend', handleAnimationEnd)
}
ajax.js используется для сохранения текущего прогресса пользователя и текущего номера слайда.
ajax.js
console.log("ajax loaded!");
function setCurrentSlide(course_id, number_of_slide){
console.log("setCurrentSlide: " + course_id + " " + number_of_slide);
$.ajax({
url: "/set_current_slide",
method: 'POST',
data: { course_id: course_id, number_of_slide: number_of_slide},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
function setStatus(course_id, status){
console.log(course_id + " " + status);
$.ajax({
url: "/set_status",
method: 'POST',
data: { course_id: course_id, status: status},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
function setResult1(course_id, result){
console.log(course_id + " " + result);
$.ajax({
url: "/set_result1",
method: 'POST',
data: { course_id: course_id, result: result},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
function setOrden(course_id, orden){
console.log(course_id + " " + orden);
$.ajax({
url: "/set_orden",
method: 'POST',
data: { course_id: course_id, orden: orden},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
function addPointsToCourse(course_id, exercise, points){
console.log(course_id + " " + exercise + " " + points);
$.ajax({
url: "/add_points_to_course",
method: 'POST',
data: { course_id: course_id, exercise: exercise, points: points},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
function setGroup(code, firstname){
console.log("code: " + code + " firstname: " + firstname);
$.ajax({
url: "/set_group",
method: 'POST',
data: { code: code, firstname: firstname},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
function checkGroup(code){
console.log("code: " + code);
$.ajax({
url: "/check_group",
method: 'GET',
data: { code: code},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') },
success: function (data) {
console.log("SUCCESS");
return data;
},
error: function () { return "true"; }
});
}
function deleteAccount(account_id){
console.log("deleteAccount: " + account_id);
$.ajax({
url: "/accounts/" + account_id,
method: 'DELETE',
data: { id: account_id},
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
});
}
Когда пользователь входит в курс, он посещает курсы / шоу.html.erb
show.html.erb
<%= render "courses/show", course: @course %>
_show.html.erb
<div class="container-fluid p-3 bg-image-<%= @course.name_of_picture.split('.').first %> min-vh-100" >
<div class="row">
<div class="offset-md-2">
</div>
<div class="offset-lg-1">
</div>
<div class="col-12 col-md-8 col-lg-6">
<div class="slide faster p-1">
<%= render "slide", current_slide: @current_slide, course: @course %>
</div>
</div>
</div>
</div>
<script>
$( document ).ready(function() {
var course_id = "<%= course.id %>";
//get previous slide
function getPreviousSlide(){
var current_slide = $("#get-previous-slide").attr('slide');
setCurrentSlide(course_id, current_slide);
//get previous slide
$.ajax({
url: "/slide/" + course_id + "/" + current_slide + ".js",
method: 'GET',
async: true,
cache: false
}).done(function(response) {
animateCss('.slide', 'fadeOutRight', function() {
$(".slide").empty().append(response);
animateCss('.slide', 'fadeInLeft');
})
});
}
function getNextSlide(){
var current_slide = $("#get-next-slide").attr('slide');
setCurrentSlide(course_id, current_slide);
//get next slide
$.ajax({
url: "/slide/" + course_id + "/" + current_slide + ".js",
method: 'GET',
async: true,
cache: false
}).done(function(response) {
animateCss('.slide', 'fadeOutLeft', function() {
$(".slide").empty().append(response);
animateCss('.slide', 'fadeInRight');
})
});
}
//remove previous event handlers to prevent bugs
$(document).unbind('keydown');
$("body").off("click", "#get-next-slide");
$("body").off("click", "#get-previous-slide");
//keys
$( document ).keydown(function(event) {
$('.modal').modal('hide');
if ( event.which == 37 ) {
getPreviousSlide();
} else if ( event.which == 39 ) {
getNextSlide();
}
});
//click on buttons
$("body").on("click", "#get-next-slide", function() {
getNextSlide();
});
$("body").on("click", "#get-previous-slide", function() {
getPreviousSlide();
});
});
</script>
_slide.html.erb
<%= render "slides/courses/#{course.topic}/#{course.title.parameterize}/#{course.slides[current_slide]}", current_slide: current_slide, course: course %>
<hr>
<%= render "/courses/navigation_buttons", current_slide: current_slide, course: course %>
_navigation_buttons.html.erb
<div class="text-center">
<% if current_slide <= 0 %>
<button type="button" class="previous-next-button get-slide-button disabled mx-2" disabled>Zurück</button>
<% else %>
<button type="button" id="get-previous-slide" class="previous-next-button get-slide-button mx-2" slide="<%= current_slide - 1 %>">Zurück</button>
<% end %>
<%= current_slide + 1 %> / <%= course.slides.count %>
<% if current_slide == course.slides.count-1 %>
<%= link_to 'Weiter', root_path, id: "get-next-slide", class: "btn btn-dark get-slide-button mx-2" %>
<% else %>
<button type="button" id="get-next-slide" class="previous-next-button get-slide-button mx-2" slide="<%= current_slide + 1 %>">Weiter</button>
<% end %>
|
<button type="button" class="ml-1 btn btn-info" data-toggle="modal" data-target="#statusModal">
<%= fa_icon "user-circle" %>
</button>
</div>
<!-- Modal -->
<div class="modal fade" id="statusModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Lernkurs Philosophie</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<%= render "/courses/status", account: @account, course: course %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schliessen</button>
</div>
</div>
</div>
</div>