I have a question that's bugging me quite a bit, been working on it a while with every road leading to dissapoints, and no suitable alternatives I've found.
How do I have the following NOT pre-load images?
var oStyle = document.createElement('style');
oStyle.setAttribute('type','text/css');
var css = 'a.hovex-imageview { -moz-outline: 1px dotted red; }';
css += 'a.hovex-imageview img.hovex-imageview { display: none;position: fixed;left: 15%;right: 85%;top:15%;bottom:85%;max-width: 100%;margin: 0;border: none; }';
css += 'a.hovex-imageview:hover img.hovex-imageview { display:block;max-width:80%;max-height:80%; }';
oStyle.innerHTML = css;
document.getElementsByTagName('head')[0].appendChild(oStyle);
var aElm = document.getElementsByTagName('a');
for (i=0; i<aElm.length; i++) {
if (aElm[i].href.match(/\.(jpg|jpeg|gif|png)$/)) {
var oImg = document.createElement('img');
oImg.setAttribute('src',aElm[i].href);
oImg.setAttribute('class','hovex-imageview');
aElm[i].appendChild(oImg);
aElm[i].setAttribute('class','hovex-imageview');
}
}
Basically, it is perfect in almost every way for my purpose, though the one drawback is it often finds itself on pages with >1000 large images, so having it only load the full image on mouseover of the link/thumb would save people some crashed browsers, I've had people complain about that.
I can see why this could be difficult to do, as it works by creating every image on load and hiding them, then showing them on hover, with it said if I'd found/managed to write an acceptable alternative I'd of used it: this seems to be what I've got.
Great thanks to any helpful wizards in advance~
I would approach it by only setting the image src on mouse over...
See this fiddle: http://jsfiddle.net/LD8t6/
var aElm = document.getElementsByTagName('a');
for (i=0; i<aElm.length; i++) {
if (aElm[i].href.match(/\.(jpg|jpeg|gif|png)$/)) {
var oImg = document.createElement('img');
oImg.setAttribute('class','hovex-imageview');
oImg.setAttribute('src','');
aElm[i].appendChild(oImg);
aElm[i].setAttribute('class','hovex-imageview');
aElm[i].onmouseover = function() {
oImg.setAttribute('src', this.href);
}
}
}
Related
I'm trying to export the whole page as PDF. During certain situation's like, if the CSS is loaded from separate file is not applied in exported PDF. So I'm trying to convert all CSS as inline using this code.
(function ($) {
var rules = document.styleSheets;
for(var rl in rules){
var rule = rules[rl].cssRules;
try{
for (var idx = 0, len = rule.length; idx < len; idx++) {
$(rule[idx].selectorText).each(function (i, elem) {
if($(elem).is(":visible"))
elem.style.cssText += rule[idx].style.cssText;
});
}
}catch(e){
console.log(e);
}
}
})(jQuery);
After I ran this code, my exported PDF is working good. But my DOM is not as before. So is there anyway where I can clone my DOM before operations, and replace the cloned DOM as before after playing with DOM. Hope my question is clear. Thanks in anticipation for the help.
In this Snippet there are 2 much more simpler ways than modifying a stylesheet:
Isolate the <iframe>,<embed>, or <object> by wrapping an element around it then apply styles referencing the wrapper element. This is demonstrated in the Snippet with div.jframe as the wrapper.
Inject a <style> block with new rulesets.
If either one is done with moderate care, you shouldn't be left with conflicting styles.
Note: The PDF in the iframe is sandboxed, so it's not there but everything still applies.
SNIPPET
function injectStyles(rule) {
document.body.insertAdjacentHTML('afterbegin',
'<style>' + rule + '</style>');
}
injectStyles('iframe:hover { border: 5px solid blue; }');
.jframe iframe {
outline: 10px solid tomato;
}
<div class='jframe'>
<iframe src='http://che.org.il/wp-content/uploads/2016/12/pdf-sample.pdf' height='400' width='400'></iframe>
</div>
I am working in a project where I need to generate a profile picture of any member and its reviews, and some data, I started working with GDI, but it was so hard to understand, so I searched for other options and found Html2Canvas that works with javascript/jquery, everything is fine, the only thing I couldn't handle, and would like to know if there is a way to hide the source html div without breaking the result image.
Ex:
This is how is it now
This is how it should look
So, when I apply display:none on the css of the source div, the image result is like this:
And finally here is the code that I have so far
var div_to_hide = $("#mydiv:hidden");
$(function() {
$('span.stars').stars();
});
html2canvas([document.getElementById('mydiv')], {
onrendered: function (canvas) {
document.getElementById('canvas').appendChild(canvas);
var data = canvas.toDataURL('image/png');
var image = new Image();
image.src = data;
document.getElementById('image').appendChild(image);
}
});
$.fn.stars = function() {
return $(this).each(function() {
var val = parseFloat($(this).html());
val = Math.round(val * 4) / 4;
var size = Math.max(0, (Math.min(5, val))) * 16;
var $span = $('<span />').width(size);
$(this).html($span);
});
}
https://jsfiddle.net/ricardojriosr/6ap9Lx1f/8/
Now the question is how do I made this work showing only the image and not the HTML source. Thanks in advace.
Instead of trying to hide it before, hide (or remove) it after the canvas is rendered.
I'm not sure why var div_to_hide equals $("#mydiv:hidden"); but if you change it to var div_to_hide = $("#mydiv"); then, on line 12, after appending the image, you can run div_to_hide.hide();
And to avoid a flash of the HTML content, you can use some CSS trickery to cover up the original HTML. I made an example here, but you can adjust to fit whatever your actual needs are. https://jsfiddle.net/m5zq2kzn/
I had the same issue.
The solution that worked for me is a css trickery to position the div that I want to hide offscreen:
.offscreen {
position:absolute;
left:-10000px;
top:auto;
width:1px;
height:1px;
overflow:hidden;
}
Then use it like this:
html2canvas(document.getElementById("ticket_template"))
.then((canvas) => {
let imgData = canvas.toDataURL('image/png');
});
I've got a GIF animation that I use thoughout my site as a saving/loading icon:
Because of edges on different background colors, I'd like to change it to a PNG animation.
When I want to show a loader at this moment I only have to make sure the following span is visible:
<span class="loader"></span>
There are several ways how this span be inserted in the document: through knockout visible binding, through JS, only by stylesheets etc.
Problem
I don't want my animation code to be aware of how this span ended up visible on the document, I just want him to animate it.
Of course scanning the whole document every frame (16 fps) for potential new spans with the 'loader' class, just to know which position properties need to be animated is not quite performant.
So what would be a good performant way to do a document wide png animation?
Note that I do need to support IE8 :(
Using a sprite in combination with CSS background-position comes immediately to mind:
(yes I know it's a pretty shitty one, but it'll do the job).
You mentioned Knockout, and as its aim is to separate logic from presentation, I'll use that. However, there's no way to completely separate it that I know of that doesn't come with a performance cost (cf your comment). Typically in Knockout bindingHandlers are used to do DOM manip independently of your viewModel.
Haven't tested, but should normally work on IE8. Run the snippet below for a demo
ko.bindingHandlers.loadIndicator = {
update: function(element, valueAccessor) {
var val = ko.unwrap(valueAccessor());
if (val == true) {
var intv = setInterval(function() {
var bgX = parseInt(element.style.backgroundPosition.split(' ')[0].replace('px',''));
if (bgX > -48) // 4 frames of 14px
element.style.backgroundPosition = (bgX - 14) + 'px';
else
element.style.backgroundPosition = '0px';
}, 150);
element.style.display = 'block';
} else {
element.style.display = 'none';
clearInterval(intv);
}
}
};
var app = { loading: ko.observable(true) };
ko.applyBindings(app);
// simulate 'loaded' after 3 secs
setTimeout(function() { app.loading(false); }, 3000);
.loader {
display: block;
width: 14px;
height: 14px;
background-image: url(http://i.imgur.com/1OZACw8.png);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<span class="loader" data-bind="loadIndicator: loading"></span>
If you think a custom binding is not worth it, you can use the visible binding in combination with a transparent animated GIF (yes, it is possible). See for example: http://blog.ciuly.com/general/internet/making-animated-gif-transparent-with-gimp/.
Any way you choose, you'll have to keep track of whether something has finished loading/ saving, for example in a KO observable property.
Prefer not using Knockout? You could do the same in vanilla JS/ jQuery. However, because you have to track the status from somewhere, you have to either interval-check DOM attributes (which achieves the same as Knockout does automatically on observables) or choose a variant of the approach below where you call an init/ stop function to hide/display the loader.
function loader(container) {
var elem = document.createElement('span');
elem.className = 'loader';
container.appendChild(elem);
var intv = setInterval(function() {
var bgX = parseInt(elem.style.backgroundPosition.split(' ')[0].replace('px',''));
if (bgX > -48) // 4 frames of 14px
elem.style.backgroundPosition = (bgX - 14) + 'px';
else
elem.style.backgroundPosition = '0px';
}, 150);
this.stop = function() {
clearInterval(intv);
container.removeChild(elem);
};
}
var x = new loader(document.body);
setTimeout(function() { x.stop() }, 10000);
Performance-wise I believe the animated transparent GIF with visible binding and the vanilla init/stop method are the 2 best candidates.
I'm currently making a game in JS, and I faced a problem.
I got an 2D array that stores an image, now I want some random pic to be changed every 1 second, everything is working but, I don't know how I can change the picture.
Do I have to print all the other images if I want to change the random cell in the array?
I'm almost sure that there's another way to change it without doing it.
I'll be glad for help, if anyone needs other explanation I'll be glad to.
You can try using something like this in your header. It should call changePic() every second, incrementing through your picture array, and setting the new picture on an image element.
//know your array sizes
var max_x = picArr.length;
var max_y = picArr[0].length;
var current_x = 0;
var current_y = 0;
function changePic()
{
if(current_y == max_y-1)
{
if(current_x == max_x-1)
{
current_x = 0;
current_y = 0;
}
else
{
current_x++;
current_y = 0;
}
}
else
current_y++;
var pic = picArr[current_x][current_y];
getElementById('randomImage').setAttribute('src', pic);
window.setTimeout(changePic, 1000);
}
setTimeout(changePic, 1000);
https://developer.mozilla.org/en/DOM/window.setTimeout
I would start out with something like
var ImageOne = new Image();
ImageOne.src = "UrlToImage";
And so on just to make sure all the images are loaded when the game starts
Thereafter I would be using jQuery:
$("#IdOfImg").attr("src", ImageOne);
You might want to try using a css class for the elements with a background image rather dan adding images to the DOM. I think a css class for back.png and one for the 1.png should do the trick.
Toggle the classes on the td elements every second.
Hope this helps.
I'm totally new to JS. I'm trying to make me a bookmarklet that finds all images on a web page and adds a colorful border to them. Then, by clicking on an image I'd like to attach the image path.
This is what I've got so far:
javascript:
for (var i= document.links.length; i-->0;) {
if (document.links[i].getElementsByTagName('img').length!=0) {
document.links[i].onclick= function() {
window.open("http://www.example.com/whatever?imgsrc=" + this.src + "");
};
}
}
How can I add a border to the images?
Thanks,
Bob
Try this code:
javascript:for(i=0;i<document.getElementsByTagName('img').length;i++){var imgTag=document.getElementsByTagName('img')[i];imgTag.style.border='2px solid #E8272C';imgTag.onclick=function(){return !window.open(this.src)};}void(0)
Friendly formatted view:
javascript:
for(i=0;i<document.getElementsByTagName('img').length;i++){
var imgTag=document.getElementsByTagName('img')[i];
imgTag.style.border='2px solid #E8272C';
imgTag.onclick=function(){
return !window.open(this.src);
}
}void(0)
There is no need to call getElementsByTagName
javascript:(function(){for(var i=0;i<document.images.length;i++){var image=document.images[i];image.style.border='medium solid blue';image.onclick=function(){location.href=this.src;return false;};}})()