Chrome Extension: PopUp Image change on click - javascript

I'm very new at chrome extensions, and navigating it is a lot of self-teaching. I was hoping someone could help with this simple issue I have!
I want to have a very small popup, that displays a closed book upon clicking the extension icon. Once clicked, I want it to switch to an open book, indicating it is "active". I currently have a manifest.json file, default popup file with a css file for styling and js file as well, and I have a background page in js.
I am not sure how to switch the book image inside the popup.
(image linked on text)
the popup window is extremely tiny, which I want it to be. Just wanted to swap those pictures to indicate active mode, and also learn how to send the "active" signal to background script to perform the task I want

If you are able to just change something like the src attribute it may be the easiest method. If you need to have two different elements then you may want to show/hide them using the style attribute and put the onclick on a parent div of the two children.
<img src="/pathToOpenBook" onclick="toggleBookOpen" alt="imageDesc" />
function toggleBookOpen(pointerEvent){
const openBook = "/pathToOpenBook";
const closedBook = "/pathToClosedBook";
const element = pointerEvent.target;
const src = element.getAttribute('src');
const isOpen = src.toLowerCase().includes('open');
const updateValue = isOpen ? closedBook : openBook;
element.setAttribute('src', updateValue);
}

Related

Change custom element displayed

I have made a web application which uses multiple pages. To go from one page to another, I was using window.location.href. As I didn't like this approach, I wanted to use Custom Element. I'm searching I way to change the current custom element displayed when we, for example, press next button. Does someone know a similar topic please?
index.html :
<body>
<div id="root"></div>
</body>
index.js :
window.customElements.define('connection-view', Connection);
//other custom element defined here like profile, ...
var root = document.querySelector('#root');
root.innerHTML = '<connection-view></connection-view>'
//when the button login is pressed, have to change this to profile component
Put a root div and then change his innerHTML with the custom element tag

toggle divs so only one is open at a time, but be able to close them all as well javascript

I have these divs that I can toggle onclick to scale larger one at a time. It works perfectly except that once one is enlarged, one is always enlarged. I am using toggleOpen for this. I am looking to be able to make it so that it can do what it already does, but then onclick of the enlarged div have it go back to its original size without having to toggle with another div. In other words, I need a way to make the page go back to a state where all the divs are in original size. I have tried else statements to no avail as well as adding another function to remove class. I only want a js solution - no jquery or anything else please. Here is the JS portion of it.
const event = document.querySelectorAll('.eventsBorder')
function toggleOpen() {
let opened = document.getElementsByClassName('large')[0];
if(opened!=undefined)
opened.classList.toggle('large');
this.classList.toggle('large');
}
event.forEach(eventsBorder => eventsBorder.addEventListener('click', toggleOpen));
Here is my codepen
Thanks in advance for any help!
The opened variable gives you back a list of all the HTML elements which have the large class, and when you click again on an already enlarged div that automatically satisfied this criteria. So, what happens is that if you click on the same item twice, your toggleOpen function first removes the large class from that item and then adds it again because of the following line in your code-
this.classList.toggle('large');
The best way to achieve what you want would be to make sure that in addition to opened not being undefined, you should also make sure opened is not the same item as the one you clicked on. You can accomplish that using-
if(opened != undefined && opened != this)
Here is a link to the updated codepen to see it in action.
So it looks like you are using querySelectorAll to select all elements with the class "large", then you're toggling the class. If you toggle the class, it will no longer be a part of that query selection, as it no longer has that class applied, so it will not be able to remove it.
const event = document.querySelectorAll('.eventsBorder')
event.forEach(eventsBorder =>
eventsBorder.onclick = () =>
eventsBorder.classList.toggle('large'));
This seems to accomplish what you'd like.

Javascript help for a Chrome extension

First of all, I am not a programmer. I do not know Javascript at all. I'm trying to create a Chrome extension that modifies my browser tab's title, by taking a specific string on a webpage. I know how to create Chrome extensions (just barely) and I just need to modify the Javascript to do what I want (which I do not know how).
I found the following script online and am trying to modify it but can't figure out how to get it working. Here is the script:
https://pastebin.com/dY1LSdjT
// Fire this event any time the mouse is moving. Sucks for performance, but it's a better experience
document.addEventListener("mousemove", function() {
// This will get us the banner
let bannerTextElements = document.getElementsByClassName("dijitReset dijitInputField dijitInputContainer");
console.log(bannerTextElements);
console.log(bannerTextElements[0]);
if (bannerTextElements[0]) {
console.log("ok!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
console.log(bannerTextElements[0].innerHTML);
// This will get us the text
let bannerTextLine = bannerTextElements[0].getElementsByClassName("dijitReset dijitInputInner");
console.log(bannerTextLine);
document.title = bannerTextLine[0].innerHTML
}
}, false);
And here's the website viewed in developer mode. I would like to get the text "blahhhh" and use that for the title of my browser tab.
Below is a different webpage and the difference here is that the "div class" names will change. The numbers in those class will change to different numbers, but the structure and the overall name remains the same. For example, "ms-Button-label label-549" may change to "ms-Button-label label-640". This happens whenever you refresh the page. I found that the "viewport" id name doesn't change though, so I think if we can use that as a reference and then just look at the nested div classes and reference them and extract the value (in this case Crystal Mountain).
Fixing your code
You got like 95% of everything you need.
The one thing you are missing right now is that the fact that an input element does not posses an "innerHTML" (That is why it isn't closed like this: <input>renderedText</input>). Instead you want to check for it's value:
document.title = bannerTextLine[0].value;
Some Improvements:
Search by ID
You have a well defined input which can be more easily obtained by looking it up using the id:
let bannerTextLine = document.getElementById('lanDeviceIndex_searchBox');
End result:
const bannerTextLine = document.getElementById('lanDeviceIndex_searchBox');
bannerTextLine.addEventListener("blur", function() {
if (bannerTextLine != null) {
document.title = bannerTextLine.value;
}
});
This is the entire JS code. Note that I changed the event to blur which activates when the form is left, this should be optimal for your case.

Looking for advice on what approach to take for multiple image swaps

I'm working on designing an interactive university campus map and need some direction with what I am looking to do.
Link to page: http://www.torontoclassfind.com/startpage.html
I want to be able to click on the links in the top menu (only one link is active so far and it loads and Ajax page in lower left div) and have it swap the building image with a different image to show that it's been selected.
I could do that with the following:
$("#buildinglink1").click(function () {
$("#buildingimg1").attr("src","highlightedimage.gif")
})
Problem is I need to change back the image to it's default image once another menu link is clicked and a new building is selected.
The building images are located at www.torontoclassdfind.com/building/ and the highlighted images are located at www.torontoclassdfind.com/buildingc/ and the names for the buildings are the same in both locations.
I am thinking of using JQuery's .replace element to do this (ex: jquery remove part of url) which would remove or add the 'c' to the url, but I'm kind of lost from here.
Any tips? I think I need to make a function that would indicated a link is selected and somehow merge it with the .replace element.
Just a note: .replace is a JavaScript string (and others) method, not a jQuery method.
I think you're asking to do something like this:
$(".any-building").click(function () {
//replace all building sources with the unhighlighted version
$(".any-building").attr('src', function () {
return $(this).attr('src').replace('buildingc', 'building');
});
//replace clicked image with highlighted one
$(this).attr('src', $(this).attr('src').replace('building', 'buildingc'));
});
A possible downside is that with a lot of images this swap may take a long time or cause some flicker. If that's the case, then you may want to add a class .active to the highlighted image or something like that and only do the swap for that image and the newly clicked one.
A common learning mistake in jQuery is to focus on ID's for all types of selectors. They work great for very small number of elements however become very unwieldy fast for large groups of elements that can easily be managed by simpler code methods.
You want to be able to write far more universal code where one handler would cover all of your links that share the same functionality in the page .
Example:
var $mainImage=$('#mainImage')
var $buildingLinks=$('.buildingliststyle a').click(function(){
/* "this" is the link clicked*/
/* get index of this link in the whole collection of links*/
var index=$buildingLinks.index(this);
/* perhaps all the image urls are stored in an array*/
var imgUrl= imagesArray( index);
/* perhaps the image urls are stored in data attribute of link( easy to manage when link created server side)*/
var imgUrl=$(this).data('image');
/* store the current image on display (not clear how page is supposed to work)*/
var currImage=$mainImage.attr('src');
$mainImage.data('lastImage', currImage);/* can use this to reset in other parts of code*/
/* nw update main image*/
$mainImage.attr('src', imgUrl);
/* load ajax content for this link*/
$('#ajaxContainer').load( $(this).attr('href') );
/* avoid browser following link*/
return false;
});
/* button to reset main image from data we already stored*/
$('#imageResetButton').click(function(){
$mainImage.attr('src', $mainImage.data('lastImage') );
})
Can see that by working with groups of elements in one handler can do a lot with very little code and not needing to focus on ID
Code above mentions potentially storing image url in data attribute such as:
Building name

Updating target href problem

I'm working on a little image gallery, where you'd roll over a small thumbnail, the larger image would display over it. Clicking on the image would load a full size version in an overlay.
http://shopcoobie.server303.com/shop/
The issue is with the larger image, the rollovers are working fine, but the script I have updates the href which points to the full size image only seems to work the first time I click the image.
$$('.thumbs img').each(function(s) {
$(s).observe('mouseover', function(e) {
var el = e.target;
var thumb = $(el).src;
var large = $(el).alt;
$(el).up(3).down(1).href = large;
$(el).up(3).down(2).src = thumb;
console.log((el).up(3).down(1).href);
console.log(thumb);
});
});
The console outputs the proper image reference, so it seems this should work (and partially does), Im just not sure why it only works once.
Thanks
Rich
I think the lightview plugin builds up its list of images first, then you change the src dynamically, and it doesn't update. So try adding a call to Lightview.updateViews(); at the end of the mouseover handler above.
From Lightview:
Lightview.updateViews(): Force a reset of all Lightview
elements on the page. Most of the time
you won't need to do this since
Lightview will pick up on newly
inserted elements automatically. After
updating existing elements it might be
required to call this function.
So yours is a case where it doesn't automatically pick up the change.

Categories