简体   繁体   中英

VueJS works on chrome but not in Safari

I work on an auction-like VueJs app with the Laravel backend. When I open the chrome browser it works as I want it to work. However, in safari, it doesn't seem to do anything.

I have two components

  • DealerAuction.vue
    • Timer.vue (in the DealerAuction)

DealerAuction:

<template>
  <div class="flex flex-col items-center b p-10 rounded shadow-lg bg-white">
    <div
      class="
        absolute
        top-0
        bg-green-200
        w-full
        px-3
        py-2
        uppercase
        font-bold
        leading-relaxed
        tracking-widest
        text-sm
        rounded-t
        border-b-2 border-green-300
      "
    >
      Aukcia prebieha - končí o 24 minút
    </div>
    <div v-if="beforeAuction">
      <p>Auckia ešte nezačala.</p>
    </div>

    <div v-if="afterAuction">
      <p>Auckia sa skončila.</p>
    </div>

    <div v-if="auctionRunning" >
      <p class="text-xl text-blueGray-800 leading-relaxed mt-6 text-center">
        Aktuálna cena:
      </p>

      <div class="flex flex-col items-center justify-evenly w-full mt-3 mb-6">
        <div>
          <h1 class="text-xl md:text-4xl mb-4 font-bold font-heading">
            {{ price }} €
          </h1>
        </div>
        <p
          v-if="highestBidder"
          class="mb-5 bg-green-800 text-xs text-white p-1 rounded font-bold"
        >
          Vaša ponuka je najvyššia!
        </p>
        <p
          v-if="!highestBidder"
          class="mb-5 bg-red-800 text-xs text-white p-1 rounded font-bold"
        >
          Niekto má vyššiu ponuku!
        </p>
        <div>
          <a
            href="#"
            class="
              inline-block
              py-4
              px-8
              text-lg text-white text-center
              font-bold
              leading-none
              bg-blue-600
              hover:bg-blue-700
              rounded
            "
            @click="raisePrice"
            >Prihodiť 100 €</a
          >
          <p>{{ koniec }}</p>
        </div>
      </div>
    </div>
    <hr class="w-full mb-6" />
    <table class="w-full">
      <tbody>
        <tr>
          <td>Rezervovaná cena:</td>
          <td>{{ auction.minimal_price }} €</td>
        </tr>
        <Timer
          v-bind:starttime="starting"
          v-bind:endtime="ending"
          v-bind:beforeParent="before"
          v-bind:runningParent="running"
          v-bind:endedParent="ended"
          trans='{  
         "day":"Day",
         "hours":"Hours",
         "minutes":"Minuts",
         "seconds":"Seconds",
         "expired":"Event has been expired.",
         "running":"Till the end of event.",
         "upcoming":"Till start of event.",
         "status": {
            "expired":"Expired",
            "running":"Running",
            "upcoming":"Future"
           }}'
        ></Timer>
      </tbody>
    </table>
  </div>
</template>

<script>
import Timer from "./Timer.vue";

export default {
  name: "DealerAuction",
  components: {
    Timer,
  },

  props: ["id", "bidder_id", "starting", "ending"],
  data() {
    return {
      auction: "",
      price: "",
      newPrice: null,
      channel: null,
      actualBidder: "",
      highestBidder: false,
      koniec: "",
      beforeAuction: false,
      auctionRunning: false,
      afterAuction: false,
    };
  },

  created() {
    console.log(this);
    window.axios.defaults.headers.common = {
      "X-Requested-With": "XMLHttpRequest",
      "X-CSRF-TOKEN": document
        .querySelector('meta[name="csrf-token"]')
        .getAttribute("content"),
    };
    this.fetchPrice();
    this.changeBidderView();
    //PUSHER RECIEVER-------------------------------------------------------------

    Pusher.logToConsole = true;

    var pusher = new Pusher("1234567890", {
      cluster: "eu",
    });

    this.channel = pusher.subscribe(this.id.toString());

    var that = this;
    this.channel.bind("price-raise", function (data) {
      that.price = data.price;
      that.actualBidder = data.bidder;
      that.changeBidderView();
    });

    //-----------------------------------------------------------------------------
  },

  methods: {
    fetchPrice() {
      axios.get(`/auction/${this.id}`).then((response) => {
        this.auction = response.data;
        this.price = response.data.actual_price;
        this.actualBidder = response.data.bidder_id;
        if (this.actualBidder == this.bidder_id) {
          this.highestBidder = true;
        }
      });
    },

    raisePrice() {
      this.newPrice = this.price + 100;
      this.price = this.price + 100;
      const req_data = {
        actual_price: this.newPrice,
        id: this.id,
        bidder_id: parseInt(this.bidder_id),
      };
      axios
        .post("/auction/raise/" + this.id, req_data)
        .then((response) => {
          console.log(response.data);
        })
        .catch(function (error) {
          console.log(error);
        });
    },

    changeBidderView() {
      if (this.actualBidder == this.bidder_id) {
        this.highestBidder = true;
      } else {
        this.highestBidder = false;
      }
    },

    before() {
      this.beforeAuction = true;
      this.auctionRunning = false;
      this.afterAuction = false;
    },

    running() {
      this.beforeAuction = false;
      this.auctionRunning = true;
      this.afterAuction = false;
    },

    ended() {
      this.beforeAuction = false;
      this.auctionRunning = false;
      this.afterAuction = true;
    },
  },
};
</script>

