71GA 71GA - 29 days ago 21
CSS Question

CSS or jQuery not working inside javascript

I am working on a website where in header I try to inspire people with a text that is constantly changing with javascript. One of the lines that appear among this text includes a link to the video, which was supposed to be a modal video, but it somehow fails to load properly while other videos outside this of this javascript work just fine. Here is the video of the problem.

I am not sure, what isn't working here. Is it CSS or jQuery?



<!doctype HTML>
<html lang="en-US">
<head>
<!-- load latest jQuery 3.1.1 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<style>
.modal.fade.in {
top: 20%;
}
.fade.in {
opacity: 1;
}
.modal.fade {
-webkit-transition: opacity .3s linear, top .3s ease-out;
-moz-transition: opacity .3s linear, top .3s ease-out;
-o-transition: opacity .3s linear, top .3s ease-out;
transition: opacity .3s linear, top .3s ease-out;
top: -25%;
}
.fade {
opacity: 0;
-webkit-transition: opacity 0.15s linear;
-moz-transition: opacity 0.15s linear;
-o-transition: opacity 0.15s linear;
transition: opacity 0.15s linear;
}
.hide {
display: none;
}
.modal {
position: fixed;
top: 10%;
left: 50%;
z-index: 1050;
width: 560px;
margin-left: -280px;
background-color: #ffffff;
border: 1px solid #999;
border: 1px solid rgba(0, 0, 0, 0.3);
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
-webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
-webkit-background-clip: padding-box;
-moz-background-clip: padding-box;
background-clip: padding-box;
outline: none;
margin-top: 10px;
margin-bottom: 10px;
overflow-y: hidden;
}
.modal-header {
padding: 9px 15px;
border-bottom: 1px solid #eee;
}
.modal-header .close {
margin-top: 2px;
}
.close {
float: right;
font-weight: bold;
line-height: 20px;
color: #000000;
text-shadow: 0 1px 0 #ffffff;
opacity: 0.2;
filter: alpha(opacity=20);
font-size: 45px;
height: 50px;
cursor: pointer;
}
.modal-body {
position: relative;
max-height: 80%;
overflow-y: visible;
padding: 5px;
margin-bottom: -4px;
}

.modal-body.modal-body-video iframe {
height: 400px;
width: 100%;
}

