I am sure this is rediculously simple, but I'm stumped.
Very simply, I want to create a text link that changes the width property of an image on mouse over, and on mouse out, return to the original.
The image I wish to change has an id 'photoimage'
Here's what I have, but it's not doing anything. Any ideas>
<a href="#" onmouseover="MM_changeProp('photoimage','','Width','10','IMG')">
photographs
</a>
Sorry here is the function
function MM_changeProp(objId,x,theProp,theValue) { //v9.0
var obj = null; with (document){ if (getElementById)
obj = getElementById(objId); }
if (obj){
if (theValue == true || theValue == false)
eval("obj.style."+theProp+"="+theValue);
else eval("obj.style."+theProp+"='"+theValue+"'");
}
Any help much appreciated
Javascript:
function setWidth( elementId, width ) {
var element = getElementById(elementId);
element.style.width = width;
}
<a href="#"
onmouseover="setWidth('photoimage','200px')"
onmouseout="setWidth('photoimage', '100px')"> photographs </a>
Related
I have a problem when I am making the website for one gallery.
I made the code for the button that can show and hide multiple images.
I intend to make the button can place several images in randomly.
I write the code that can function for only one image.
Please tell me the code that functions as a button to place multiple images in a random location.
Users can hide images by pressing the button.
And when users press the button again, it places the images in another random location.
const btn = document.querySelector("button");
const height = document.documentElement.clientHeight;
const width = document.documentElement.clientWidth;
const box = document.getElementById("color");
btn.addEventListener("click", () => {
let randY = Math.floor((Math.random() * height) + 1);
let randX = Math.floor((Math.random() * width) + 1);
box.style.top = randY + "px";
box.style.right = randX + "px";
});
function showhide() {
var x = document.querySelectorAll("#color");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].style.display === "block") {
x[i].style.display = "none";
} else {
x[i].style.display =
"block";
}
}
}
body {
height: 500px;
}
.random {
position: absolute;
}
<button onclick="showhide()" value="Zeige Features" id="button">click me</button>
<img id="color" style="display: none;" class="random" src="http://lorempixel.com/200/200/">
<img id="color" style="display: none;" class="random" src="http://lorempixel.com/200/200/">
You're doing the correct thing in showHide() when using querySelectorAll. You are then able to get all images.
You should never have elements with the same ids. They should be unique. So querySelectorAll("#color") works, but it's now how you should do. Do a querySelector on "img.random" instead.
getElementById only returns a single element, not like querySelectorAll. So you need to use querySelectorAll('img.random').
This might be beyond your knowledge, I don't think you should add the images in HTML, but in javascript code.
a) Add all image paths in an array: ['https://image.com/image.png', ...]
b) Add a single img element. <img id="template" class="random">
c) In javascript code, clone that element for each image path in the array. You can use cloneNode for this.
d) Randomize each position for each element, just like you have done now.
e) Add each element to the DOM through appendChild. Have a unique div that you append to. Be sure to clear it every time second time you hit the button.
f) Solve all bugs along the way. :P
The problem
The main issue here is that you're using getElementById to query #color
const box = document.getElementById("color");
Since getElementById only returns one element (but you have two in your DOM) and the style only applies to one element. That's why you're seeing only one element is randomly moving and the other just stay in the same place.
A side note here, id should be unique in a DOM.
You're in fact using the correct API for the job in the showhide function
var x = document.querySelectorAll("#color");
The fix:
To fix this, you need to query all images by their classname (as suggested in the side note, don't use id for the job)
const boxes = document.querySelectorAll(".random");
Now we have a node list, as you do in the showhide function, we need to loop thru it, I'm not using a for loop here, instead, a forEach loop, it's just more terser and a modern addition to the JS
// Since boxes are not array, we need to covert it to array so we can use that handy `.forEach` here:
Array.from(boxes).forEach(box => {
box.style.top = Math.floor((Math.random() * height) + 1) + "px";
box.style.right = Math.floor((Math.random() * width) + 1) + "px";
})
Now, this should fix your issue. See the complete code below.
const btn = document.querySelector("button");
const height = document.documentElement.clientHeight;
const width = document.documentElement.clientWidth;
const boxes = document.querySelectorAll(".random");
btn.addEventListener("click", () => {
Array.from(boxes).forEach(box => {
box.style.top = Math.floor((Math.random() * height) + 1) + "px";
box.style.right = Math.floor((Math.random() * width) + 1) + "px";
})
});
function showhide() {
var x = document.querySelectorAll(".random");
var i;
for (i = 0; i < x.length; i++) {
if (x[i].style.display === "block") {
x[i].style.display = "none";
} else {
x[i].style.display =
"block";
}
}
}
body {
height: 500px;
}
.random {
position: absolute;
}
<button onclick="showhide()" value="Zeige Features" id="button">click me</button>
<img id="color" style="display: none;" class="random" src="http://lorempixel.com/200/200/">
<img id="color" style="display: none;" class="random" src="http://lorempixel.com/100/100/">
I want to add image and text to popup of leaflet map such as this link:
https://www.bookdepository.com/
I can add image But How I can add text near the image?
my code is here:
<div id="map" style="width:270px;height:310px;"></div>
<?php
$matrix = [
[34.05777800, 51.48416700],
[38.50972200, 46.65444400],
[29.26666700, 51.21666700],
[34.05777800, 51.48416700],]
?>
<script type="text/javascript">
var matrix = JSON.parse('<?php echo json_encode($matrix);?>');
var map = L.map('map').setView(matrix[0],7);
var i = 1;
function myLoop() {
setTimeout(function () {
var div = L.DomUtil.create('div', 'my-div');
var img = L.DomUtil.create('img', 'my-img',div);
img.style.width = '60px';
img.style.height = '80px';
div.style.textAlign = 'right';
img.src = 'http://127.0.0.1:8000/productImages/64517.jpg';
L.marker(matrix[i]).addTo(map)
.bindPopup(div)
.openPopup();
map.flyTo(matrix[i]);
i++;
if (i < 10) {
myLoop();
}
}, 6000)
}
L.tileLayer('https://stamen-tiles
{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.{ext}', {
ext: 'jpg'
}).addTo(map);
myLoop();
</script>
My output is this pic:
You can use bindpopup function of leaflet to attach a pop up with your custom html.
marker.bindPopup("<div>Your custom html</div>");
You can find more information here.
You can indeed use the .bindPopup method like this (in your case) :
matrix
.bindPopup("<div> <p>Text</p> <img src="path/or/url"/> </div>");
Nevertheless it seems that using the css background-image in a <span> tag as popup image doesn't work correctly, I recommend using an <img> tag.
Hope it's helpful, you can find more information on methods there.
I have an anglarJS project that has a horizontal navigation bar. Each element in the navigation bar is a category and uses an angularJS dropdown directive to show the subcategories for that category.
I would like the drop down to fill the whole screen from left to right. Currently the drop down determines it's width from the css "min-width" property. This does not solve my desire for the drop down menu to fill the whole screen I have seen some websites do this, and was wondering if there is a way to force my dropdown to fill the whole screen from left to right.
Here is the html for the page/drop down including the css that specifies the dropdown width.
Here is a picture of the dropdown again. I added blue arrows to indicate what I mean when I want the drop down to fill the whole screen.
The pictures are pretty high resolution and show you all the details. The page is rather complex to try and replicated in a plunker.
The whole thing needs to be responsive as well, and is based off of Bootstrap 3 and AngularJS Bootstrap.
Thanks for any help you can give!
David
I found a solution for the problem.
I created a button group that floats left that is on the same row as the button group in the center. The button group that floats left only contains one button, and that button has it's visibility set to hidden.
You have the dropdown attached to this button, rather than the ones in the center, since the dropdown won't start any farther left than the beginning of the button it is attached to.
<div class="pull-left">
<div class="btn-group" dropdown is-open="isOpen">
<button type="button" style="visibility: hidden" class="btn btn-link dropdown-toggle filter-criteria-variety-category-name" dropdown-toggle ng-disabled="disabled">
<span class="caret"></span>
</button>
<div class="dropdown-menu top-level-category-drop-down-standard" ng-style="{{windowWidth}}" ng-click="$event.stopPropagation()" >
<div ng-click="$event.stopPropagation()" ng-mouseleave="close()" ng-mouseenter="keepOpen()">
<div ng-if="currentCategory != undefined">
<horizontal-menu-inner close-drop-down-menu=$parent.closeDropDownMenu top-level-category=$parent.currentCategory></horizontal-menu-inner>
</div>
</div>
</div>
</div>
</div>
And for the centered button group that contains your categories you want to trigger the dropdown you pass the 'ioOpen' variable into the centered button directive as an attribute.
<div class="text-center">
<div class="btn-group">
<div class="horizontal-top-level-category" ng-repeat="topLevelCategory in categoryNavigationGraph">
<horizontal-top-level-category is-open=$parent.isOpen current-category-id=$parent.currentCategoryId top-level-category=topLevelCategory></horizontal-top-level-category>
</div>
</div>
</div>
You then have that directive set up to close or open the drop down depending on whether the mouse enters or leaves the button in that directive
<button ng-mousemove="activeMenuItemm()" ng-mouseleave="close($event)" ng-mouseenter="open()" type="button" ng-class="{'filter-criteria-variety-category-name-hover': filterCriteriaCategoryActive}" class="btn btn-link dropdown-toggle filter-criteria-variety-category-name" ng-disabled="disabled">
{{topLevelCategory.text}}
The tricky part is not having the dropdown close when you hover down from the centered button onto the dropdown
I did this by figuring out if the mouse was leaving from "down", which should not close the dropdown, or other, which should from the last position, which was calculated In the centered button directive link function:
link: function (scope, element) {
init();
scopeLevelFunctions();
function init(){
calculateBoundry();
}
function scopeLevelFunctions(){
scope.calculateElementBoundry = function(){
calculateBoundry();
}
}
function calculateBoundry(){
var boundry = element[0].getBoundingClientRect();
scope.boundry = boundry;
scope.topBoundry = boundry.top;
scope.bottomBoundry = boundry.bottom;
scope.leftBoundry = boundry.left;
scope.rightBoundry = boundry.right;
}
},
The open function triggered by mouseenter sets the boundry, which the close calculates from that value to see if this is a mouseleave that is leaving down
$scope.open = function(){
$scope.calculateElementBoundry();
$scope.currentCategoryId = $scope.topLevelCategory.categoryId;
$scope.filterCriteriaCategoryActive = true;
$scope.timeoutPromise = $timeout(function() {
$scope.isOpen = true;
}, 150);
};
$scope.close = function($event){
$scope.lastPosition = {
x : $event.clientX,
y : $event.clientY
};
var deltaX = $scope.lastPosition.x - $event.clientX,
deltaY = $scope.lastPosition.y - $event.clientY;
if($event.clientY >= ($scope.bottomBoundry - 8))
$scope.direction = "bottom";
else
$scope.direction = "other";
if($scope.direction != "bottom"){
if($scope.timeoutPromise != undefined)
$timeout.cancel(this.timeoutPromise);
$scope.isOpen = false;
$scope.filterCriteriaCategoryActive = false;
}
else{
if($scope.isOpen == false && $scope.timeoutPromise != undefined){
$timeout.cancel(this.timeoutPromise);
$scope.filterCriteriaCategoryActive = false;
}
}
I put the timeout in there so that if the user is just scrolling to bottom of the screen the drop down does not just appear. I cancel the timeout if they mouseleave and the drop down is not open.
The dropdown gets different data in it because the centered category directive has an attribute "categoryId" that is shared with the directive that the dropdown is located in. As that categoryId is changed that directive determines what that new categories submenu should be and feeds that into the dropdown.
I know how wide the dropdown should be because in the directive that contains the dropdown/invisible button I calculated the window width:
var width = $window.innerWidth;
$scope.windowWidth = "{'min-width':" + width + "}";
and on the dropdown I use ng-style to set this width
ng-style="{{windowWidth}}"
I have a question about a lightbox see my jsFiddle.
Clicking on one of the images opens a bigger version of the painting as a page overlay.
How to use the ESC key to close this page overlay?
And how to use the arrow keys to move to the next image?
What kind of jQuery plugin / javascript would I need to make this happen?
<ul class="lb-album">
<li>
<a href="#Fly-My-Pretties-Walled-Garden">
<img src="http://sandipa.com.au/images/works-for-sale/thumbs/Fly-my-Pretties-Walled-Garden-sm.jpg" alt="Fly My Pretties: Walled Garden">
<span>Fly My Pretties</span> </a>
<div class="lb-overlay" id="Fly-My-Pretties-Walled-Garden">
x Close
<img src="http://sandipa.com.au/images/2010-2011/1000px-wide/Fly-my-Pretties-Walled-Garden.jpg" alt="Fly My Pretties: Walled Garden">
<div>
<h3>Fly My Pretties: Walled Garden<span>mixed media on canvas</span></h3>
<p>72 x 137 cm</p>
Prev
Next
</div>
</div>
</li>
<li>
<a href="#Central-Highlands-Circle-of-Gold">
<img src="http://sandipa.com.au/images/works-for-sale/thumbs/Central-Highlands-Circle-of-Gold-sm.jpg" alt="Central Highlands: Circle of Gold">
<span>Circle of Gold</span> </a>
<div class="lb-overlay" id="Central-Highlands-Circle-of-Gold">
x Close
<img src="http://sandipa.com.au/images/works-for-sale/Central-Highlands-Circle-of-Gold.jpg" alt="Central Highlands: Circle of Gold">
<div>
<h3>Central Highlands: Circle of Gold<span>mixed media on canvas</span></h3>
<p>51 x 108 cm</p>
Prev
Next
</div>
</div>
</li>
</ul>
A full implementation of Pure Javascript Lightbox or Image Popup Modal is available in one my Answers at https://stackoverflow.com/a/67169851/8210884.
This Answer mentioned in the link above allows handling both the issues of Hiding Lightbox with ESC key as well as navigating through images in Lightbox using Left and Right arrow key.
Here are the Pieces of code from that Answer which will help us achieve these Two issues.
Hiding the Lightbox with ESC key :
if(event.keyCode==27){ // If ESC key is pressed
if(document.getElementById("lightbox-container").classList.contains("showcontainer")){ // LIGHTBOX ON
document.getElementById("lightbox-container").classList.remove("showcontainer");
}
}
Navigating through all the images on a Webpage in Lightbox with Left and Right Arrow key :
else if(event.keyCode==37) { // Left arrow key
if(document.getElementById("lightbox-container").classList.contains("showcontainer")){ // LIGHTBOX ON
// first get the URL of image displayed in the LIGHT BOX
var currimgsrc = document.getElementById("lightbox-cont-img").getAttribute("src");
// now match the sequence number in the array
var serialofarray = 0;
for(k=0;k<allimgurlarray.length;k++){
if(currimgsrc == allimgurlarray[k][2]){
serialofarray = allimgurlarray[k][0];
}
}
// with LEFT arrow, we are supposed to reduce the sequence and then use its ATTR SRC to LIGHT BOX
if(serialofarray<=0){
serialofarray = allimgurlarray.length - 1;
}
else {
serialofarray = serialofarray - 1;
}
console.log("Left Arrow : "+serialofarray);
document.getElementById("lightbox-cont-img").setAttribute("src", allimgurlarray[serialofarray][2]);
}
}
else if(event.keyCode==39) { // Right Arrow Key
if(document.getElementById("lightbox-container").classList.contains("showcontainer")){
// first get the URL of image displayed in the LIGHT BOX
var currimgsrc = document.getElementById("lightbox-cont-img").getAttribute("src");
// now match the sequence number in the array
var serialofarray = 0;
for(l=0;l<allimgurlarray.length;l++){
if(currimgsrc == allimgurlarray[l][2]){
serialofarray = allimgurlarray[l][0];
}
}
// with RIGHT arrow, we are supposed to increase the sequence and then use its ATTR SRC to LIGHT BOX
if(serialofarray>=allimgurlarray.length-1){
serialofarray = 0;
}
else {
serialofarray = serialofarray + 1;
}
console.log("Right Arrow : "+serialofarray);
document.getElementById("lightbox-cont-img").setAttribute("src", allimgurlarray[serialofarray][2]);
}
}
These conditional cases related to Key Pressing events are tackled in document.onkeydown = function(event).
This piece of code below is very important for disabling the default behaviours of Key pressing events on IMG tags as well as stacking up all the images on a webpage in an Array to allow Navigation in Lightbox with Left and Right arrow key.
// Select all A tags with IMG child nodes
var atagswithimgtag = document.querySelectorAll("a[href]");
// then prevent the default behaviour of A tags by preventing of opening new page by HREF
// as well as collect all the HREF of A tags with images to enable RIGHT and LEFT arrow key
var allimgurlarray = [];
for(i=0;i<atagswithimgtag.length;i++){
var childAIMGtag = atagswithimgtag[i].childNodes;
if (childAIMGtag[0].nodeType != Node.TEXT_NODE) // or if (el[i].nodeType != 3)
{
// this seems too be a A tag with IMG tag as Childnode
// first we need to prevent the default behaviour of opening the IMG in New Tab
atagswithimgtag[i].addEventListener("click", function(event){
event.preventDefault();
});
// second is when we need to fill image URL aray with A HREF
var listofnodes = atagswithimgtag[i];
allimgurlarray[i] = [];
allimgurlarray[i][0] = i;
allimgurlarray[i][1] = " Image URL is ";//listofnodes.getAttributeNode("title").value;
allimgurlarray[i][2] = listofnodes.getAttributeNode("href").value;
}
console.log(childAIMGtag[0].innerHTML);
}
hi all im building a menu and im trying to put an hover effect on each menu item
but... when i hover everything is working great and i get the html i want and the menu item has a backgruond image.
but the unhover effect dosnt fire most of the times. i found out that if i move my mouse horziantly across the ul menu it works fine. but if my mouse does a vertical move across the li item it dosnt fire.
my code is this:
$("ul.menu li").hover(ChangeToHoverMenuItem, ChangeBackMenuItem);
function ChangeToHoverMenuItem()
{
var currLi = $(this);
lastLi = currLi;
var currMenuItemText = currLi.find("a").text();
currLi.html("");
currLi.append("<div style='float:right;'><div class='right_item_hov'></div>" +
"<a class='item_menu_hov'>" +
currMenuItemText +
"</a>" +
"<div class='left_item_hov'></div></div>");
}
function ChangeBackMenuItem ()
{
var currLi = $(this);
var currMenuItemText = currLi.find("a").text();
currLi.html("");
currLi.append("<a>" + currMenuItemText + "</a>");
}
<div class="menu_middle">
<ul class="menu">
<li>
<a>
main
</a>
</li>
<li>
<a>
gallery
</a>
</li>
<li>
<a>
event
</a>
</li>
<li>
<a>
about
</a>
</li>
<li>
<a>
contact
</a>
</li>
</ul>
</div>
thank you
The strange thing is, that there are two mouseenter() events on sibling elements without a mouseleave() event in between.
One idea is to register the mouseenter() and mouseleave() event instead of using hover(). hover() should do the same, but how knows. If this works, the problem lies in the implementation of hover() but I don't think so.
$("ul.menu li")
.mouseenter(ChangeToHoverMenuItem)
.mouseleave(ChangeBackMenuItem);
Another idea is to ensure that the mouseleave() code was executed. In your "doHover" handler you can check if there is anhoveredItem. If so, you can call the ChangeBackMenuItem function with the still hovered item as this. To ensure that the "unhover" handler is called when you leave your ul, you need a mouseleave event on this, that does the same. This solution relies on a working mouseleave on the ul element.
$(function() {
var hoveredItem = null;
function ChangeToHoverMenuItem()
{
if (hoveredItem) {
ChangeBackMenuItem.call(hoveredItem);
}
hoveredItem = this;
var currLi = $(this);
lastLi = currLi;
var currMenuItemText = currLi.find("a").text();
currLi.html("");
currLi.append("" +
"" +
currMenuItemText +
"" +
"");
}
function ChangeBackMenuItem ()
{
var currLi = $(this);
var currMenuItemText = currLi.find("a").text();
currLi.html("");
currLi.append("" + currMenuItemText + "");
hoveredItem = null;
}
$("ul.menu li").hover(ChangeToHoverMenuItem, ChangeBackMenuItem);
$("ul.menu").mouseleave(function() {
if (hoveredItem) {
ChangeBackMenuItem.call(hoveredItem);
hoveredItem = null;
}
});
});
Try giving a boundary to the li (using css 'border' property) and then add a console.log(firebug) statement in the beginning of 'ChangeBackMenuItem' to see if the function is called each time you un-hover.