Chrome Extension add button to each image on a page - javascript

I am trying to append a button to each image on a webpage using a Chrome Extension. I have the following code in my content script:
var imagesArray = document.getElementsByTagName("img");
console.log(imagesArray);
for (const img of imagesArray) {
var button = document.createElement("button");
button.innerHTML = "button";
button.onclick = function() {
console.log("clicked");
}
img.append(button);
}
I am able to get all the images and I know I can append buttons, I just don't know how to append the button onto the image. Any help is appreciated

Use this line document.body.appendChild(button); <-- use this line down this img.append(button)

You can use something like this in the css. If you are able to add any css. Thanks
button {
display: none;
}
img:hover + button {
display:block;
}
<img src="https://picsum.photos/id/237/200/300" />
<button>My Button</button>

Related

Trouble with hover effect

to put it simply, I am trying to add a hover effect onto my cv.
I want when someone hovers over my linkedin icon, for it to display a text underneath saying "LinkedIn"
However I need this to be in Javascript.
html part <i class="icon-linkedin"></i>
<div id="popup">LinkedIn</div>
js part
var e = document.getElementById('liIcon');
e.onmouseover = function() {
document.getElementById('popup').style.display = 'block';
}
e.onmouseout = function() {
document.getElementById('popup').style.display = 'none';
}
and css part
#popup {
display:none;
}
Any idea why it isn't working?
Thanks.
I noticed a few semicolons missing after the onmouseovers. I'm not an expert on JS, but an unterminated statement looks weird.
Also, I added a LinkedIn text to the button, cause there's no image link visible in the following code. This is how your code should be structured for your code to work (assuming your browser doesn't have JavaScript disabled):
<!DOCTYPE html>
<html>
<head>
<style>
#popup {
display: none;
}
</style>
</head>
<body>
<i class="icon-linkedin">LinkedIn</i>
<div id="popup">LinkedIn</div>
<script>
var e = document.getElementById('liIcon');
e.onmouseover = function () {
document.getElementById('popup').style.display = 'block';
};
e.onmouseout = function () {
document.getElementById('popup').style.display = 'none';
};
</script>
</body>
</html>
No hover:
Hover:
Sometimes selectors can get fussy, I've run into issues with tags nested in other elements similar to what you have here.
Have you tried adding an event listener to the icon tag as well?
var icon = document.getElementById('liIcon').getElementsByClassName('icon-linkedin');
// assuming there is only one element of class: icon-linkedin, access element by index 0
icon[0].onmouseover = function () {
document.getElementById('popup').style.display = 'block';
};
icon[0].onmouseout = function () {
document.getElementById('popup').style.display = 'none';
};

JS function when clicking parent element but return false when clicking child element

I have an image gallery on my site and when you click on it, it opens into a lightbox kind of effect.
I want them to be able to click off of the preview image on the lightbox background and close the preview but not if they click on the actual preview image itself.
function get_image_preview(){
var lightbox = document.getElementById("lightbox");
var image_src = document.getElementById("gallery_image").src;
lightbox.style.display = "block";
lightbox.setAttribute("onclick", "end_image_preview()");
var new_image = document.createElement("img");
new_image.setAttribute("id", "preview_image");
new_image.setAttribute("src", image_src);
new_image.setAttribute("onclick", "return false");
lightbox.appendChild(new_image);
}
function end_image_preview(){
var lightbox = document.getElementById("lightbox");
lightbox.style.display = "none";
lightbox.innerHTML = "";
}
So basically this line:
lightbox.setAttribute("onclick", "end_image_preview()");
does what it is supposed to do and close the preview.
However, the preview is a child of this and I want them to be able to click on the image without ending the preview, so I tried this:
new_image.setAttribute("onclick", "return false");
I think you mignt want to use event.stopPropagation():
function new_image_click(e) {
e.stopPropagation();
}
new_image.setAttribute("onclick", "new_image_click(event)");
in your end image preview click listener make sure that the element does not have in its ancestor the preview element it self, lets say that you gave the preview element the id "preview"
in end_image_preview
function end_image_preview(e) {
if (e.closest('#preview')) {
return
}
// here do what you already doing
}

