Can't add omouseover attribute dynamically from javascript - javascript

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);
}

Related

Javascript InnerText, setAttributes not working only on iphones

let thankYouMain = document.querySelector(".thank-you-main-div");
let woocommerceTYBtn = document.querySelectorAll(
".woocommerce-MyAccount-downloads-file"
);
//get product title
let productTitle = document.querySelectorAll(".download-product a");
//get product price
let priceAmount = document.querySelectorAll(".woocommerce-Price-amount bdi");
//create elements for each product item
for (let i = 0; i < woocommerceTYBtn.length; i++) {
let thankYouInnerDiv = document.createElement("div");
thankYouInnerDiv.setAttribute("class", "thank-you-inner-div");
thankYouMain.append(thankYouInnerDiv);
let thankYouImg = document.createElement("img");
thankYouImg.setAttribute(
"src",
"https://slowtravellerss.com/wp-content/uploads/2022/04/IMG_0169.png"
);
thankYouImg.setAttribute("width", "300px");
let thankYouContent = document.createElement("div");
thankYouContent.setAttribute("class", "thank-you-content");
let thankYouDownloadBtn = document.createElement("a");
thankYouDownloadBtn.setAttribute("class", "thank-you-dw-btn");
thankYouDownloadBtn.textContent = "Download";
thankYouInnerDiv.append(thankYouImg, thankYouContent, thankYouDownloadBtn);
let thankYouProductTitle = document.createElement("a");
thankYouProductTitle.setAttribute("class", "thank-you-pd-title");
let thankYouProductDevider = document.createElement("span");
thankYouProductDevider.setAttribute("class", "thank-you-pd-devider");
let thankYouProductPrice = document.createElement("p");
thankYouProductPrice.setAttribute("class", "thank-you-pd-price");
thankYouContent.append(
thankYouProductTitle,
thankYouProductDevider,
thankYouProductPrice
);
//function to set href via get and set attributes
function settingAttr() {
thankYouDownloadBtn.setAttribute(
"href",
woocommerceTYBtn[i].getAttribute("href")
);
thankYouProductTitle.innerText = productTitle[i].innerText;
thankYouProductPrice.innerText = priceAmount[i].innerText;
}
settingAttr();
}
<div class="download-product">
This is the product title
</div>
<div class="woocommerce-Price-amount"><bdi>$99</bdi></div>
Download
<div class="thank-you-main-div">
</div>
I am trying to get data from one set of divs and show it in another div dynamically using getAttribute, setAttribute and innerText. The code is working fine on windows, mac and android devices. You can see the below code working just fine, But it does not work on iPhones. I tried using android and it works without any issue. This happens only on iphones. No idea how to fix this or find the issue. Does anyone have any suggestions?
This first part is to the point, but the latter section is "Meh. Take it if it makes sense." Sorry, I'm a bit of a snob. I have, uhm, "aesthetic" issues with what you're doing, but I'll separate that from the functionally-relevant issue.
The main bits
The main problem is that you're trying to use setAttribute for a structural, rendering-related attribute. I don't see why it'd be a "SHOULD NOT support" usage, but I'm not surprised it's a "MAY support" usage. In the following jsfiddle, I switch out your use of <element>.setAttribute for use of <element>.classList.add, and I confirm it's working as intended: https://jsfiddle.net/azpLj57f/1/ Note that the use of <element>.setAttribute for other attributes is retained...so far.
The opinionated fluff
I do hope you actually like this version of. It's going to look quite different, but I'll edit it to answer any questions you add in the comments: https://jsfiddle.net/q1my9c45/

how to add a (click) function inside the .ts