.modal-backdrop,
.modal-backdrop.fade.in {
opacity: 0.8;
filter: alpha(opacity=80);
}
.modal-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1040;
background-color: #000000;
}
.modal-header .link {
white-space: normal;
margin-left: 5px;
}
@media (max-width: 767px) {
.modal.fade.in {
top: 20px;
}
.modal {
position: fixed;
top: 20px;
left: 20px;
right: 20px;
width: auto;
margin: 0;
}
}
@media (max-width: 480px) {
.modal {
top: 10px;
left: 10px;
right: 10px;
}
}
body{
margin: 0;
padding-left: 10%;
padding-right: 10%;
padding-top: 2%;
padding-bottom: 1%;
}
#moto{
margin-top: -20px;
font-size: 1.7vw;
text-align: center;
height: 5vw;
opacity: 0.8;
}
.boxspace {
overflow: hidden;
}
.box {
float: left;
position: relative;
width: 16.6666%;
padding-bottom: 16.6666%;
}
.boxInner {
position: absolute;
left: 2%;
right: 2%;
top: 2%;
bottom: 2%;
overflow: hidden;
border: thin solid #969696;
border-radius: 4%;
}
.boxInner .titleBox {
position: absolute;
/*no top border*/
bottom: 0;
left: 0;
right: 0;
/*we push the square down*/
margin-bottom: -20%;
background: #000000;
background: rgba(0, 0, 0, 0.8);
color: #FFFFFF;
padding-top: 2%;
padding-bottom: 2%;
padding-left: 2%;
padding-right: 2%;
text-align: center;
font-size: 1.2vw;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.boxInner .titleBox header{
color: #FFFFFF;
font-size: 1.4vw;
}
.boxInner .titleBox p{
color: #FFFFFF;
font-size: 1.0vw;
}
body.no-touch .boxInner:hover .titleBox, body.touch .boxInner.touchFocus .titleBox {
margin-bottom: 0px;
}


</style>

<!--VIDEO-scripts-->
<script type="text/javascript">
/// <reference path="../jquery.min.js" />

//force strict mode
"use strict";

/* Modal Video pluggin.
* currently handles videos in mp4 using html5 native controls && youtube videos
* currently handles modal click events
*/

//scope safe constructor
function ModalVideoOptions(callbackOnModalOpenClick) {
if (this instanceof ModalVideoOptions) {

this.callbackOnModalOpenClick = callbackOnModalOpenClick;
this._videoType = undefined;

//we freeze the object if possible
if (Object.freeze)
Object.freeze(this.VideoEnum);
}

else {
return new ModalVideoOptions(callbackOnModalOpenClick);
}
}

ModalVideoOptions.prototype = {
constructor: ModalVideoOptions,

//getters and setters for videoType

getVideoType : function () {
return this._videoType;
},

setVideoType : function (value) {
if (typeof value != "number") {
throw new Error('Invalid argument: value. This argument must be a number.');
}

var videoTypeItem;
//loop in the enum properties
for(videoTypeItem in this.VideoEnum) {
var enumValue = this.VideoEnum[videoTypeItem];

if (value == enumValue) {
this._videoType = enumValue;
}
}

if (this._videoType == undefined)
throw new Error('Invalid argument: value. This argument must be in the range of VideoEnum.');
},

//enum

VideoEnum : {
MP4: 0,
YOUTUBE: 1
}
};

/**
* JavaScript function to match (and return) the video Id
* of any valid Youtube Url, given as input string.
* @author: Stephan Schmitz <eyecatchup@gmail.com>
* @url: http://stackoverflow.com/a/10315969/624466
*/
function ytVidId(url) {
var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
return (url.match(p)) ? RegExp.$1 : false;
}

(function ($) {

function showModal(options) {

//mask doesn't exist
if ($('#mask').length == 0) {
//we create it
$('body').prepend("<div id='mask' class='modal-backdrop fade in'></div>");
}

var dialogContainer = $('#dialog-container-video');

//popup not created yet
if (dialogContainer.length == 0) {

//we create it
var dialogContainer = $("<div id='dialog-container-video' class='modal fade in'></div>");
$('body').prepend(dialogContainer);

}

var dialogContent;

if (options.getVideoType() == options.VideoEnum.MP4)
dialogContent = "<div id='dialog-content' class='modal-body'><video width='100%' src='" + options.link + "' controls></video></div>";

else if (options.getVideoType() == options.VideoEnum.YOUTUBE)
dialogContent = "<div id='dialog-content' class='modal-body modal-body-video'><iframe src='https://www.youtube.com/embed/" + options.youtubeId + "' frameborder='0' allowfullscreen></iframe></div>";

if(dialogContent)
dialogContainer.append(dialogContent);

//transition effect
$('#mask').show();
$("#dialog-container-video").show();

//modal only must be visible, so we hide the scrollbars
$('body').css('overflow', 'hidden');

//add here transition effect to hide the modal window
var closePopup = function () {
$('#mask').hide();
$('#dialog-container-video').hide();

//we unbind at the closing of the modal window
$("#mask").unbind("click", closePopup);
$('#dialog-container-video a.close').unbind("click", closePopup);
$(document).unbind("keyup", escKeyClosePopup);

$('#dialog-content').remove();

//we display the scrollbars again if needed
$('body').css('overflow', 'auto');
};

$('#mask').on("click", closePopup);
$('#dialog-container-video a.close').on("click", closePopup);

var escKeyClosePopup = function (e) {
//escape key
if (e.keyCode == 27) {
closePopup();
}
};

$(document).keyup(escKeyClosePopup);
}

$.fn.modalvideo = function (options) {

if ((options instanceof ModalVideoOptions) == false)
throw new Error('Invalid argument: options. This argument must be an instance of ModalVideoOptions.');

//force strong-typed object
if (!options || $.isEmptyObject(options)) {
options = new ModalVideoOptions();
}

//every link the selector found
$(this).each(function (i) {

//get the url of the link
var link = $(this).prop("href");

//no href property ? we leave
if (typeof link == "undefined") {
return true;
}

var youtubeId = ytVidId(link);

//youtube id detected
if (youtubeId != false) {
//console.log('youtube ID : ' + youtubeId);
options.setVideoType(options.VideoEnum.YOUTUBE);
options.youtubeId = youtubeId;
}

//test if the link ends with '.mp4'
else if (link.indexOf('.mp4', link.length - '.mp4'.length) != -1) {
options.setVideoType(options.VideoEnum.MP4);
}

//no mp4 or youtube video, continue to the next link
else
return true;

options.link = typeof options.link == "undefined" ? link : options.link;

//binding to the click event. This will cancel the trigger('click') event.
$(this).click(function (e) {
e.preventDefault();

showModal(options);

//open modal event

if (typeof options.callbackOnModalOpenClick == "function") {
options.callbackOnModalOpenClick();
}
});

});
}
})(jQuery);
</script>
<script type="text/javascript"">
"use strict";

$(document).ready(function () {

//each video has need its own instance of modalVideoOptions
$('a[href]').each(function(){
$(this).modalvideo(new ModalVideoOptions());
});
});
</script>
<script type="text/javascript"">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-36251023-1']);
_gaq.push(['_setDomainName', 'jqueryscript.net']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>

<body class="no-touch">

<div id="moto"></div>
<script type="text/javascript">
var text = ["Line 1",'Line 2 and nonworking <a href="./video/test.mp4">video</a>.'];
var counter = 0;
var elem = document.getElementById("moto");
ChangeFunction();
setInterval(ChangeFunction, 3000);
function ChangeFunction() {
var moto = text[counter++];
$(elem).fadeOut('slow', function() {
$(elem).html(moto);
$(elem).fadeIn('slow');
});
if(counter >= text.length) { counter = 0; }
}
</script>

<div class="boxspace">
<div class="box">
<div class="boxInner">
<div class="titleBox">
<header>
Header title
</header>
<a href="./video/test.mp4">video</a>
</p>
</div>
</div>
</div>
</div>

</body>
</html>




Answer

The problem is that you replace the html in each rotation. So when you replace the html you actually create a new DOM elements, including the a tag. So the code $(this).modalvideo(new ModalVideoOptions()); not apply to it.

You have 2 options:

  1. Run this line in each rotation (like I did my snippet).
  2. Do the rotation using show/hide. I mean, in the first place, add all the "slides" in the html and just show/hide (or fade, never mind) them.

Let me know if something is not clear.

<!doctype HTML> 
<html lang="en-US"> 
  <head>
    <!-- load latest jQuery 3.1.1 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

    <style>
      .modal.fade.in {
        top: 20%;
      }
      .fade.in {
        opacity: 1;
      }
      .modal.fade {
        -webkit-transition: opacity .3s linear, top .3s ease-out;
        -moz-transition: opacity .3s linear, top .3s ease-out;
        -o-transition: opacity .3s linear, top .3s ease-out;
        transition: opacity .3s linear, top .3s ease-out;
        top: -25%;
      }
      .fade {
        opacity: 0;
        -webkit-transition: opacity 0.15s linear;
        -moz-transition: opacity 0.15s linear;
        -o-transition: opacity 0.15s linear;
        transition: opacity 0.15s linear;
      }
      .hide {
        display: none;
      }
      .modal {
        position: fixed;
        top: 10%;
        left: 50%;
        z-index: 1050;
        width: 560px;
        margin-left: -280px;
        background-color: #ffffff;
        border: 1px solid #999;
        border: 1px solid rgba(0, 0, 0, 0.3);
        -webkit-border-radius: 6px;
        -moz-border-radius: 6px;
        border-radius: 6px;
        -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
        -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
        -webkit-background-clip: padding-box;
        -moz-background-clip: padding-box;
        background-clip: padding-box;
        outline: none;
        margin-top: 10px;
        margin-bottom: 10px;
        overflow-y: hidden;
      }
      .modal-header {
        padding: 9px 15px;
        border-bottom: 1px solid #eee;
      }
      .modal-header .close {
        margin-top: 2px;
      }
      .close {
        float: right;
        font-weight: bold;
        line-height: 20px;
        color: #000000;
        text-shadow: 0 1px 0 #ffffff;
        opacity: 0.2;
        filter: alpha(opacity=20);
        font-size: 45px;
        height: 50px;
        cursor: pointer;
      }
      .modal-body {
        position: relative;
        max-height: 80%;
        overflow-y: visible;
        padding: 5px;
        margin-bottom: -4px;
      }

      .modal-body.modal-body-video iframe {
        height: 400px;
        width: 100%;
      }

      .modal-backdrop,
      .modal-backdrop.fade.in {
        opacity: 0.8;
        filter: alpha(opacity=80);
      }
      .modal-backdrop {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1040;
        background-color: #000000;
      }
      .modal-header .link {
        white-space: normal;
        margin-left: 5px;
      }
      @media (max-width: 767px) {
        .modal.fade.in {
          top: 20px;
        }
        .modal {
          position: fixed;
          top: 20px;
          left: 20px;
          right: 20px;
          width: auto;
          margin: 0;
        }
      }
      @media (max-width: 480px) {
        .modal {
          top: 10px;
          left: 10px;
          right: 10px;
        }
      }   
      body{
        margin: 0;
        padding-left: 10%;
        padding-right: 10%;
        padding-top: 2%;
        padding-bottom: 1%;
      }
      #moto{
        margin-top: -20px;
        font-size: 1.7vw;
        text-align: center;
        height: 5vw;
        opacity: 0.8;
      }
      .boxspace {
        overflow: hidden;
      }
      .box {
        float: left;
        position: relative;
        width: 16.6666%;
        padding-bottom: 16.6666%;
      }
      .boxInner {
        position: absolute;
        left: 2%;
        right: 2%;
        top: 2%;
        bottom: 2%;
        overflow: hidden;
        border: thin solid #969696;
        border-radius: 4%;
      }
      .boxInner .titleBox {
        position: absolute;
        /*no top border*/
        bottom: 0;
        left: 0;
        right: 0;
        /*we push the square down*/
        margin-bottom: -20%;
        background: #000000;
        background: rgba(0, 0, 0, 0.8);
        color: #FFFFFF;
        padding-top: 2%;
        padding-bottom: 2%;
        padding-left: 2%;
        padding-right: 2%;
        text-align: center;
        font-size: 1.2vw;
        -webkit-transition: all 0.3s ease-out;
        -moz-transition: all 0.3s ease-out;
        -o-transition: all 0.3s ease-out;
        transition: all 0.3s ease-out;
      }
      .boxInner .titleBox header{
        color: #FFFFFF;
        font-size: 1.4vw;
      }
      .boxInner .titleBox p{
        color: #FFFFFF;
        font-size: 1.0vw;
      }
      body.no-touch .boxInner:hover .titleBox, body.touch .boxInner.touchFocus .titleBox {
        margin-bottom: 0px;
      }


    </style>

    <!--VIDEO-scripts-->
    <script type="text/javascript">
      /// <reference path="../jquery.min.js" />

      //force strict mode
      "use strict";

      /* Modal Video pluggin.
        * currently handles videos in mp4 using html5 native controls && youtube videos
        * currently handles modal click events 
        */

      //scope safe constructor
      function ModalVideoOptions(callbackOnModalOpenClick) {
        if (this instanceof ModalVideoOptions) {

          this.callbackOnModalOpenClick = callbackOnModalOpenClick;
          this._videoType = undefined;

          //we freeze the object if possible
          if (Object.freeze)
            Object.freeze(this.VideoEnum);   
        }

        else {
          return new ModalVideoOptions(callbackOnModalOpenClick);
        }
      }

      ModalVideoOptions.prototype = {
        constructor: ModalVideoOptions,

        //getters and setters for videoType

        getVideoType : function () {
          return this._videoType;
        },

        setVideoType : function (value) {
          if (typeof value != "number") {
            throw new Error('Invalid argument: value. This argument must be a number.');
          }

          var videoTypeItem;
          //loop in the enum properties
          for(videoTypeItem in this.VideoEnum) {
            var enumValue = this.VideoEnum[videoTypeItem];

            if (value == enumValue) {
              this._videoType = enumValue;
            }
          }

          if (this._videoType == undefined)
            throw new Error('Invalid argument: value. This argument must be in the range of VideoEnum.');
        },

        //enum 

        VideoEnum : {
          MP4: 0,
          YOUTUBE: 1
        }
      };

      /**
        * JavaScript function to match (and return) the video Id 
        * of any valid Youtube Url, given as input string.
        * @author: Stephan Schmitz <eyecatchup@gmail.com>
        * @url: http://stackoverflow.com/a/10315969/624466
        */
      function ytVidId(url) {
        var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
        return (url.match(p)) ? RegExp.$1 : false;
      }

      (function ($) {

        function showModal(options) {

          //mask doesn't exist
          if ($('#mask').length == 0) {
            //we create it
            $('body').prepend("<div id='mask' class='modal-backdrop fade in'></div>");
          }

          var dialogContainer = $('#dialog-container-video');

          //popup not created yet
          if (dialogContainer.length == 0) {

            //we create it
            var dialogContainer = $("<div id='dialog-container-video' class='modal fade in'></div>");
            $('body').prepend(dialogContainer);

          }

          var dialogContent;

          if (options.getVideoType() == options.VideoEnum.MP4)
            dialogContent = "<div id='dialog-content' class='modal-body'><video width='100%' src='" + options.link + "' controls></video></div>";

          else if (options.getVideoType() == options.VideoEnum.YOUTUBE)
            dialogContent = "<div id='dialog-content' class='modal-body modal-body-video'><iframe src='https://www.youtube.com/embed/" + options.youtubeId + "' frameborder='0' allowfullscreen></iframe></div>";

          if(dialogContent)
            dialogContainer.append(dialogContent);

          //transition effect
          $('#mask').show();
          $("#dialog-container-video").show();

          //modal only must be visible, so we hide the scrollbars
          $('body').css('overflow', 'hidden');

          //add here transition effect to hide the modal window
          var closePopup = function () {
            $('#mask').hide();
            $('#dialog-container-video').hide();

            //we unbind at the closing of the modal window
            $("#mask").unbind("click", closePopup);
            $('#dialog-container-video a.close').unbind("click", closePopup);
            $(document).unbind("keyup", escKeyClosePopup);

            $('#dialog-content').remove();

            //we display the scrollbars again if needed
            $('body').css('overflow', 'auto');
          };

          $('#mask').on("click", closePopup);
          $('#dialog-container-video a.close').on("click", closePopup);

          var escKeyClosePopup = function (e) {
            //escape key
            if (e.keyCode == 27) {
              closePopup();
            }
          };

          $(document).keyup(escKeyClosePopup);
        }

        $.fn.modalvideo = function (options) {

          if ((options instanceof ModalVideoOptions) == false)
            throw new Error('Invalid argument: options. This argument must be an instance of ModalVideoOptions.');

          //force strong-typed object
          if (!options || $.isEmptyObject(options)) {
            options = new ModalVideoOptions();
          }

          //every link the selector found
          $(this).each(function (i) {

            //get the url of the link
            var link = $(this).prop("href");

            //no href property ? we leave
            if (typeof link == "undefined") {
              return true;
            }

            var youtubeId = ytVidId(link);

            //youtube id detected
            if (youtubeId != false) {
              //console.log('youtube ID : ' + youtubeId);
              options.setVideoType(options.VideoEnum.YOUTUBE);
              options.youtubeId = youtubeId;
            }

            //test if the link ends with '.mp4' 
            else if (link.indexOf('.mp4', link.length - '.mp4'.length) != -1) {
              options.setVideoType(options.VideoEnum.MP4);
            }

            //no mp4 or youtube video, continue to the next link
            else
              return true;

            options.link = typeof options.link == "undefined" ? link : options.link;

            //binding to the click event. This will cancel the trigger('click') event.
            $(this).click(function (e) {
              e.preventDefault();

              showModal(options);

              //open modal event

              if (typeof options.callbackOnModalOpenClick == "function") {
                options.callbackOnModalOpenClick();
              }
            });

          });
        }
      })(jQuery);
    </script>
    <script type="text/javascript">
      "use strict";

      $(document).ready(function () {

        //each video has need its own instance of modalVideoOptions  
        $('a[href]').each(function(){
          $(this).modalvideo(new ModalVideoOptions());
        });
      });
    </script>
  </head> 

  <body class="no-touch"> 

    <div id="moto"></div>
    <script type="text/javascript">
      var text = ["Line 1",'Line 2 and nonworking <a href="./video/test.mp4">video</a>.'];
      var counter = 0;
      var elem = document.getElementById("moto");
      ChangeFunction();
      setInterval(ChangeFunction, 3000);
      function ChangeFunction() {
        var moto = text[counter++];
        $(elem).fadeOut('slow', function() {
          $(elem).html(moto);
          $(elem).fadeIn('slow');
          $(elem).find('a').modalvideo(new ModalVideoOptions());
        });
        if(counter >= text.length) { counter = 0; }
      }
    </script>

    <div class="boxspace">
      <div class="box">
        <div class="boxInner">
          <div class="titleBox">
            <header>
              Header title
            </header>
            <a href="./video/test.mp4">video</a>
            </p>
        </div>
      </div>
    </div>
    </div>

  </body> 
</html>