如何在用户首次登录时以及第一次加载特定页面时检测到?

mar*_*ion 9 javascript jquery ruby-on-rails turbolinks ruby-on-rails-5

我想仅在用户第一次登录时触发一些JS,并且只在第一次加载特定页面时触发.

我相信我可以通过简单的检查来处理他们第一次登录user.sign_in_count < 2,但我不知道如何仅在第一页加载时指定.

即我不希望在用户首次登录后触发JS并刷新页面而不注销.

我正在使用Turbolinks并$(document).on('turbolinks:load', function() {触发它.

编辑1

所以我要做的是在许多页面上执行Bootstrap Tour.但我只希望在第一页加载时自动执行该游览.游览本身将引导用户访问我的应用程序中的其他特定页面,但每个页面将在每个页面上具有特定于页面的游览JS.

现在,在我的HTML中我有这样的事情:

<script type="text/javascript">
  $(document).on('turbolinks:load', function() {
      var tour = new Tour({
        storage: false,
        backdrop: true,
        onStart: function(){
        $('body').addClass('is-touring');
        },
        onEnd: function(){
        $('body').removeClass('is-touring');
        },
        steps: [
        {
          element: "#navbar-logo",
          title: "Go Home",
          content: "All throughout the app, you can click our logo to get back to the main page."
        },
        {
          element: "input#top-search",
          title: "Search",
          content: "Here you can search for players by their name, school, positions & bib color (that they wore in our tournament)"
        }
      ]});

      // Initialize the tour
      tour.init();

      // Start the tour
      tour.start();
  });
</script>
Run Code Online (Sandbox Code Playgroud)

所以我真正想要的是以下内容:

  • 每当他们重新加载页面时,不会在首次登录时执行新游览时轰炸用户.
  • 如果需要,允许他们通过简单的按下链接在以后手动执行巡视.
  • 如果我不需要,我不想在我的数据库中存储任何东西 - 所以最好这应该是基于cookie的方法或localStorage
  • 假设我将使用Rails跟踪他们已完成的登录次数.所以一旦他们不止一次登录,我就无法触发这个JS.

真正的问题就在于第一次登录,如果他们刷新主页10次,这次巡演将被执行10次.这就是我想要阻止的.

我希望这能提供更多的清晰度.

hax*_*ton 13

前言

我的理解是你有:

  1. 包含单个游览的多个页面(每个页面的游览不同)
  2. 检测首次登录帐户的方法(ruby登录计数)
  3. 能够script根据首次登录添加值

方案概述

下面的解决方案localStorage用于存储每个游览的标识符的键值对,如果已经看到它.localStorage在页面刷新和会话之间持续存在,顾名思义,localStorage对于每个域,设备和浏览器都是唯一的(即,即使是同一个域,chrome localStorage也无法访问firefox localStorage,也不能localStorage在你的笔记本电脑上访问chrome localStorage,即使是相同的域).我提出这一点来说明如果用户先前已登录,则依赖前言3来切换JS标志.

为了开始游览,代码检查localStorage其对应的键值对是否未设置为true(表示已被"看到").如果它确实存在且设置为true,则游览不会启动,否则它将运行.当每个游览开始时,使用其onStart方法,我们更新/添加游览的标识符localStorage并将其值设置为true.

start如果您只希望执行当前页面的巡视,则可以通过手动调用巡视方法来手动执行巡视,否则,您可以清除所有localStorage与巡视相关的内容并将用户发送回第一页/如果您在第一页上,请再次调用该start方法.

JSFiddle(HTML基于其他关于巡回演出的问题)

HTML(这可以是具有id="tourAgain"以下代码的属性的任何元素.

<button class="btn btn-sm btn-default" id="tourAgain">Take Tour Again</button>
Run Code Online (Sandbox Code Playgroud)

JS

var isFirstLogin = true; // this value is populated by ruby based upon first login
var userID = 12345; // this value is populated by ruby based upon current_user.id, change this value to reset localStorage if isFirstLogin is true
// jquery on ready function
$(function() {
    var $els = {};  // storage for our jQuery elements
    var tour; // variable that will become our tour
    var tourLocalStorage = JSON.parse(localStorage.getItem('myTour')) || {};

    function activate(){
        populateEls();
        setupTour();
        $els.tourAgain.on('click', tourAgain);
        // only check check if we should start the tour if this is the first time we've logged in
        if(isFirstLogin){
            // if we have a stored userID and its different from the one passed to us from ruby
            if(typeof tourLocalStorage.userID !== "undefined" && tourLocalStorage.userID !== userID){
                // reset the localStorage
                localStorage.removeItem('myTour');
                tourLocalStorage = {};
            }else if(typeof tourLocalStorage.userID === "undefined"){ // if we dont have a userID set, set it and save it to localStorage
                tourLocalStorage.userID = userID;
                localStorage.setItem('myTour', JSON.stringify(tourLocalStorage));
            }
            checkShouldStartTour();
        }
    }

    // helper function that creates a cache of our jQuery elements for faster lookup and less DOM traversal
    function populateEls(){
        $els.body = $('body');
        $els.document = $(document);
        $els.tourAgain = $('#tourAgain');
    }

    // creates and initialises a new tour
    function setupTour(){
        tour = new Tour({
            name: 'homepage', // unique identifier for each tour (used as key in localStorage)
            storage: false,
            backdrop: true,
            onStart: function() {
                tourHasBeenSeen(this.name);
                $els.body.addClass('is-touring');
            },
            onEnd: function() {
                console.log('ending tour');
                $els.body.removeClass('is-touring');
            },
            steps: [{
                element: "div.navbar-header img.navbar-brand",
                title: "Go Home",
                content: "Go home to the main page."
            }, {
                element: "div.navbar-header input#top-search",
                title: "Search",
                content: "Here you can search for players by their name, school, positions & bib color (that they wore in our tournament)"
            }, {
                element: "span.num-players",
                title: "Number of Players",
                content: "This is the number of players that are in our database for this Tournament"
            }, {
                element: '#page-wrapper div.contact-box.profile-24',
                title: "Player Info",
                content: "Here we have a quick snapshot of the player stats"
            }]
        });
        // Initialize the tour
        tour.init();
    }

    // function that checks if the current tour has already been taken, and starts it if not
    function checkShouldStartTour(){
        var tourName = tour._options.name;
        if(typeof tourLocalStorage[tourName] !== "undefined" && tourLocalStorage[tourName] === true){
            // if we have detected that the tour has already been taken, short circuit
            console.log('tour detected as having started previously');
            return;
        }else{
            console.log('tour starting');
            tour.start();
        }
    }

    // updates localStorage with the current tour's name to have a true value
    function tourHasBeenSeen(key){
        tourLocalStorage[key] = true;
        localStorage.setItem('myTour', JSON.stringify(tourLocalStorage));
    }

    function tourAgain(){
        // if you want to tour multiple pages again, clear our localStorage 
        localStorage.removeItem('myTour');
        // and if this is the first part of the tour, just continue below otherwise, send the user to the first page instead of using the function below
        // if you just want to tour this page again just do the following line
        tour.start();
    }

    activate();
});
Run Code Online (Sandbox Code Playgroud)

PS.我们不使用onEnd触发tourHasBeenSeen函数的原因是bootstrap tour目前存在一个错误,如果最后一步的元素不存在,游览结束时不会触发onEnd回调BUG.


Mas*_*Bob 6

您可以尝试使用Javascript sessionStorage,当用户关闭选项卡时会删除它,但通过刷新生存.只需使用sessionStorage.setItem(key, valuesessionStorage.getItem(key).请记住,sessionStorage只能存储字符串!


使用你的代码:

<script type="text/javascript">
  $(document).on('turbolinks:load', function() {
      var tour = new Tour({
        storage: false,
        backdrop: true,
        onStart: function(){
        $('body').addClass('is-touring');
        },
        onEnd: function(){
        $('body').removeClass('is-touring');
        },
        steps: [
        {
          element: "#navbar-logo",
          title: "Go Home",
          content: "All throughout the app, you can click our logo to get back to the main page."
        },
        {
          element: "input#top-search",
          title: "Search",
          content: "Here you can search for players by their name, school, positions & bib color (that they wore in our tournament)"
        }
      ]});
      if(sessionStorage.getItem("loggedIn") !== "yes"){//Remember that sessionStorage can only store strings!
        //Initialize the tour
        tour.init();
        // Start the tour
        tour.start();
      }
      else{
        //Set item "loggedIn" in sessionStorage to "yes"
        sessionStorage.putItem("loggedIn", "yes");
      }
      var goBackToTour = function(e){
        //You can also make a "fake" link, so that it looks like a link, but is not, and you don't have to put the following line:
        e.preventDefault();
        tour.init();
        tour.start();
      };
      document.getElementById("goBackToTourLink").addEventListener("click", goBackToTour);
  });
  //On the logout
  var logout = function(){
    sessionStorage.setItem("loggedIn", "no");
  };
</script>
Run Code Online (Sandbox Code Playgroud)