And here is the Timer.vue:

<template>
  <div>
    <div v-show="statusType !== 'expired'">
      <div class="day">
        <span class="number">{{ days }}</span>
        <div class="format">{{ wordString.day }}</div>
      </div>
      <div class="hour">
        <span class="number">{{ hours }}</span>
        <div class="format">{{ wordString.hours }}</div>
      </div>
      <div class="min">
        <span class="number">{{ minutes }}</span>
        <div class="format">{{ wordString.minutes }}</div>
      </div>
      <div class="sec">
        <span class="number">{{ seconds }}</span>
        <div class="format">{{ wordString.seconds }}</div>
      </div>
    </div>
    <div class="message">{{ message }}</div>
    <div class="status-tag" :class="statusType">{{ statusText }}</div>
  </div>
</template>

<script>
export default {
  props: ["auction", "trans", "endedParent", "beforeParent", "runningParent", "starttime", "endtime"],
  data: function () {
    return {
      timer: "",
      wordString: {},
      start: "",
      end: "",
      interval: "",
      days: "",
      minutes: "",
      hours: "",
      seconds: "",
      message: "",
      statusType: "",
      statusText: "",
    };
  },
  created: function () {
      
    this.wordString = JSON.parse(this.trans);
  },
  mounted() {
    console.log(this);
    this.start = new Date(this.starttime).getTime();
    this.end = new Date(this.endtime).getTime();
    // Update the count down every 1 second
    this.timerCount(this.start, this.end);
    this.interval = setInterval(() => {
      this.timerCount(this.start, this.end);
    }, 1000);
  },
  methods: {
    timerCount: function (start, end) {
      // Get todays date and time
      var now = new Date().getTime();

      // Find the distance between now an the count down date
      var distance = start - now;
      var passTime = end - now;

      if (distance < 0 && passTime < 0) {
        this.message = this.wordString.expired;
        this.statusType = "expired";
        this.statusText = this.wordString.status.expired;
        this.endedParent();
        clearInterval(this.interval);
        return;
      } else if (distance < 0 && passTime > 0) {
        this.calcTime(passTime);
        this.message = this.wordString.running;
        this.statusType = "running";
        this.runningParent();
        this.statusText = this.wordString.status.running;
      } else if (distance > 0 && passTime > 0) {
        this.calcTime(distance);
        this.message = this.wordString.upcoming;
        this.statusType = "upcoming";
        this.beforeParent();
        this.statusText = this.wordString.status.upcoming;
      }
    },
    calcTime: function (dist) {
      // Time calculations for days, hours, minutes and seconds
      this.days = Math.floor(dist / (1000 * 60 * 60 * 24));
      this.hours = Math.floor(
        (dist % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
      );
      this.minutes = Math.floor((dist % (1000 * 60 * 60)) / (1000 * 60));
      this.seconds = Math.floor((dist % (1000 * 60)) / 1000);
    },
  },
};
</script>

<style>
</style>

Plus I can't find any error in the console regarding these components.

I would appreciate any help. I can't figure out what's going on.

Thank you all in advance!

Developer build does not work in Safari because poly-fillers are not present while serving your application on localhost, the error I was seeing using serve was about Promise's Safari needs poly-fillers for Promises.

However the production build is likely to work since any poly-fills would have been compiled into the build.

This was my experience with crappy apple.

Little side note on apple devices, it is their strict policy that all 3rd Party browsers must utilize Apples web rendering engine so Chrome, Firefox etc are technically just skins and additional features, so on apple those browsers aren't exactly the Chromium and Mozilla engines.

Installing momentJS have helped with the problem. Apperently, Date() has a different format on safari and thus can't calculate the difference between starttime, now and endtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM