Events not triggered in Safari

For training exercises, I turned the syntax / core application into a Rails environment. I worked on Chrome and Firefox, but it does not work in Safari. It turns out that the original http://backbone-hangman.heroku.com application also does not work in Safari. When you click the β€œnew game”, it looks like this is not an event. The Safari console does not show any errors (although I am not so familiar with the Safari developer tools, as I never use them).

Since there is a current version of the application available here http://backbone-hangman.heroku.com I will not publish a lot of code, but it is a view code that sets an event when #new_game is clicked by calling the startNewGame function. Nothing happens in Safari. The source code of the original is here https://github.com/trivektor/Backbone-Hangman

I did a bit of work with Google and found some mention of how Safari handles events differently, but couldn't find a solution. Can anyone recommend something?

$(function() { window.OptionsView = Backbone.View.extend({ el: $("#options"), initialize: function() { this.model.bind("gameStartedEvent", this.removeGetAnswerButton, this); this.model.bind("guessCheckedEvent", this.showGetAnswerButton, this); }, events: { 'click #new_game': 'startNewGame', 'click #show_answer': 'showAnswer' }, startNewGame: function() { this.model.new(); }, removeGetAnswerButton: function() { $("#show_answer").remove(); }, showGetAnswerButton: function(response) { console.log("showGetAnswerButton"); console.log(response); var threshold = this.model.get("threshold"); console.log(threshold); if (response.incorrect_guesses == this.model.get("threshold")) { $(this.el).append('<input type="button" id="show_answer" class="action_button" value="Show answer" />'); } }, showAnswer: function() { this.model.get_answer(); } }) }) 

Update

Based on one of the comments below the OP, I am posting more code. This is hangman.js where objects are created

 var game = new Game var options_view = new OptionsView({model: game}); var characters_view = new CharactersView({model: game}); var hint_view = new HintView({model: game}); var word_view = new WordView({model: game}); var hangman_view = new HangmanView({model: game}); var answer_view = new AnswerView({model: game}); var stage_view = new StageView({model: game}); 

Views and models are attached to a window like this.

 window.AnswerView = Backbone.View.extend({ ... 

Update In addition to Backbone, jQuery and Underscore, which are downloaded separately, the following files are downloaded for this particular application in the Rails system.

enter image description here

+4
source share
2 answers

This is jQuery + Safari problem (document.ready)

You can simply transfer your scripts inside the body tag and remove the $(function(){ /**/ }) wrapper in each file.

I also added requirejs support and made a transfer request

EDIT:

First of all, sorry for my English :)


View /index.haml Files:

We have to insert js at the bottom of the page (to avoid Safari error)

= javascript_include_tag "javascript/require.js", :"data-main" => "javascript/config"

Here javascript/config is the path to requirejs config.


Publishing the /javascript/config.js file:

"deps" : ["hangman"]

This means the application will start with hangman.js


Publishing /javascript/hangman.js file:

We do not need a wrapper $(function() { , because our script, initialized from the body and the document, is already "ready"

 define([ 'models/game', 'views/answerView', /* ... */ ], function(Game, OptionsView, /* ... */) { // ... } 

Here we load our modules (the first element of the array will be available in the first argument of the function, etc.)


Other files

We simply replace $(function() { with define(['backbone'], function(Backbone) {

In the first line we load the base module. When it is extracted, it will be available inside an anonymous function (the first parameter is the Trunk)

Then we must return the view in order to avoid the value of the undefined module ( public/javascript/hangman.js file must initialize the views a lot. It is not possible to initialize undefined it must initialize the Backbone.View , which we must return)


To learn more, you should read the requirejs documentation. I recommend you start with this article.

+2
source

Try this instead.

 var OptionsView = Backbone.View.extend({ el: $("#options"), initialize: function() { this.model.bind("gameStartedEvent", this.removeGetAnswerButton, this); this.model.bind("guessCheckedEvent", this.showGetAnswerButton, this); }, events: { 'click #new_game': 'startNewGame', 'click #show_answer': 'showAnswer' }, startNewGame: function() { this.model.new(); }, removeGetAnswerButton: function() { $("#show_answer").remove(); }, showGetAnswerButton: function(response) { console.log("showGetAnswerButton"); console.log(response); var threshold = this.model.get("threshold"); console.log(threshold); if (response.incorrect_guesses == this.model.get("threshold")) { $(this.el).append('<input type="button" id="show_answer" class="action_button" value="Show answer" />'); } }, showAnswer: function() { this.model.get_answer(); } }); 

Your code should not be in the finished document (it does not directly manipulate the DOM, it simply declares the object);

Make sure game.js comes after all of your ads.

It seems that Safari's problem is adding variables to the global object. Using var in a global context ensures that window.OptionsView exists. You might want to consider using require.js in the future to manage all of these global object problems.

0
source

All Articles