I'm working on some javascript to insert a youtube video into a page using the tubeplayer plugin. The video is inserted when the user clicks a link and is removed when the user clicks the close button.
For the most part, the script works fine. When the user clicks the close button, the button slides away, the video player fades out, the container fades out, and everything looks the way it did before the user clicked the link.
In Chrome, however, after everything has faded out, the video and the close button will occasionally re-appear in a brief flash. It's not consistent - it only occurs about half the time - but it looks bad.
I've tried all sorts of things to fix this - hiding elements, not hiding elements, removing elements at various point in the script - and it keeps happening. The only thing I'm certain of is that tubeplayer is a necessary element; if I take tubeplayer out and just show / hide the other elements, the flash does not occur.
I'm at a total loss about how to prevent this from happening. Any help would be hugely appreciated.
Here's my markup:
<section id="hero">
<div class="item-content">
<a href="http://www.youtube.com/watch?v=sC_IESaVT0A" class="youtube">
<img src="/dynamic-content/solutions/hero_content_mobility.png">
</a>
</div>
</section>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
jnet.ytplayer.init('#hero', 711, 400, '#000');
});
</script>
And the script:
ytplayer = {
$target:null,
height:null,
width:null,
background:null,
defaults:{
allowFullScreen: "true",
initialVideo: 'FtUtE_kv7DU',
preferredQuality: "default",
showControls: 1,
showRelated: 0,
autoPlay: 1,
autoHide: 3,
border: 0,
theme: 'dark',
wmode: 'opaque',
origin: document.domain,
swfobjectURL: "/assets/js/jquery/plugins_jq.js",
allowScriptAccess: "always",
playerID: "tubeplayer-player-container",
loadSWFObject: false,
iframed: true,
onPlayerEnded: function(){
ytplayer.removeVideo();
}
},
init:function(target, w, h, bg){
this.$target = $(target);
this.defaults.height = h;
this.defaults.width = w;
this.background = bg;
},
showVideo:function(link){
var id = $(link).attr("href").replace("http://www.youtube.com/watch?v=", "");
this.defaults.initialVideo = id;
var markup = "<div id='youtube-container'>";
markup += "<div id='youtube-player'>";
markup += "<div id='youtube-closeBtn'></div>";
markup += "<div id='youtube'></div>";
markup += "</div>";
markup += "</div>";
this.$target.prepend(markup);
$('#youtube-closeBtn').click(function(){
ytplayer.removeVideo();
});
$('#youtube-container').height(this.defaults.height);
$('#youtube-container').css('background', this.background);
$('#youtube').height(this.defaults.height);
$('#youtube').width(this.defaults.width);
$('#youtube-player').height(this.defaults.height);
$('#youtube-player').width(this.defaults.width);
$('#youtube-container').fadeIn(200);
$('#youtube-player').fadeIn(600, function() {
$('#youtube').tubeplayer(ytplayer.defaults);
$('#youtube-closeBtn').show();
$('#youtube-closeBtn').animate({ 'right' : '-=49' }, 600, function(){
});
});
},
removeVideo:function(){
$('#youtube-closeBtn').animate({'right' : '+=49'}, 200, function() {
$('#youtube-closeBtn').hide();
$('#youtube').tubeplayer('stop');
$('#youtube-player').fadeOut(600, function(){
$('#youtube-container').fadeOut(100, function(){
$('#youtube-container').remove();
});
});
})
}
}
Related
I have embedded images in text blocks on my Divi website. I'd like that when the user clicks on the image, the largest/original size of the image opens up in a lightbox (instead of the thumbnail size as stated in the src). I have hundreds of images and therefore would be too time consuming to change the src link on each to the original size url. Could anyone help me on how I can change the src link to point to the largest/original image size and then for it to open in a lightbox upon click? I'm not sure of the JQuery to go about this. I've included below the HTML structure I'm using for each embedded image in the text blocks. I've also included the JQuery snippet I'm currently using. The snippet opens the image in a lightbox but only the thumbnail version (not the largest size possible).
Here are a few examples of the URLs of the images on my site:
https://mydomain/wp-content/uploads/2023/01/myimage-235x300.jpg
https://mydomain/wp-content/uploads/2023/01/myimage.jpg
https://mydomain/wp-content/uploads/2023/01/myimage-1.jpg
HTML:
<div class="dmpro_timeline_item_description">
<img decoding="async" loading="lazy" src="https://mydomain/wp-content/uploads/2023/01/myimage-235x300.jpg" width="235" height="300" class="wp-image-2129 alignnone size-medium">
<br>
<em>Image caption</em>
</div>
JQuery:
<script>
if ( jQuery('.dmpro_timeline_item_description').length > 0 ) {
jQuery(".dmpro_timeline_item_description p img").each(function(i, e){
var img_src = jQuery(this).attr("src");
var img = jQuery(this).parent().html();
var new_elem = jQuery('<a style="color: inherit;" href="'+img_src+'">'+img+'</a>');
jQuery(this).parent().html(new_elem);
});
}
jQuery(document).ready(function($){
$(".dmpro_timeline_item_description p").magnificPopup({
delegate: 'a',
type: 'image',
closeOnContentClick: true,
closeBtnInside: false,
mainClass: 'mfp-no-margins mfp-with-zoom',
gallery:{
enabled:false,
},
zoom: {
enabled: true,
duration: 200
}
});
});
</script>
In the snippet below you can see that the width and the height attributes can be toggled.
function toggleLarge(context) {
if (!context.large) {
context.large = true;
context.formerWidth = context.width;
context.formerHeight = context.height;
context.removeAttribute("width");
context.removeAttribute("height");
} else {
context.large = false;
context.width = context.formerWidth;
context.height = context.formerHeight;
}
}
for (let img of document.querySelectorAll("img.size-medium")) {
img.addEventListener('click', function(event) {
toggleLarge(this);
});
}
<div class="dmpro_timeline_item_description">
<img decoding="async" loading="lazy" src="https://www.yourtango.com/sites/default/files/styles/header_slider/public/image_blog/lion-meaning.png?itok=-eB2XSyC" width="235" height="300" class="wp-image-2129 alignnone size-medium">
<br>
<em>Image caption</em>
</div>
If you also need to change the URLs, then you will need to proceed similarly. Since you have not given a sample of large URLs, it's impossible to tell you how to convert the URL to something you did not specify. However, if the "-235x300" part is the problematic, then you can do something like this:
function toggleSrc(context) {
if (context.large) {
context.src = context.src.replace(".", "-235x300.");
} else {
context.src = context.src.replace("-235x300", "");
}
}
and call this function in toggleLarge just before the if, passing context. If this is inappropriate to your problem, then you need to provide further information.
EDIT
Initially, for the sake of simplicity, the event listener was defined with the onclick attribute, but I have changed it to be an addEventListener as per Roko C. Buljan's suggestion.
EDIT2
As Roko C. Buljan explained, it's also possible to use forEach instead of a for loop. For those who prefer that syntax, there is another snippet below:
function toggleLarge(context) {
if (!context.large) {
context.large = true;
context.formerWidth = context.width;
context.formerHeight = context.height;
context.removeAttribute("width");
context.removeAttribute("height");
} else {
context.large = false;
context.width = context.formerWidth;
context.height = context.formerHeight;
}
}
document.querySelectorAll("img.size-medium").forEach(function(img) {
img.addEventListener('click', function(event) {
toggleLarge(this);
});
});
<div class="dmpro_timeline_item_description">
<img decoding="async" loading="lazy" src="https://www.yourtango.com/sites/default/files/styles/header_slider/public/image_blog/lion-meaning.png?itok=-eB2XSyC" width="235" height="300" class="wp-image-2129 alignnone size-medium">
<br>
<em>Image caption</em>
</div>
EDIT3
In the snippet below I have implemented the two functions you need based on the comment section's content:
/*
https://mydomain/wp-content/uploads/2023/01/myimage-235x300.jpg
https://mydomain/wp-content/uploads/2023/01/myimage.jpg
https://mydomain/wp-content/uploads/2023/01/myimage-1.jpg
*/
function thumbnailToLarge(input) {
return input.substring(0, input.lastIndexOf(".")).split("-").filter((item) => (
!/[0-9]+x.*[0-9]+/g.test(item)
)).join("-") + input.substring(input.lastIndexOf("."));
}
console.log("Thumbnail to large: " + thumbnailToLarge("https://mydomain/wp-content/uploads/2023/01/myimage-235x300.jpg"));
function largeToThumbnail(input) {
return input.substring(0, input.lastIndexOf(".")) + "-235x300" + input.substring(input.lastIndexOf("."))
}
console.log("Large to thumbnail " + largeToThumbnail("https://mydomain/wp-content/uploads/2023/01/myimage.jpg"));
console.log("Large to thumbnail " + largeToThumbnail("https://mydomain/wp-content/uploads/2023/01/myimage-1.jpg"));
Hi I'm working on a project where I have a multi-image slider.
Each image needs to have a legend.
I'm getting the alt tag from the image and storing it in a p tag with a legend of legend--text.
I've then created a function that plays when I change slides. This is where I'm having a problem.
I'm setting a variable that gets the active slide, and another one that gets the legend from the active slide - this works fine.
I then tried to use the appendTo() function to copy the content from the legend variable to a div tag with a class of .project__information.
I understand that this is not working because it's not a DOM element, but I've looked for solutions and can't really find any.
Here's my code:
// For each active slide get the alt attribute and store it in <p>
$('.is--legend').each(function() {
var $this = $(this);
$this.append('<p class="legend--text">' + $this.parent().find('img').attr('alt') + '</p>');
});
// Set splide slider
var elms = document.getElementsByClassName('splide');
for (var i = 0, len = elms.length; i < len; i++) {
var splide = new Splide(elms[i], {
type: 'loop',
drag: 'free',
focus: 'center',
perPage: 3,
autoWidth: 'true',
breakpoints: {
767: {
perPage: 1,
}
}
}).mount();
}
function slideChange() {
// Gets active slide
var activeSlide = $(".splide__slide.is-active:not(.splide__slide--clone)");
console.log('Passing through the', activeSlide);
// Gets the legend
var myLegend = activeSlide.find('.legend--text').text();
console.log('Getting the new', myLegend);
myLegend.appendTo('.project__information');
}
splide.on("move", function() {
slideChange();
});
slideChange();
If anyone has an idea as to how I could achieve this, some related documentation about how to proceed, please let me know
I know that it's possible to use CSS to make video full width on a page, but I am using a Javascript library to display the videos because it has some nice skinning and other functionality in the template I'm using. It works great for a single video but the template hard codes the resize to an ID tag and I'm struggling to get it to work with multiple, different videos with different ID tags. The second container doesn't resize. Here is the code:
<section class="wrapper">
<section class="full-width">
<video id="video1" controls poster="img/poster.jpg" >
<source src="media/sample.mp4" type="video/mp4"/>
</video>
</section>
</section>
<!-- video2 markup is almost identical to video1 -->
function htmlVideo() {
videojs("video1", {
controlBar: {
timeDivider: false,
fullscreenToggle: false,
playToggle: false,
remainingTimeDisplay: false
},
"height": "auto",
"width": "auto"
}).ready(function() {
var myPlayer = this;
var aspectRatio = 9 / 16;
function resizeVideoJS() {
var width = document.getElementById(myPlayer.id()).parentElement.offsetWidth;
myPlayer.width(width).height(width * aspectRatio);
// I added these two lines but they don't work
var width2 = document.getElementById("video2").parentElement.offsetWidth;
document.getElementById("video2").width(width2).height(width2 * aspectRatio);
}
resizeVideoJS();
window.onresize = resizeVideoJS;
});
// I added the following code as well trying to initialize the
// video, but it doesn't work
videojs("video2", {
controlBar: {
timeDivider: false,
fullscreenToggle: false,
playToggle: false,
remainingTimeDisplay: false
},
"height": "auto",
"width": "auto"
}).ready(function() {
resizeVideoJS();
});
}
Be sure that each player instance refers to a player object (as provided by the library), as opposed to directly referring to the video element dom node.
I have a task where i need to load a URL (e.g www.yahoo.com) , on my webpage, and take screenshot. I am using html2canvas for screenshot and appending it to the body of the page.
The page specified by the URL is successfully loaded in an iframe inside a div element. But when i try to take screenshot of that, the iframe area comes blank.
Below is the code for previewURL and screenshot.
//to preview the URL content
function previewUrl(url,target){
//use timeout coz mousehover fires several times
clearTimeout(window.ht);
window.ht = setTimeout(function(){
var div = document.getElementById(target);
div.innerHTML = '<iframe style="width:100%;height:100%;" frameborder="0" src="' + url + '" />';
},20);
}
function pic() {
html2canvas(document.body, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
};
And the HTML part goes here :
<body>
<input type="button" class="clear-button" onclick="pic();" value="Take Screenshot" >
Hover to load
<div id="div1"></div>
</body>
The screenshot looks something like this :
I am stuck and don't understand why is this happening. I want something similar to this which can load URL and then onclick can give me screenshot.
The problem here is that you are not pointing correctly to the part of the iframe that you want to take the screenshot, instead you are pointing directly to the document body.
you can try this:
var body = $(iframe).contents().find('body')[0];
html2canvas(body, {
onrendered: function( canvas ) {
$("#content").empty().append(canvas);
},
Hope this helps!
Seems like it's not possible:
The script doesn't render plugin content such as Flash or Java applets. It doesn't render iframe content either.
http://html2canvas.hertzen.com/documentation.html#limitations
This code worked 4 me:
setTimeout(() => {
html2canvas($('#'+idd2).contents().find('body')[0], {
allowTaint : true,
logging: true,
profile: true,
useCORS: true
}).then(function(canvas) {
document.getElementById('screen').appendChild(canvas);
}); }, 3000);
i have many links in my page each with two attributes that are format & src.
<a class="play" src="'.$p['video_path'].'" format="'.$p['video_type'].'"></a>
what its clicked i get its 2 attr and make HTML in js like this.
$(".play").live('click',function() {
var src = $(this).attr('src');
var fmt = $(this).attr('format');
var html = '<video width="200" height="240" controls> <source src="'+src +'" type="video/'+ fmt +'"> </video>';
$("#myVideoDiv").html(html);
$.mobile.changePage( $("#myVideoDiv"), { transition: 'pop' } );
});
<div data-role="dialog" id="myVideoDiv"></div>
when i clicked on any video link my browser url changes like this
http://pp.local/maps/maps/40295472#&ui-state=dialog
but nothing displaying just a white screen.
although its working $("#myVideoDiv").html( html ); i can see the HTML through Firbug.
No error or Warning in Firebug:(
Basically what i need to do is that i want to show each video in jquery Mobile dialog like we do in normal jquery UI like the code below.i need to do same thing here too but with jquery mobile dialog.
$(".watchVideo").live('click', function() {
if( $('div.ui-dialog').length ) {
$('div.ui-dialog').remove();
}
var path = $(this).attr('rel');
var title = $(this).attr('title');
var $dialog = $('<div>', {
title: 'Title'
}).dialog({
autoOpen: false,
modal: true,
width: 600,
height: 500,
closeOnEscape: false
});
var tab = '<table id="video_player" style="margin: 10px 10%;"><tr><td><object codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"><param value="'+path+'" name="src"><param value="true" name="autoplay"><param value="true" name="controller"><embed pluginspage="http://www.apple.com/quicktime/download/" controller="true" style="height:300px;width:400px;background-color:#D9EBFB" autoplay="true" target="myself" src="'+path+'"></object></td></tr></table>';
$('<div id="updateContent">').html( tab ).appendTo( $dialog );
$dialog.dialog('open');
return false;
});
I have successfully recreated your problem, unfortunately I can't be 100 % sure this is the problem. I think you have a an error with your page/dialog setup.
Take a look at my working example, try to use it in your app: http://jsfiddle.net/Gajotres/5REkc/. This example uses dialog as a video container:
$('#index').live('pagebeforeshow',function(e,data){
$('#show-video').live('click', function(e) {
$('#video-content').append('<video width=450px height=300px controls="controls"><source src="http://dev.swinginsam.com/_files/testvid_01.ogv" type="video/ogg"></video>');
$.mobile.changePage("#second", { transition: "slide"});
});
});
I have also created another example for you. This one is much better and it uses popup as a video container. Unlike dialog popup will resize to accommodate video tag: http://jsfiddle.net/Gajotres/vscrU/.
$('#index').live('pagebeforeshow',function(e,data){
$('#show-video').live('click', function(e) {
$('#popup-video').append('<video width=600px height=300px controls="controls"><source src="http://dev.swinginsam.com/_files/testvid_01.ogv" type="video/ogg"></video>');
$('#popup-video').popup("open");
});
});
<div data-role="popup" id="popup-video" data-tolerance="15,15" class="ui-content"</div>
Data tolerance is here so popup can have a padding. Without it video player is overflowing popup container.
One more thing, I can see you are using php for content generation. In this case popup is much better solution. Unlike dialog (which acts as another page, and is a another page), popup is a part of a single page, so i has a much better usability in server side generation.
WARNING:
My examples will only work in firefox browser. I have used only a ogg video source. Video sources are taken from this post.