I am working on a solution to rewrite links in an HTML element.
I get HTML information via a JSON string 'spanClass1'. In this string I need to rewrite a class to a link. This works wonderfully. Unfortunately, I use hash routing in Angular and can only link further via the toDocument() function. It doesn't work via a normal link name tag
Via span.className.replace(/\D/g, '') I get the ID I need to link to the page.
Unfortunately I was not able to define an Angular (click) function including the ID to the page.
Also, I can't manipulate the code in the .html, only in the .ts.
document.ts
var div = document.createElement('div');
div.innerHTML = spanClass1;
div.querySelectorAll('[class^=doc-]').forEach(function (span) {
var anchor = document.createElement('a');
anchor.href = '/suche#/document/' + span.className.replace(/\D/g, '');
anchor.href = span.className.split('doc-')[1];
anchor.innerHTML = span.innerHTML;
span.parentNode.replaceChild(anchor, span);
});
spanClass1 = div.innerHTML;
toDocument(id) {
window.open('/suche#/document/' + id);
}
JSON
"spanClass1": "blablablablabla <span class=\"doc-158 \">Radleuchter,</span> blablablabla"
How do I add a (click)="toDocument(123)" function to the <a> tag inside the Component.
It seems that you want to add a event listener to a div you are creating at run time. A possible approach is to use the Renderer2 API, as provided by the Angular Team.
In this case, your code would look like the following:
In the constructor:
construct(private _renderer2: Renderer2, ...) { ... };
In the method where you create the div:
var div = document.createElement('div');
this._renderer2.listen(div, 'click', (event) => {
// Code to be run here or callback.
}
div.innerHTML = spanClass1;
...
Furthermore, I would advise some caution on changing the DOM directly. It's best to use the renderer for this since it comes with built it methods that are far safer and expose less risks.
You want to add an event listener to each a and listen for the click event. There are a few pieces of your code that I don't fully understand, but it's basically this:
function toDocument(id) {
window.open('/suche#/document/' + id);
}
var div = document.createElement('div');
div.innerHTML = spanClass1; // what is this?
div.querySelectorAll('[class^=doc-]').forEach(function (span) {
var anchor = document.createElement('a');
var id = span.className.split('doc-')[1];
anchor.href = '/suche#/document/' + span.className.replace(/\D/g, '');
anchor.innerHTML = span.innerHTML;
anchor.addEventListener('click', function() {
toDocument(id);
})
span.parentNode.replaceChild(anchor, span);
});
spanClass1 = div.innerHTML;

Setting a onClick function to a dynamically created button, the function fires onload

I am currently creating a program which utilizes localStorage to create a site with a wishlist like functionality. However when I go to generate the html page that should create the wishlist with the photo of the item, the name and a button to remove said item from the list. But when I go to assign the onClick functionality to the button, the function fires on page load rather then on click. I have four main java script functions, one to add to the localstorage, one to remove from local storage, a helper function for removing and the one that will generate the wishlist page (where the problem is).
function genWishListPage(){
for (var i = 0; i < localStorage.length; i++) {
var item = getWishlist(i);
var name = document.createElement("p");
var removeButton = document.createElement("button");
var image = document.createElement("img")
image.src = item.image;
removeButton.innerText = "Remove from wishlist";
removeButton.onClick = RemoveFromWishList(item.name);
removeButton.setAttribute("ID","remove");
name.innerText = item.name;
document.body.appendChild(image);
document.body.appendChild(name);
document.body.appendChild(removeButton);
document.body.appendChild(document.createElement("BR"));
//removeButton.setAttribute("onclick", RemoveFromWishList(item.name));
//removeButton.addEventListener('click', RemoveFromWishList(item.name));
//document.getElementById("remove").addEventListener("click",RemoveFromWishList(item.name));
}
}
The commented parts are ways I have already tried and gotten the same bug.
Any help or advice is appreciated.
When you write
removeButton.onClick = RemoveFromWishList(item.name); you are assigning the return value of the function call to the onClick event. Instead you can write
removeButton.onClick = function() { RemoveFromWishList(item.name);}
You should assign a function to the onClick event listener.

Generate html using Javascript

I have a gallery page that is updated often with new images. I use simple HTML to post the photos. My process currently is copy and paste the set of tags for a photo and change the number to correspond with the image file name. E.G. I change the number 047 to 048. Copy-Paste, change it to 049. This goes on until I have reached the number of additional photos. As you can see, this is very inefficient and there must be a better way of doing this. I was wondering if there is a simpler way to achieve this with Javascript? Perhaps generate additional tags by inputing a certain number or range?
Any ideas that would make this process efficient are welcomed please! Thank you!
<div class="cbp-item trim">
<a href="../assets/images/trim/img-trim-047.jpg" class="cbp-caption cbp-lightbox" data-title="">
<div class="cbp-caption-defaultWrap">
<img src="../assets/images/trim/img-trim-047.jpg" alt="">
</div>
</a>
</div>
You could use a templating solution. There are several libraries for that, but you can also implement it yourself.
Here is one way to do that:
Put the HTML for one image in a script tag that has a non-standard language property so the browser will just ignore it
Put some keywords in there that you'll want to replace, e.g. {url}. You can invent your own syntax.
Read that template into a variable
In the JS code, put all the images' URLs in an array of strings
For each element in that array, replace the keywords in the template string with that particular URL, and concatenate all these resulting HTML snippets.
Inject the resulting HTML into the appropriate place in the document.
Here is a snippet doing that:
// Add new images here:
var images = [
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/SNice.svg/330px-SNice.svg.png",
"https://nettemarie357.files.wordpress.com/2014/09/smiley-face.jpg?w=74&h=74",
];
// Load the template HTML
var template = document.querySelector('script[language="text/template"]').innerHTML;
// Use template to insert all the images:
container.innerHTML = images.map(url => template.replace(/{url}/g, url)).join('');
img { max-width: 50px }
<div id="container"></div>
<script language="text/template">
<div class="cbp-item trim">
<a href="{url}" class="cbp-caption cbp-lightbox" data-title="">
<div class="cbp-caption-defaultWrap">
<img src="{url}" alt="">
</div>
</a>
</div>
</script>
This would help you creating it programatically:
var new_row = document.createElement('div');
new_row.className = "cbp-item trim";
var a = document.createElement('a');
a.href = "../assets/images/trim/img-trim-047.jpg";
a.className= "cbp-caption cbp-lightbox";
document.body.appendChild(a);
var div = document.createElement('div');
div.className = "cbp-caption-defaultWrap";
var img = document.createElement('img');
img.src= "../assets/images/trim/img-trim-047.jpg";
div.appendChild(img);
a.appendChild(div);
new_row.appendChild(a);
If it is just about printing HTML, I suggest you to use plugins like Emmet for Sublime Text editor.
When you install this plugin and see how it works, you can simple create a complex html in a way that 'for' loop would do this. This will help you to change only the image/link number of every item.
Check the demo in the link, that I added.
Here's an example in Java Script that will generate the html you will need. Set the total to whatever number you need to generate the number of images you want.
var total = 47;
var hook = document.getElementById('hook');
// Main Node for SlideShow
var node = document.createElement('div');
node.classList = "cbp-item trim";
// Work out the correct number
var n = function(int) {
var length = int.toString().length;
return length === 1
? '00' + int
: length === 2
? '0' + int
: length
}
// Create the item
var createItem = function(int){
// Create Anchor
var a = document.createElement('a');
a.href = '../assets/images/trim/img-trim-' + ( n(int) ) + '.jpg" class="cbp-caption cbp-lightbox';
a.classList = 'cbp-caption cbp-lightbox';
// Create Div
var div = document.createElement('div');
div.classList = 'cbp-caption-defaultWrap';
// Create Image
var img = document.createElement('img');
img.src = '../assets/images/trim/img-trim-' + ( n(int) ) + '.jpg';
img.alt = 'gallery image';
// Finalise Dom Node
var container = div.appendChild(img)
a.appendChild(div);
// Return Final Item
return a
}
// Create Items
for (var i = 1; i < total + 1; i++) {
node.appendChild(createItem(i));
}
// Append Main Node to Hook
hook.appendChild(node);
<div id="hook"></div>

Check if an element has a background-image with pure JS?

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;
});

Categories

Resources