What is the correct way to check if a particular element has a background-image associated with it, in pure Javascript?
Right now I have this:
var elementComputedStyle = window.getComputedStyle(element);
var hasBGImage = elementComputedStyle.getPropertyValue('background-image') !== 'none'
What you have works, but there are alternate ways of finding the property that you might find easier. I don't believe there is a single 'correct' way to do it, however.
Just javascript:
var hasBGImage = element.style.backgroundImage !== '';
Using jQuery:
var hasBGImage = $(element).css('background-image') !== 'none';
Make sure you declare the background image "inline", otherwise .style.backgroundImage won't work.
<script>
window.onload=function() {
var bg = document.getElementById('el').style.backgroundImage.length!=0;
alert(bg);
}
</script>
<div id='el' style="background-image: url('a.jpg');"></div>
If you can use inline CSS, that's the way. If, for some reason, you can't use that, let me know, I'll try to find out something else :)
I used this code in last one project and works perfect
// Check all background images exists
var imageURLs = $('.image-container ');
imageURLs.each(function(index, element){
var imageURL = $(element).css('background-image').replace('url("', '').replace('")', '');
var img = new Image();
img.onerror = function() { $(element).css('background-image','url(/build/images/missing-image.svg)'); };
img.src = imageURL;
});
Related
I'm trying to add the attributes dynamically to an img tag but only onmouseenter is not been included else everything is been added perfectly
let img_elem = document.createElement('img')
img_elem.src = movies[i].large_cover_image
img_elem.alt = 'poster'
img_elem.id = i
img_elem.className ='poster'
img_elem.onmouseover = 'give_me_id(this)'
This is my HTML after adding attributes dynamically
<img src="https://yts.mx/assets/images/movies/woodstock_99_peace_love_and_rage_2021/large-cover.jpg" alt="poster" id="0" class="poster">
Just an issue with onmouseover else everything working perfectly.
I have already found other ways to add onmouseover attribute but the above method seems to be easier than I have used, so let me know the issue here. Thank you in advance
It's not working because we are trying to add the attribute but what we really want is add event listener. Below is the code please try it out
let img_elem = document.createElement('img');
img_elem.src = 'https://upload.wikimedia.org/wikipedia/commons/1/12/User_icon_2.svg'
img_elem.alt = 'poster';
img_elem.id = 'img1'; //i;
img_elem.className ='poster';
img_elem.addEventListener("mouseover",function(event){console.log('mouseover');});
document.getElementById('imgParent').appendChild(img_elem);
<div id='imgParent'>
</div>
I'm guessing that you're following the W3Schools example, but the example is adding a method through the attribute. You can't really do that in javascript code. Instead, you send in a function and then use event.target to get which image that the user is hovering. I'm taking one more step, and using shorthand properties (I think that's the name) to get target directly by using {target}.
Another way is to add an eventlistener instead, like in Bharat's answer.
const imageIds = [100, 200, 400];
for (const id of imageIds) {
let img_elem = document.createElement('img');
img_elem.src = `https://picsum.photos/id/${id}/200/200`;
img_elem.alt = 'poster';
img_elem.id = id;
img_elem.className = 'poster';
img_elem.onmouseover = giveMeId;
document.body.appendChild(img_elem);
}
function giveMeId({target}) {
console.log('id:', target.id);
}
Hi I have markup sent to me from a server and I set it as the innerHTML of a div element for the purpose of traversing the tree, finding image nodes, and changing their src values. Is there a way to prevent the original src value from being downloaded?
Here is what I am doing
function replaceImageSrcsInMarkup(markup) {
var div = document.createElement('div');
div.innerHTML = markup;
var images = div.getElementsByTagName('img');
images.forEach(replaceSrc);
return div.innerHTML;
}
The problem is that in browsers as soon as you do:
var img = document.createElement('img'); img.src = 'someurl.com' the browser fires off a request to someurl.com. Is there a way to prevent this without resorting to parsing the markup myself? If there is in no other way does anyone know a good way of parsing the markup with as little code as possible to accomplish my goal?
I know you are already happy with your solution, but I think it would be worth sharing a safe method for future users.
You can now simply use the DOMParser object to generate an external document from your HTML string, instead of using a div created by your current document as container.
DOMParser specifically avoids the pitfalls mentioned in the question and other threats: no img src download, no JavaScript execution, even in elements attributes.
So in your case you can safely do:
function replaceImageSrcsInMarkup(markup) {
var parser = new DOMParser(),
doc = parser.parseFromString(markup, "text/html");
// Manipulate `doc` as a regular document
var images = doc.getElementsByTagName('img');
for (var i = 0; i < images.length; i += 1) {
replaceSrc(images[i]);
}
return doc.body.innerHTML;
}
Demo: http://jsfiddle.net/94b7gyg9/1/
Note: with your current code, browsers will still try downloading the resource initially specified in your img nodes src attribute, even if you change it before the end of JS execution. Trace network transactions in this demo: http://jsfiddle.net/94b7gyg9/
Rather than append the new markup to the DOM before you change the img sources, create an element, set it's inner HTML, change the source of the images and then finally, append the changed markup to the page.
Here's a fully-worked sample.
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
//function allByClass(className,parent){return (parent == undefined ? document : parent).getElementsByClassName(className);}
function allByTag(tagName,parent){return (parent == undefined ? document : parent).getElementsByTagName(tagName);}
function newEl(tag){return document.createElement(tag);}
//function newTxt(txt){return document.createTextNode(txt);}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
byId('goBtn').addEventListener('click', onGoBtnClick, false);
}
var dummyString = "<img src='img/girl.png'/><img src='img/gfx07.jpg'/>";
function onGoBtnClick(evt)
{
var div = newEl('div');
div.innerHTML = dummyString;
var mImgs = allByTag('img', div);
for (var i=0, n=mImgs.length; i<n; i++)
{
mImgs[i].src = "img/murderface.jpg";
}
document.body.appendChild(div);
}
</script>
<style>
</style>
</head>
<body>
<button id='goBtn'>GO!</button>
</body>
</html>
You could directly parse the markup string using a regex to replace the img src. Searching for all the img src urls in the string and then replacing them with the new url.
var regex = /<img[^>]+src="?([^"\s]+)"?\s*\/>/g;
var imgUrls = [];
while ( m = regex.exec( markup ) ) {
imgUrls.push( m[1] );
}
imgUrls.forEach(function(url) {
markup = markup.replace(url,'new-url');
});
Another solution might be, if you have access to it, to set the all the img src to an empty string, and put the url in in a data-src attribute. Having your markup string look like something like this
markup = '
';
Then setting this markup to your div.innerHTML won't trigger any download from the browser. And you can still parse it using regular DOM selector.
div.innerHTML = markup;
var images = div.getElementsByTagName('img');
images.forEach(function(img){
var oldSrc = img.getAttribute('data-src');
img.setAttribute('src', 'new-url');
});
I have a series of images each with the class "photo";
I want to go through each of these and retrieve the photo source, for use later in an if statement. I have written the below code to do this, but have not been successful:
$.each($(".photo"), function() {
var imgsrc = $(this).attr("src").length;
console.log(imgsrc);
});
I am not sure where I have gone wrong here. It seems to make sense to me, but I dont get anything in the console.
Can anyone point me in the right direction?
If you have given same class name for all img tag then try this ,
$(".photo").each(function() {
imgsrc = this.src;
console.log(imgsrc);
});
$(document).ready(function(){
$(".photo").each(function() {
imgsrc = this.src;
console.log(imgsrc);
});
});
May be you are missing doc ready handler:
$(function(){
$.each($(".photo"), function() {
var imgsrc = $(this).attr("src").length;
console.log(imgsrc); // logging length it should now print the length
});
});
make sure to load this script first then your $.each() function:
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
You are trying to read the lenght of an object / array out of context here :
var imgsrc = $(this).attr("src").length;
change to
var imgsrc = $(this).attr("src");
edit : in order to check if the attribute exists
if (imgsrc == undefined) { /* do something */ }
I am struggling to get the image src of a image when its clicked. I just need the jQuery(this).attr("src") but in prototype, this.readAttribute doesn't work. I get: “this.readAttribute is not a function”
$$('.more-views > ul > li > img').invoke('observe', 'click', this.updateImage.bind(this));
updateImage: function (){
//var src = jQuery(this).attr("src").replace("thumbnail/66x66", "image");//changes src from thumbnail to large image
Needs the above but in prototype.
//jQuery('#image').attr("src", src);//updates large image
this.imageEl.writeAttribute("src","http://www.timelapseme.com/images/logonew.png");
val_scale = !this.showFull ? this.slider.value : 1;
this.scale(val_scale);
},
Try this:
updateImage: function (){
var src = $(this).readAttribute('src');
...
}
Thanks wajiw I fixed it by var that = this, so I could use it later and getting rid of .bind(this)
You're binding an event, so the click-handler should be:
...
updateImage: function(event)
{
var img = Event.findElement(event, 'IMG');
var src = img.src;
}
...
If I write something like this:
var img = $(new Image()).attr('src', image.src);
How can I check later if img var is an image and not something else ?
if ( img.is('img') ){
}
for safety I may be tempted to wrap the var in jQuery again just incase you may have changed the img to a dom node or something else...
if ( $(img).is('img') ){
}
img.filter('img')
If this returns something then it is an image.
You should avoid explicit type checking.
Use polymorphism to select what has to be done with images, and what has to be done with other objects.
var img = $(new Image())(...);
img.process = function(){ ... do whatever images need ... };
objs.push( img );
var txt = new Text();
txt.process = function(){ .. do text processing, spellcheck, ... };
objs.push( txt );
...
objs.each( o ) { o.process(); }