Mouse over the <a> tag

There is a prompt in the lower left corner When I put the mouse over the tag,
and can u tell me how to forbid this phenomenon.enter image description here
As commented, the behaviour that you wish to stop is a browser's feature.
To avoid this, you will have to simulate anchor's behaviour on your own but as you said you have many anchors and you cannot manually convert them to buttons, you can try following code:
function maskAnchors() {
var els = document.querySelectorAll('a[href]');
console.log("Anchors Found: ", els.length)
for (var i = 0; i < els.length; i++) {
els[i].setAttribute("data-url", els[i].getAttribute('href'));
els[i].removeAttribute("href");
els[i].addEventListener("click", handleClick)
}
}
function handleClick() {
var url = this.getAttribute('data-url');
window.open(url)
}
document.getElementById('btnAdd').addEventListener("click", function() {
var container = document.querySelector('.content');
var link = document.createElement('a')
link.href = "www.google.com";
link.textContent = "This is a newly added link";
container.append(link)
})
document.getElementById('btnMask').addEventListener("click", maskAnchors)
window.addEventListener('load', maskAnchors)
.maskedAnchor {
color: -webkit-link;
text-decoration: underline;
cursor: auto;
}
<div class="content">
Google
Facebook
StackOverflow
YouTube
Example
<a>blabla</a>
</div>
<button id="btnAdd">Add Anchor</button>
<button id="btnMask">Run masking</button>
Note:
Removing href will change styling. You will also have to do that manually.
This will not handle any anchors added dynamically after execution of this function. You will have to call this function again. I have optimised function to only fetch anchors that has href
Hope it helps!

Why won't my JavaScript work!? It's selecting the ID but won't apply display changes

Before I get in to this, I know I should learn jQuery but I haven't got to that yet, I want to learn raw JavaScript first! Well, mostly. Can someone help me without the use of jQuery please just for understanding, thank you!:
Hi, I'm new to JavaScript, not long started learning it as you can see by the first code (which works so I'm leaving it) for the navigation.
However, my problem comes on the 2nd piece of code I'm trying something from a different angle after watching videos on event listeners etc and everything I have written makes sense, to me, I'm going through it step by step, it's selecting all the right stuff, but it's still not showing the desired result!!
When you click CSS i want it to show the div with id "cs", and same for the HTML and JavaScript ones.
I really don't know JavaScript enough to solve this myself, I can not think of anything AT ALL to help with the problem!
Somebody save me, please, my mind is going crazy and I want to go to bed!
Here is the code, and here is the JS fiddle: https://jsfiddle.net/pmj26o9p/2/
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
htm.addEventListener("click", contentShow);
css.addEventListener("click", contentShow);
js.addEventListener("click", contentShow);
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
switcheroo.onclick = function() {
if (switcheroo.style.display === "none") {
switcheroo.style.display = "";
} else {
switcheroo.style.display = "none";
}
}
EDIT: On reading through the code again I don't think it will achieve what I want even if it works. This will let me show and hide whichever I'm clicking right?
I want to show the clicked one but then hide / apply display:none to all others that aren't clicked.
My example below will show the chosen block and hide the others, as per your EDIT comment.
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
function contentShow(el) {
var whichOne = el.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
// show selected block, hide the others
switch (switcheroo) {
case htm:
htm.style.display = "block";
css.style.display = "none";
js.style.display = "none";
break;
case js:
htm.style.display = "none";
css.style.display = "none";
js.style.display = "block";
break;
case css:
htm.style.display = "none";
css.style.display = "block";
js.style.display = "none";
break;
}
}
<span data-id="htm" onClick="contentShow(this)" style="margin-right:10px;color:red; cursor:pointer">Click to show the HTML Block</span>
<span data-id="css" onClick="contentShow(this)" style="margin-right:10px;color:green; cursor:pointer">Click to show the CSS Block</span>
<span data-id="js" onClick="contentShow(this)" style="margin-right:10px;color:blue; cursor:pointer">Click to show the JS Block</span>
<br/>
<br/>
<div id="htm">Some HTML info here</div>
<div id="css" style="display:none">Some CSS info here</div>
<div id="js" style="display:none">Some JavaScript info here</div>
you are binding a second event handler to the switcheroo element, but the click event is not triggered so nothing happens.
If you want to make a toggle function on the switcheroo variable, you should do this instead:
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
return toggleDisplay(switcheroo);
}
function toggleDisplay(elem) {
if (elem.style.display === "none") {
elem.style.display = "";
} else {
elem.style.display = "none";
}
}
Ignoring your other bad practices, change
var htm = document.getElementById('htm');
var css = document.getElementById('css');
var js = document.getElementById('js');
htm.addEventListener("click", contentShow);
css.addEventListener("click", contentShow);
js.addEventListener("click", contentShow);
function contentShow() {
var whichOne = this.attributes["data-id"].value;
var switcheroo = document.getElementById(whichOne);
switcheroo.onclick = function() {
if (switcheroo.style.display === "none") {
switcheroo.style.display = "";
} else {
switcheroo.style.display = "none";
}
}
to something more like:
var doc = document;
function E(id){
return doc.getElementById(id); // you guessed it - same as document.getElementById, without typing it every time
}
var htm = E('htm'), css = E('css'), js = E('js');
contentShow = (function(){ // self-executing scopes off var showing - variable style assignment requires function definition before execution
var showing = false;
return function(){ // returns unexecuted function
var ht = E('ht').style, cs = E('cs').style, jsc = E('jsc').style;
if(showing){
ht.display = cs.display = jsc.display = 'none'; showing = false;
}
else{
ht.display = cs.display = jsc.display = 'block'; showing = true;
}
}
})();
htm.addEventListener('click', contentShow);
css.addEventListener('click', contentShow);
js.addEventListener('click', contentShow);
See updated JSFiddle here.
If there are no other click Events on those Elements, you could even change
htm.addEventListener('click', contentShow);
css.addEventListener('click', contentShow);
js.addEventListener('click', contentShow);
to
htm.onclick = css.onclick = js.onclick = contentShow;
JSFiddle here
but keep in mind this technique overwrites previous Events of the same type.
Here is a variation of #K Scandrett answer which add some scalability/flexibility
var navElements = document.getElementsByClassName("nav");
//Add Event Listeners
for(var i = 0; i < navElements.length; i ++)
{
navElements[i].addEventListener('click', contentShow, false);
}
function contentShow(el) {
var whichOne = el.target.attributes["data-id"].value;
var target = document.getElementById(whichOne);
for(var i = 0; i < navElements.length; i ++)
{
var content = document.getElementById(navElements[i].attributes["data-id"].value)
content.style.display = content === target ? "block" : "none";
}
}
<span data-id="htm" style="margin-right:10px;color:red; cursor:pointer" class="nav">Click to show the HTML Block</span>
<span data-id="css" style="margin-right:10px;color:green; cursor:pointer" class="nav">Click to show the CSS Block</span>
<span data-id="js" style="margin-right:10px;color:blue; cursor:pointer" class="nav">Click to show the JS Block</span>
<br/>
<br/>
<div id="htm">Some HTML info here</div>
<div id="css" style="display:none">Some CSS info here</div>
<div id="js" style="display:none">Some JavaScript info here</div>
I know you're looking for a javascript solution here.and kudos to you for wanting to understand javascript before getting into jquery, but here is an out of the box solution for you.... pure HTML and CSS
.info {display:none;}
.info:target{display:block;}
Click to show the HTML Block
Click to show the CSS Block
Click to show the JS Block
<br/>
<br/>
<div id="htm" class="info">Some HTML info here</div>
<div id="css" class="info">Some CSS info here</div>
<div id="js" class="info">Some JavaScript info here</div>
What I've done here is, leverage internal page id links and the :target selector. In my mind, this is more semantic and can also still be extended by scripting while still maintaining semantics. This option also gives your uses the option of bookmarking selections etc.
CSS OPTION 2
This option achieves the initial display. It is not as clean and uses absolute positioning and z-indexes. Alos note that is uses a background color to conceal the initial option.
.info {position:relative;}
.info > div {
position:absolute;
top:0;
left:0;
background-color:#FFF;
z-index:10;
display: none;
}
#htm
{
display:block;
z-index:1;
}
.info > div:target {
display: block;
}
Click to show the HTML Block
Click to show the CSS Block
Click to show the JS Block
<br/>
<br/>
<div class="info">
<div id="htm">Some HTML info here</div>
<div id="css">Some CSS info here</div>
<div id="js">Some JavaScript info here</div>
</div>
On a side note you should consider adding/removing css classes using javascript instead of the display property directly. This will enable the use of CSS transitions.

Toggle image src attribute using Javascript

I am trying to change the HTML image src using Javascript. I have two images Plus.gif and Minus.gif.I have inserted HTML img tag and have written a Javascript function to change the image src when clicked.
Problem is that I want to change it back again when user clicks on the image.
For example when the page is loaded the Plus.gif shows and when user clicks on it the image it changes to Minus.gif.
I want it so, when the image is Minus.gif and user clicks on it this should be changed to Plus.gif.
Here is my Javascript function:
<script language="javascript" type="text/javascript">
function chngimg() {
var img = document.getElementById('imgplus').src; //= 'Images/Minus.gif';
if (img) {
document.getElementById('imgplus').src = 'Images/Minus.gif';
} else if (!img) {
document.getElementById('imgplus').src = 'Images/Plus.gif';
alert(img);
}
}
</script>
Image tag:
<img id="imgplus" alt="" src="Images/Plus.gif" onmouseover="this.style.cursor='pointer'" onclick="chngimg()" />
See the changes I made to make it working
<script language="javascript" type="text/javascript">
function chngimg() {
var img = document.getElementById('imgplus').src;
if (img.indexOf('Plus.gif')!=-1) {
document.getElementById('imgplus').src = 'Images/Minus.gif';
}
else {
document.getElementById('imgplus').src = 'Images/Plus.gif';
}
}
</script>
<img id="imgplus" alt="" src="Images/Plus.gif" onmouseover="this.style.cursor='pointer'" onclick="chngimg()" />
Hope that resolves your question.
One way would be to add a toggle variable in your function:
var toggle = false;
function chngimg() {
if (toggle === true) {
document.getElementById('imgplus').src = 'Images/Minus.gif';
} else {
document.getElementById('imgplus').src = 'Images/Plus.gif';
alert(img);
}
toggle = !toggle;
}
Note that it's a better practice to use a sprite for this kind of thing. If you're using two images, the user experience is going to be clunky, because the first time they click the image, there will be a slight delay while the second image loads.
Ideally you would have the two images as a sprite sheet, and be using JQuery. Then you could just do it like this.
HTML
<img id="imgplus" src="Images/Sprite.gif" onclick="chngimg()" />
CSS
#imgplus .clicked { background-position: 0 -30px; }
Javascript
function chngimg() {
$("#imgplus").toggleClass("clicked");
}
I have successfully used this general solution in pure JS for the problem of toggling an img url:
function toggleImg() {
let initialImg = document.getElementById("img-toggle").src;
let srcTest = initialImg.includes('initial/img/url');
let newImg = {
'true':'second/img/url',
'false':'initial/img/url'}[srcTest];
return newImg;
}
Then call toggleImg() inside whatever event handler you use....
someButton.addEventListener("click", function() {
document.getElementById("img-toggle").src = toggleImg();
}

Categories

Resources