jquery .show() and .hide() not working in safari - adding spinner to <a

前端 未结 6 1394
清酒与你
清酒与你 2021-01-17 15:55

I have some very basic code that acts as a loading gif for a webpage:

The loading and content containers sit in my base template. The


//header         


        
相关标签:
6条回答
  • 2021-01-17 16:28

    I have not tested this in Safari but you could try

    $("#loading").fadeIn(0);
    $("#content").fadeOut(0);
    

    But make sure to remove the

    display: none
    

    from your CSS

    0 讨论(0)
  • 2021-01-17 16:31

    Instead of $('elem').show() and $('elem').hide() try using...

    $('elem').attr( 'data-display', 'block');
    $('elem').attr( 'data-display', 'none');
    

    In CSS add...

    Attribute selector used twice to increase specificity ;)

    [data-display][data-display='none'] {
      display:none!important;
    }
    [data-display][data-display='block'] {
      display:block!important;
    }
    

    Code will look like this...

    $('h1').attr( 'data-display', 'block');
    $('h2').attr( 'data-display', 'none');
    [data-display][data-display='none'] {
      display:none!important;
    }
    [data-display][data-display='block'] {
      display:block!important;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h1>I'm displayed</h1>
    <h2>I'm hidden</h2>
    <p>
      I'm unaffected ;)
    </p>

    This will hide it (even if there is some css forcing visibility by using !important), if not try increasing specificity of selector even more. Inspecting the element would help ;)

    0 讨论(0)
  • 2021-01-17 16:40

    It appears that you function is named spinner, yet you're attempting to fire loading() inside your a tag (onclick="javascript:loading();). Changing your function name to loading should fix it.

    Here's a working example:

    https://jsfiddle.net/nvzge1e8/5/

    Edit for updated question:

    You need to prevent the event, if you stick event.preventDefault() at the top of your function, it should play the animation. Do note, doing this will prevent your link from actually sending your user to the page, so you may need to add a timed redirect to whatever page you're sending them to.

    Example code:

     $(function() {
     $(".spin_click").click(function(event) {
         event.preventDefault()
         $("#logo_spinner").attr("src", "/static/images/loaders/spinner.gif");
         $('.content').addClass('hide');
         setTimeout(function() {
             window.location.href = "/wait";
         }, 4000);
    
     });
    });
    
    0 讨论(0)
  • 2021-01-17 16:43

    I am having the same issue as the OP, I am simply trying to have an element display only when on IOS, show/hide do not work, any combination of add class/remove class is not working either.

    In my case I am working on progressive web application and this issue has eaten half of my day.

    I even have an alert in the same function method that tries to fire the show, and/or remove class. This alert fires as expected but the element never appears. If I simply remove the hide class and reload the page it appears, if I change the element to show by default in CSS it works, but nothing I have tried so far gets the element to appear via JS. I have tried it in the CSS spreadsheet and with inline style. I've tried using visibility, display none/block, and simply hiding/unhiding via JS. Nothing works on IOS. Works fine in Chrome, Internet Explorer, Edge, Firefox, and various other browser. It just won't work in Safari on IOS and frankly I am stumped as to why.

    If I ever get to the bottom of this issue I will post an answer but I have to say this is proving to be one of the more inexplicable situations that I have encountered in a 20 year development career.

    !!UPDATE!!

    Fixed it yes! After much stress, a colleague suggested it may be a popup blocker in Safari... he suggested tying it to a click in order to prove the concept.

    At that precise moment an error modal popped up all on its own which led me to think... wait a minute - how does that work. It doesn't happen on page load! There is a delay!

    And VOILA - wrapping the show functionality in a very small setTimeout function (10ms) solves the problem.

    In my case I am adding functionality to replicate the Android PWA "add to home screen" functionality for IOS, so when the device is detected as IOS and when the PWA is not already on the home screen, the user is gently prompted to add it.

    0 讨论(0)
  • 2021-01-17 16:44

    I am unable to reproduce the issue with the code provided. However, I am adding an answer with a simple version of what you want to accomplish.

    My guess is that the code not provided is more complex than you describe (or some dependencies are missing).

    Since you already are using jQuery, I am giving you my answer using that library as well.

    (updated: added other libraries, used by the OP, to test if their presence introduces the issue described)

    See sample code below:

    $(function() {
      // add event listener to home (class) - 
      // used instead of inline binding using 'onclick'
      $('.home').on('click', function() {
        console.log('show spinner');
        // show spinner right away
        $("#loading").show();
    
        console.log('waiting now...');
    
        // simulate delay in fetching backend response (delay is 3 secs)
        // contains the callback function to be invoked after your response is completed
        setTimeout(function() {
          // hide spinner
          console.log('hide spinner');
          $("#loading").hide();
    
          // show content
          console.log('show content');
          $("#content").show();
        }, 3 * 1000); // time is in ms so 1000ms = 1 sec (3*1000=3secs)
    
      });
    });
    div#loading {
      height: 50px;
      position: relative;
      display: none;
      background: white;
    }
    .ajax-loader {
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      max-width: 100px;
      margin: auto;
    }
    #content {
      display: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.min.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.min.js"></script>
    
    
    <header>
      Header here
    </header>
    <hr/>
    
    <a href="#" class="home">Home</a>
    
    <div id="loading">
      <img class="ajax-loader" src="https://i.stack.imgur.com/akN6H.png?s=48&amp;g=1" alt="" width="24" height="24" class="avatar-me js-avatar-me">
    </div>
    <hr/>
    <div id="content">
    
      content will be loaded here
    
    </div>
    
    <footer>footer here
    </footer>

    0 讨论(0)
  • 2021-01-17 16:48

    Sorry haven't tried reproducing your bug but unless you must use elem.hide() and elem.show().

    Alternatively, You can work with addClass and removeClass functions

    $('#loading').addClass('hide');
    $('#loading').removeClass('hide');
    

    with .hide { display: none; }

    works perfectly on safari too.

    0 讨论(0)
提交回复
热议问题