nrweb
nrweb

Reputation: 221

Preventing the iOS Double-Tap Issue for this Click Event?

Is there a way to prevent the double-tap link issue from occurring on iOS mobile Safari for the click event presented below?

var self = this;
this.$thumbnail.on('click', function(e) {
  e.preventDefault();
  src = src + '&autoplay=1';
  $innerContainer.addClass('yt-hd-thumbnail-clicked');
  self.$elem.attr({
    'src': src
  });
});

I am primarily looking for a JQuery solution.

UPDATE: Added a Complete Snippet Example

I have supplied a snippet which presents how the click event must be tapped twice via iOS Safari in order to autoplay the embedded video:

I have applied modifications to my original script from a recent answer, but it still was unable to resolve the double-tap issue.

See below:

(function($, window, document, undefined) {
  "use strict";

  var defaults = {
    darkenThumbnail: false
  };

  function YouTubeHDThumbnail(element, options) {
    this.elem = element;
    this.$elem = $(element);
    this.settings = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = "youTubeHDThumbnail";
    this.init();
  }

  $.extend(YouTubeHDThumbnail.prototype, {
    init: function() {
      (this.videoId = null), (this.$thumbnail = null);

      // retrieve HD thumbnail
      var src = this.$elem.attr("src"),
        srcSplit = src.split("?"),
        srcMain = null,
        srcPure = null;

      if (srcSplit.length > 0) {
        srcMain = srcSplit[0];
        srcPure = srcMain.split("/");
        this.videoId = srcPure.pop();
        this.$thumbnail = $("<a />")
          .attr({
            href: "#"
          })
          .addClass("yt-hd-thumbnail");
        let thumb = $("<img/>", {
          src: "http://i.ytimg.com/vi/" + this.videoId + "/maxresdefault.jpg"
        });
        thumb.on("load", () => {
          const src =
            thumb[0].width < 121 ?
            "http://i.ytimg.com/vi/" + this.videoId + "/hqdefault.jpg" :
            "http://i.ytimg.com/vi/" + this.videoId + "/maxresdefault.jpg";
          this.$thumbnail.append(
            $("<img/>", {
              src
            })
          );
        });
      } else {
        console.log("The src attribute of iframe is not valid.");
        return;
      }

      // create container
      var $outerContainer = $("<div />")
        .addClass("yt-hd-thumbnail-outer-container")
        .insertAfter(this.elem)
        .css("width", this.$elem.attr("width")),
        $innerContainer = $("<div />")
        .addClass("yt-hd-thumbnail-inner-container")
        .appendTo($outerContainer);

      // insert thumbnail and iframe
      if (this.settings.darkenThumbnail) {
        this.$thumbnail.addClass("yt-hd-thumbnail-darken");
      }
      $innerContainer.append(this.$thumbnail).append(this.elem);

      // add click handler to thumbnail
      var self = this;
      this.$thumbnail.on("click touchend", function(e) {
        if (e.handled === false) return;
        e.stopPropagation();
        e.preventDefault();
        e.handled = true;
        src = src + "&autoplay=1";
        $innerContainer.addClass("yt-hd-thumbnail-clicked");
        self.$elem.attr({
          src: src
        });
      });
    }
  });

  $.fn["youTubeHDThumbnail"] = function(options) {
    return this.each(function() {
      if (!$.data(this, "plugin_" + "youTubeHDThumbnail")) {
        $.data(
          this,
          "plugin_" + "youTubeHDThumbnail",
          new YouTubeHDThumbnail(this, options)
        );
      }
    });
  };
})(jQuery, window, document);

$('iframe[src*="youtube.com"]').addClass("yt-hd-thumbnail");

$("iframe.yt-hd-thumbnail").youTubeHDThumbnail({
  darkenThumbnail: true
});
.yt-hd-thumbnail-outer-container {
  position: relative;
  height: auto;
}

.yt-hd-thumbnail-inner-container {
  position: absolute;
  padding-top: 56.25%;
  width: 100%;
  height: 0;
  top: 0;
  left: 0;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail,
.yt-hd-thumbnail-inner-container>iframe {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-width: 0;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail {
  z-index: 2;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail img {
  max-width: 100%;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail.yt-hd-thumbnail-darken:before {
  display: block;
  position: absolute;
  content: "";
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #000;
  opacity: 0.15;
  -webkit-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail.yt-hd-thumbnail-darken:hover:before {
  opacity: 0;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail:after {
  display: block;
  position: absolute;
  content: "";
  -webkit-mask-image: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 70"><path d="M97.94,10.95a12.53,12.53,0,0,0-8.81-8.81C81.3,0,50,0,50,0S18.7,0,10.87,2.06A12.79,12.79,0,0,0,2.06,11C0,18.77,0,35,0,35S0,51.31,2.06,59.05a12.53,12.53,0,0,0,8.81,8.81C18.78,70,50,70,50,70s31.3,0,39.13-2.06a12.53,12.53,0,0,0,8.81-8.81C100,51.31,100,35.08,100,35.08S100.08,18.77,97.94,10.95ZM40,50V20L66,35Z"/></svg>');
  mask-image: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 70"><path d="M97.94,10.95a12.53,12.53,0,0,0-8.81-8.81C81.3,0,50,0,50,0S18.7,0,10.87,2.06A12.79,12.79,0,0,0,2.06,11C0,18.77,0,35,0,35S0,51.31,2.06,59.05a12.53,12.53,0,0,0,8.81,8.81C18.78,70,50,70,50,70s31.3,0,39.13-2.06a12.53,12.53,0,0,0,8.81-8.81C100,51.31,100,35.08,100,35.08S100.08,18.77,97.94,10.95ZM40,50V20L66,35Z"/></svg>');
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center center;
  mask-position: center center;
  background-repeat: no-repeat;
  background-position: center center;
  background-color: white;
  width: 75px;
  height: auto;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  opacity: 0.85;
  -webkit-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

.yt-hd-thumbnail-inner-container>a.yt-hd-thumbnail:hover:after {
  opacity: 0;
}

.yt-hd-thumbnail-inner-container>iframe {
  max-width: 100%;
  opacity: 0;
  -webkit-transition: opacity 0.3s ease 0.3s;
  -moz-transition: opacity 0.3s ease 0.3s;
  transition: opacity 0.3s ease 0.3s;
}

.yt-hd-thumbnail-inner-container.yt-hd-thumbnail-clicked>a.yt-hd-thumbnail {
  display: none;
}

.yt-hd-thumbnail-inner-container.yt-hd-thumbnail-clicked>iframe {
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<iframe width="560" height="315" src="https://www.youtube.com/embed/WUUM27T38IE?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

Upvotes: 0

Views: 1956

Answers (1)

browntown412
browntown412

Reputation: 11

I found a method using touchend that seems to do the trick. If anyone has a fix that doesn't involve me adding this to all of my click functions, I'd love to know.

var self = this;
this.$thumbnail.on('click touchend', function(e) {
  if (e.handled === false) return;
  e.stopPropagation();
  e.preventDefault();
  e.handled = true;

  src = src + '&autoplay=1';
  $innerContainer.addClass('yt-hd-thumbnail-clicked');
  self.$elem.attr({
    'src': src
  });
});

Upvotes: 1

Related Questions