jQuery .before not including divs - javascript

So there is a h2 that contains the following class entry-contentH2 and I'm simply trying to include the following divs before that h2 but it's not even showing anything. I can't seem to figure out why it isn't adding it, because when I try it without any divs and I test with just text it works.
jQuery(function($) {
$(".entry-contentH2").before("<div class="video_player"><iframe id="ytplayer" type="text/html" width="640" height="390" src="https://www.youtube.com/embed/'.$recipe->recipe_video.'?fs=1" frameborder="0"></iframe></div>");
});
What is the reason as to why .before doesn't work in this case?
Here is the code: https://jsfiddle.net/or9Lbbq0/2/

Your iframe is most likely being blocked by youtube. External websites such as:
youtube.com
google.com
stackoverflow.com
etc.
are not loading in your frame, is because they are intentionally leveraging some sort of Frame Killer.
Suggested reading:
Framekiller (Wikipedia)
Busting a tough FRAME killer
see simular problem here

you need to change the inner or outer " to '
like so
jQuery(function($) { //V here V
$(".entry-contentH2").before("<div class='video_player'>hi</div>");
});
or so
jQuery(function($) { //V here and here V
$(".entry-contentH2").before('<div class="video_player">hi</div>');
})
jsfiddle

Related

Print function only works after second click

I have this function to print a DIV.
Whenever the page is loaded and I click in a "Print" link I have, the DIV is shown to be printed without CSS.
If I close Chrome's print visualization page and click in the "Print" link again, the DIV has CSS applied.
Any ideas why?
Javascript
function printDiv(divId) {
var printDivCSSpre =
'<link href="/static/assets/vendor/sb-admin-2-1.0.7/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">' +
'<link href="/static/assets/vendor/sb-admin-2-1.0.7/dist/css/sb-admin-2.css" rel="stylesheet">' +
'<div style="width:1000px; padding-right:20px;">';
var printDivCSSpost = '</div>';
$('body').append('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
$("link").clone().appendTo($("#print_frame").contents().find("head"));
window.frames["print_frame"].document.body.innerHTML =
printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
var windowInstance = window.frames["print_frame"].window;
windowInstance.print();
}
HTML
<a id="print" href="#">
<i class="fa fa-print"></i> Print
</a>
<script>
$('#print').click(function () {
printDiv('report')
})
</script>
<div id="report" class="report">
<p># Generated Table#</p>
</div>
First click:
http://imgur.com/a/Go81Y
Closing the print preview page and clicking again in print
http://imgur.com/a/SCxJF
This happens because when you call your printDiv() function, css is also written using inner HTML and in this scenario CSS is not applied during first click because you wrote CSS to the elements even when they do not exist inside DIV.
The function to work as desired has to write DIV contents first and then CSS should be applied. I would say write css after contents of DIV or load on top of your HTML page and just write DIV contents.
Hope that helps.
Every thing is right just change the sequence. In browser debugger on first click it didn't show 'print_frame' in sources section while in second click it does (I am using chrome devtool).
So load in memory frame with css attributes during onload:
var windowInstance;
$(function(){
$('body').append('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
$("link").clone().appendTo($("#print_frame").contents().find("head"));
windowInstance = window.frames["print_frame"].window;
});
and onClick just append html
$('#print').click(function () {
var divId = 'report';
var printDivCSSpre ='<div id="printReportDiv" style="width:1000px; padding-right:20px;">';
var printDivCSSpost = '</div>';
window.frames["print_frame"].document.body.innerHTML = printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
windowInstance.print();
});
updated jsfiddle
Try this one. The problem mainly arises because the css has not been applied to the page when the print command is initiated. setTimeout is one way to solve it as others have mentioned but it is really not possible to predict how much delay you will need. Slow internet connections will require high delays before you fire the print statement. The following code, however, only fires the print event after the css has been properly applied to the iframe.
$('#print').click(function () {
if($("#print_frame").length == 0) {
$('#report').after('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
}
var $head = $("#print_frame").contents().find("head");
// for now for ease I will just empty head
// ideally you would want to check if this is not empty
// append css only if empty
$head.empty();
$.ajax({
url : "https://dl.dropboxusercontent.com/u/7760475/reports.css",
dataType: "text",
success : function (reports) {
// grab css and apply its content to the iframe document
$head.append('<style>'+reports+'</style>');
$.ajax({
url : "https://dl.dropboxusercontent.com/u/7760475/bootstrap.css",
dataType: "text",
success : function (bootstrap) {
// grab another css and apply its content to the iframe document
// there may be better ways to load both css files at once but this works fine too
$head.append('<style>'+bootstrap+'</style>');
// css has been applied
// clone your div and print
var $body = $("#print_frame").contents().find('body');
// empty for ease
// but later append content only if empty
$body.empty();
$("#report").clone().appendTo($body);
$('#print_frame').get(0).contentWindow.print();
}
});
}
});
});
Use inline CSS instead.
Reason: When we PRINT or save as PDF if fails to fetch external css Files, So we have to use Inline css.
edited your file please see: jsfiddle.net/ytzcwykz/18/
As other people mentioned it is hard to see your problem without seeing the working example of a problem, but just guessing from the code:
Browser is not able to load the CSS before your print() call.
Browser is not able to render the CSS before your print() call.
Keeping that in mind changing your JS function that way might do the trick
function printDiv(divId) {
$("link").clone().appendTo($("#print_frame").contents().find("head"));
window.frames["print_frame"].document.body.innerHTML =
printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
var windowInstance = window.frames["print_frame"].window;
setTimeout(function() {
windowInstance.print();
}, 0);
}
The idea behind this function is to let browser execute it's code after we added changed the HTML/CSS code in the window - see Why is setTimeout(fn, 0) sometimes useful?
WARNING: this approach is not tested for your particular problem, and it might also not work because we escape/leave the mouse-click call-stack, calling print() method might be not possible out of user-interaction stack.
UPDATE: after looking in the posted jsfiddle - my assumption was correct, the browser needs some time to load and render the CSS, that is why calling the print() right after changing iframe contents doesn't give the desired result. There are 3.5 ways to solve that:
Use events to identify when iframe's document and window has finished loading and rendering. I tried two approaches, and failed so far, need to read docs more carefully about when document and window are behiving during the loading sequence:
we can do that from outside of iframe, i.e. listen to events of iframe element and it's children
we can do that from inside of iframe, i.e. add little javascript snippet inside which will send a message to the parent window when loading is done.
Consider forming the print result different, how about print style-sheets? I.e. add one more style sheet with print-media query to the parent doc and just call print on it?
Consider forming an iframe which is already loaded and ready to be printed, but replace just the table contents inside it.
As others mentioned, The problem here is that the CSS files used are external resources and browser takes time to download and cache it locally. Once it is cached, it would serve faster and that's why it works fine from the second click.
As Anton mentioned, setTimeout is the key here! You may probably increase the timeout seconds to make that work. I tried setting it to 500ms and that worked,
setTimeout(function(){windowInstance.print();},500);

How can I check that if img src start with http://img.youtube.com/vi/ and after any character and replace with a youtube video iframe?

So basically I would like to make a little lazy load code to my site.
Every Youtube video has a thumbnail and usually the url is something like this:
http://img.youtube.com/vi/<THEVIDEOID>/maxresdefault.jpg
I would like to detect this and if it's true, this can be a click event, and after you clicked the image, you get the iframe and you can play the video.
Now, I know there is thousand and thousand outsiders plugin in the internet, but I don't want to load any other code, just that function what is really necessary for this script to work (I hate big load times like anyone else).
Sometimes the outside plugins has thousand, and thousand unnecessary functions for me, like check on every load I chose the click method or the scroll method, and other not useful things.
That's why I decided I trying to build my own.
I saw this post in the search results, but I would like to build this on jQuery way.
Note:
This need for a Wordpress site, that's why I use jQuery instead of $.
This what I have now:
jQuery(document).ready(function() {
function youtubecheck(){
var myregexp = /[a-z,A-Z,0-9]/g;//Regexp for videoid
var imageurl="http://img.youtube.com/vi/"+myregexp+"/maxresdefault.jpg"; // This doesn't sounds right, I need to find out something else.
if (jQuery("img").attr("src")=== "imageurl"){
var autoplay="?autoplay=1/"//this for iframe
jQuery(this).addClass("YT-image"); // Obviously we need class, because we don't whant to do this with all images, just with YT-imgaes.
jQuery(".YT-image").click(function() {
jQuery(".YT-image").replaceWith('<iframe width="560" height="315" src="https://www.youtube.com/embed/'+myregexp+autoplay+'" frameborder="0" allowfullscreen></iframe>'); // maybe we need each for every image? Also I'm not sure about "myregexp" variable in here.
});
}
}
youtubecheck();
});
Changed your if condition and regex
jQuery(document).ready(function() {
function youtubecheck() {
if (/img\.youtube\.com\/vi\/[a-z,A-Z,0-9]+\/maxresdefault\.jpg/g.test(jQuery("img").attr("src"))) {
var videoId = /img\.youtube\.com\/vi\/(.*?)\/maxresdefault\.jpg/g.exec(jQuery("img").attr("src"))[1];
var autoplay = "?autoplay=1/"; //this for iframe
jQuery("img").addClass("YT-image"); //Obviously we need class, becouse we don't whant to do this with all images, just with YT-imgaes.
jQuery(".YT-image").click(function() {
jQuery(this).replaceWith('<iframe width="560" height="315" src="https://www.youtube.com/embed/' + videoId + autoplay + '" frameborder="0" allowfullscreen></iframe>'); // maybe we need each for every image? Also I'm not sure about "myregexp" varible in here.
});
}
}
youtubecheck();
});
Updated the code this works

BackboneJS How to load spotify playlists on hover

Is there a way to only load embedded Spotify Iframes when hovering?
I have this Backbone App where I have bunch of playlists embedded inside an iframe, but the page is pretty slow and heavy because it loads all playlists at once.
I tried to add the lazysizes-plugin, but it doesnt seem to work/help (speed remains the same)
So, my HTML looks pretty simple:
<iframe class="lazyload playList" data-src="" width="300" height="80" frameborder="0" allowtransparency="true"></iframe>
EDIT
Here is my script
this.collection.each(function(spotify, index) {
var service = spotify.get('services').spotify,
s=service.match(/[^\/:]*$/);
$('iframe.playList').eq(index+3).attr('data-src', 'https://embed.spotify.com/?uri=spotify:user:digster.dk:playlist:'+s);
});
I have up to 16 playlists at once on a page, so the data-src is different for each iframe of course
Anyone have an idea or suggestion?
This is what i would do:
http://jsfiddle.net/vjw7o9ha/
Basically, you create all the iframes without the src, and on hover, you use jquery to set the source.
This is just an example, you can create a much better code starting from this.
Using mouseover directly on an iframe might be problematic, because an iframe is a different document.
In case you have used lazySizes (I hope you not hsut added the class, but also changend src to data-src) you can try to so something like this:
Add iframe with data-src, but without class="lazyload"
On domready or later on window.onload add the class lazyload
<iframe data-src="spotify.html">/iframe>
$(window).on('load', function(){
$('iframe[data-src]').addClass('lazyload');
});

Targeting an iframe with Js/jQuery BEFORE the DOM loads

In order to prevent an iframe from flashing, I'm setting its visibility inside a setTimeout (the CSS is set to visibility:hidden)
setTimeout(function(){
$n('#myFrame').css('visibility','visible');}, 750);
Works great, although when I load subsequent locations inside the frame, the flashing behavior returns since the visibility is already set.
What I'd like to do is create a function that targets the iframe BEFORE the DOM/page has loaded to set the visibility to hidden again and then setTimeout.
Keep in mind that this script will run on the ServiceNow platform, meaning some options are limited (can't load in document head, etc.)
It's sort of like a reverse document.ready(). Is this even possible?
Thanks for any leads,
Paco
Just set it in your source:
<iframe style="display: none;"></iframe>
Then un-hide it when you want to.
$('buttonToChangeTheIframePage').click(function(e){
e.preventDefault();
$('#myFrame').css('visibility','hidden');
$('#myFrame').delay(1000).css('visibility','visible');
});
This assumes you are loading locations from OUTSIDE the iframe - anything within the iframe (like a link) will still trigger this behaviour.
EDIT
This is actually better and will work for all circumstances (I think - just check no silly errors as not tested)
<iframe id="myFrame" src="http://www.google.com/" onLoad="hideUnhide();"></iframe>
function hideUnhide(){
$('#myFrame').css('visibility','hidden').delay(1000).css('visibility','visible');
}
Use addAfterPageLoadedEvent(func) in js_include_doc_type.js
<iframe id="gsft_main" style="visibility: hidden;">
anything ....
<script>
addAfterPageLoadedEvent(function() {
$j('#gsft_main').css('visibility','visible');
});
</script>
</iframe>

Create an iframe then append data to it with jQuery

I am trying do some modification to an greasemonkey userscript to implement a feature I need. The code is like
showAddress:function(addrString,type)
{
this.addrBox=$('<div id="batchPublish"></div>')
.append('<div id="batchHeader"></div>')
.append('<div id="batchContent" style="float:left;clear:both"></div>');
.........
var batchContent=this.addrBox.find('#batchContent')
.append('<pre width="300" style="text-align:left" id="batchedlink"></pre>');
this.addrBox.find('#batchedlink').css({'width':'500px','height':'250px','overflow':'auto','word-wrap': 'break-word'})
.append(addrString);
$.blockUI({message:this.addrBox,css:{width:"520px",height:"300px"}}); }
Basically this code writes data to html. What I want to implement is to have "addrString" written to an iframe embedded. Now It's in the "pre" tag. I have tried many approaches but still no luck. Iframe was always empty.
I am completely a novice in javascript and unclear whether this is possible.
Thank you for the help.
Since you are adding the iFrame in the same domain, then you can manipulate its contents like this:
(See it in action at jsBin.)
$("#batchContent").append ('<iframe id="batchedlink"></iframe>');
/*--- Compensate for a bug in IE and FF, Dynamically added iFrame needs
some time to become "DOM-able".
*/
setTimeout ( function () {
var iframeBody = $("#batchedlink").contents ().find ("body");
iframeBody.append (addrString);
},
333
);
NOTE:
For a Chrome userscript, you apparently don't need the timer delay. But for FF and IE 8 (the other 2 browsers I double-checked), a dynamically added iFrame is not manipulable until after it has "settled" for some reason. This seems to take about 200 mS.
A statically loaded iFrame does not have this lag, see the jsBin demo.
Sort of hard to tell exactly what you're asking -- but if you want to know whether or not you can append DOM elements to an iFrame, the answer is "no".

Categories

Resources