Query text() over dynamically added img - javascript

I realize it's probably an already answered question, but I wanted to ask, if there is something new on the market, that can easily solve my issue.
I'm loading images to specified coordinates using javascript.
var span = document.createElement("span");
span.innerHTML = "<img src=\"source.gif\" id=\"someid\">";
span.style.position = "absolute";
span.style.left = coodinatesLeft[i] + "px";
span.style.top = coodinatesTop[i] + "px";
document.body.appendChild(span);
Later on, when the mouse goes over the images I want to use the simple mouseenter function in jquery
$("mydivid").mouseenter(function(){ $(this).text("something"); });
to write a text there, where the image is. And I don't get any text, I suppose, because the image is more foreground then the text. Other times I've used it, and it worked, but then I just had a div, and no actual image source on it.
Is there a way to keep the structure and append the text over the image?
PS: I read about the z-index, but not sure if it is exactly what I need, since I don't have a pre-defined css class for the images.
Thanks in advance!

You should use event delegation for dynamically added elements.
$('<span />')
.html('<img src="source.gif" class="myImages">')
.css({
'position': 'absolute',
'left': coodinatesLeft[i] + 'px',
'top': coodinatesTop[i] + 'px'
})
.appendTo('body');
$('.myImages').hover(function() {
$(this).append('<span id="myText">MY TEXT HERE</span>');
}, function() {
$('#myText').remove();
});
CSS:
#myText {
height: same as .myImages;
width: same as .myImages;
opacity: .5;
background: #ccc;
}

You could try something like this:
var span = document.createElement("span");
span.innerHTML = "<img src=\"source.gif\" id=\"someid\" class=\"image-class\">";
span.style.position = "absolute";
span.style.left = coodinatesLeft[i] + "px";
span.style.top = coodinatesTop[i] + "px";
var imgText = document.createElement("span");
imgText.className = "overlay-text";
span.appendChild(imgText);
document.body.appendChild(span);
Add the following css:
.image-class {
width: 100px;
height: 100px;
background-color: red;
}
.overlay-text {
position: absolute;
left: 0;
top: 0;
}
Please checkout this jsfiddle: https://jsfiddle.net/duLL2wrj/
$("#mydivid").mouseenter(function(){ $(this).children('.overlay-text').text("something"); });
$("#mydivid").mouseleave(function(){ $(this).children('.overlay-text').text(""); });

Related

image fading out when size is big using HTML drag

We are using drag & drop feature of HTML.
As you can see div width is 410px and if start dragging this div, its ghost image of it fades out completely. I have big/large images to display while dragging them and as they are big in size they start to fade out completely. Is there any problem ?
If I change div width to 210px then the ghost image looks fine. Then what's the problem with 410px is there any limit to it? If yes, how can I increase it ?
var els = document.getElementsByTagName('div');
for (var i = 0, l = els.length; i < l; i++) {
els[i].addEventListener('dragstart', function (e) {
e.dataTransfer.setData('text/plain', e.target.innerText);
});
}
div {
display: inline-block;
line-height: 300px;
text-align: center;
background: orange;
margin: 20px;
}
<div draggable="true" style="width:410px">Item 2</div>
hide original image using event.dataTransfer.setDragImage(new Image(), 0, 0);
on dragstart. onDrag get the ghost image, update position using event.pageX, evenet.pageY
onDrag(event){
event.preventDefault();
const parentElement = <HTMLDivElement>(document.querySelector('.darggable-ghost-wrapper'));
parentElement.style.position = "fixed";
parentElement.style.left = event.pageX + "px";
parentElement.style.top = event.pageY + 5 + "px";
parentElement.style.opacity = ArhitectUtlityConstants.GHOSTPREVIEW.ghostOpacity;
parentElement.style.border = "1px solid green !important";
}

Move image in every click javascript

I try to move the image in every click but it just move one time.See the code:
<img id="myImg" src="">
<script>
function move() {
var img = document.getElementById("myImg")
img.style.left += "2px";
}
</script>
<button onclick="move()"></button>
Anyone knows how to make it work?
When you get the value of left property, it looks like this: 0px. It's a string. So if you want to calculate it, you need to parse it to a number. Before doing that, you can split px part to get the number.
img {
position: absolute;
width: 150px;
height: 100px;
left: 0px;
}
button {
margin-top: 100px;
}
<img id = "myImg" src = "https://images.unsplash.com/photo-1474511320723-9a56873867b5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80">
<script>
function move(){
var img = document.getElementById("myImg");
img.style.left = +img.style.left.substring(0, img.style.left.length - 2) + 2 + 'px';
}
</script>
<button onclick = "move()">Move</button>
This line
img.style.left += "2px";
produces invalid CSS. You want to extract the integer each time, add 2, then add the "px" unit back in.
const img = document.getElementById("myImg")
function move() {
img.style.marginLeft = img.style.marginLeft ? parseInt(img.style.marginLeft, 10) + 2 + "px" : "2px"
}
<img id="myImg" src="https://placekitten.com/200/200">
<button onclick="move()">Move Image</button>
This is a very clumsy way to move an image. Please educate yourself about canvas object. But as you are a begginer and may just need a quick fix, here's a way to get your code working:
<img id = "myImg" style="width: 100px; height: 100px;" src ="https://upload.wikimedia.org/wikipedia/en/thumb/e/ec/Soccer_ball.svg/600px-Soccer_ball.svg.png">
<script>
var margin = 0;
function move(){
var img = document.getElementById("myImg")
margin += 2;
img.style.marginLeft = margin + "px";
}
</script>
<button onclick = "move()" >Move</button>
if you want to move image then you could move it either right or left for that try to fix your code at left - px
<img id = "myImg" src = "">
<script>
function move(){
var img = document.getElementById("myImg")
img.style.left += "2px";
}
function moveleft() {
imgObj.style.left = parseInt(imgObj.style.left) + 10 + 'px';
}
</script>
<button onclick = "moveleft();">

How can you get the final height on an element transitioning with css?

If you have an element whose height is animating using a CSS transition, is there a way to use jQuery or pure Javascript to get its finished height before the transition completes?
Consider the following example: https://jsfiddle.net/qm6zz0kq/
<div id="test"></div>
<style>
#test {
width: 100px;
height: 0;
transition: height 2s ease-in-out;
background: #F00;
}
#test.showing {
height: 100px;
}
</style>
<script>
var testElement = document.getElementById('test');
setTimeout(function() {
testElement.className = 'showing';
}, 100);
setInterval(function() {
testElement.innerHTML = 'Height: ' + testElement.clientHeight;
}, 100);
</script>
How could you modify the interval so it always generates "Height: 100"?
I've considered doing some kind of jQuery clone that doesn't have to transition and measuring its height but in this instance, the CSS is nested enough that I'd have to clone basically of the element's parents to make sure it's correct and that could be expensive.
You can put another hidden div (hidden-test, as an example) that is the same as the div test and add to it the class showing right away (without timeout), then get its height, that will be the same.
Look here an example: https://jsfiddle.net/qm6zz0kq/1/
You could read the actual CSSRule, note though this would just get the value defined in the CSS. For instance if the height was specified as 70% it would give 70% and not the actual px height it would end up as, eg if parents height was 170px, it wouldn't give you the value of 70% of 170px. Also note this will not work if the stylesheet is include from a file <link href="css.css">
var testElement = document.getElementById('test');
setTimeout(function() {
testElement.className = 'showing';
}, 100);
setTimeout(function() {
var rule = getRule("#test.showing");
if(rule){
testElement.innerHTML = 'Height: ' + rule.style.height;
}
}, 100);
function getRule(selector) {
var foundRule = null;
[].slice.call(window.document.styleSheets)
.filter(sheet=>sheet.rules || sheet.cssRules).forEach(sheet=>{
foundRule = foundRule || [].slice.call(sheet.rules||sheet.cssRules)
.filter(rule=>rule.selectorText == selector);
});
if(foundRule && foundRule[0]) return foundRule[0];
}
#test {
width: 100px;
height: 0;
transition: height 2s ease-in-out;
background: #F00;
}
#test.showing {
height: 100px;
}
<div id="test"></div>
You could also put in an element that is a clone. You do not have to also clone the parents like you mention in your question. You just have to insert the element into the same parent. This particular example uses display:none to hide the element, the returned value will not be a calculated value. Again like above if the parent's height is 400px and the height of the element is 75%, 100px will not be returned, 75% would be.
var clone = testElement.cloneNode();
//remove transition so we can get end height
clone.style.transition = "none";
//display:none so we do not have to see the temp element
clone.style.display = "none";
clone.classList.add("showing");
testElement.parentNode.appendChild(clone);
var endHeight = window.getComputedStyle(clone).height;
var testElement = document.getElementById('test');
setTimeout(function() {
testElement.className = 'showing';
}, 100);
//Clone the element
var clone = testElement.cloneNode();
//remove transition so we can get end height
clone.style.transition = "none";
//display:none so we do not have to see the temp element
clone.style.display = "none";
clone.classList.add("showing");
testElement.parentNode.appendChild(clone);
var endHeight = window.getComputedStyle(clone).height;
//Remove it as we dont need it anymore
clone.remove();
setTimeout(function() {
testElement.innerHTML = 'Height: ' + endHeight;
}, 300);
#parent {
height:300px;
}
#test {
width: 100px;
height: 0;
transition: height 2s ease-in-out;
background: #F00;
}
#test.showing {
height: 70%;
}
<div id="parent">
<div id="test"></div>
</div>
If you want the actual calculated height you would need to change the clone to use a couple different stles.
visibility:hidden to hide it instead of display:none as display will make it so we won't get a calculated value.
position:absolute to prevent it from modifying the parents dimensions
clone.style.visibility = "hidden";
clone.style.position = "absolute";
//needed to make sure element is contained by parent
parent.style.position = parent.style.position || "relative";
var endHeight = window.getComputedStyle(clone).height;
var testElement = document.getElementById('test');
setTimeout(function() {
testElement.className = 'showing';
}, 100);
//Clone the element
var clone = testElement.cloneNode();
//remove transition so we can get end height
clone.style.transition = "none";
clone.style.visibility = "hidden";
clone.style.position = "absolute";
clone.classList.add("showing");
var parent = testElement.parentNode;
parent.style.position = parent.style.position || "relative";
parent.appendChild(clone);
var endHeight = window.getComputedStyle(clone).height;
//Remove it as we dont need it anymore
clone.remove();
setTimeout(function() {
testElement.innerHTML = 'Height: ' + endHeight;
}, 300);
#parent {
height:300px;
}
#test {
width: 100px;
height: 0;
transition: height 2s ease-in-out;
background: #F00;
}
#test.showing {
height: 70%;
}
<div id="parent">
<div id="test"></div>
</div>
You can add an 'animationend' event listener to the element .
Example :
testElement.addEventListener('animationend' , showNewHeight);
showNewHeight function(){
// show new height ...do something after animation .
}
Source : http://www.w3schools.com/jsref/event_animationend.asp
hope this helps..

setAttribute background-image can't be changed. Stuck at default value

function showHome() {
removeSlideShow();
var homeHeader = document.createElement("div");
homeHeader.setAttribute("id", "homeHeader");
document.getElementById("window").insertBefore(homeHeader, document.getElementById("content"));
var slideShowDiv = document.createElement("div");
var images = ["slideShow/slideShow-1.jpg", "slideShow/slideShow-2.jpg", "slideShow/slideShow-3.jpg", "slideShow/slideShow-4.jpg", "slideShow/slideShow-5.jpg", "slideShow/slideShow-6.jpg", "slideShow/slideShow-7.jpg"];
homeHeader.appendChild(slideShowDiv);
startSlideShow(slideShowDiv, images);
content.innerHTML = "";
}
function startSlideShow(element, images) {
var iterator = 0;
element.setAttribute("id", "slideShowDiv");
element.setAttribute("style", "background-image: url(" + images[0] + ")");
var startInterval = setInterval(function() {
iterator++;
if (iterator == images.length) iterator = 0;
element.setAttribute("style", "background-image: url(" + images[iterator] + ")");
element.style = "background-image: url(" + images[iterator] + ")";
transition(element);
}, 3000);
}
function removeSlideShow() {
if (document.getElementById("homeHeader")) {
document.getElementById("window").removeChild(document.getElementById("homeHeader"));
}
}
function transition(element) {
element.setAttribute("style", "opacity:0.01;");
var i = 0;
var set = setInterval(function() {
i += 0.01;
element.setAttribute("style", "opacity:" + i + ";");
}, 4);
setTimeout(function() {
clearInterval(set);
element.setAttribute("style", "opacity:1;");
}, 500);
}
div#homeHeader {
background-color: #FFF;
width: 900px;
height: 280px;
border: solid 2px #F00;
border-radius: 20px;
}
div#slideShowDiv {
background-image: url(slideShow/slideShow-1.jpg);
background-color: #FFF;
width: 898px;
height: 278px;
border: solid 1px #FFF;
border-radius: 20px;
background-size: 100% 100%;
}
What i want to do is change the background image every 3 seconds. The code work but it's not changing the image, stays at 'slideShow-1.jpg'. If i remove the transition(element); part, the image rotate just fine. What should i do to get it work? Im still beginner in Javascript, will learn jquery when i got better. Sorry for my grammar.
If i remove the transition(element); part, the image rotate just fine.
The transition part sets a new value for the style attribute.
Setting a new value for the attribute replaces the old value.
You are removing the style for the background image. (So the one from the stylesheet is applied again instead).
What should i do to get it work?
Don't use setAttribute(..., ...) to modify styles.
Use .style.cssPropertyName = ... instead.

How to apply css to a dynamically created div?

Here I have a function that creates a div box, but I wish to move the styling to a external css file. When I do that, however, the boxes are no longer styled. How could I apply the css to the div boxes that are created dynamically? Is it even worth moving the styling to an external css file?
function createBox() {
var box = document.createElement("DIV");
box.setAttribute("id", "box");
document.body.appendChild(box);
boxStyle = box.style;
boxStyle.position = "absolute";
boxStyle.background = '#'+Math.floor(Math.random()*16777215).toString(16);
boxStyle.width = Math.floor(Math.random()*50) + '%';
boxStyle.height = Math.floor(Math.random()*50) + '%';
boxStyle.top = Math.floor(Math.random()*100) + '%';
boxStyle.left = Math.floor(Math.random()*100) + '%';
}
EDIT: I realized that what's been causing me grief in my CSS is that I was using Math.floor and Math.random() functions that don't work in CSS. Silly me!
As you are creating div with id #box, add the following css in the external css file and include it in the <head>
#box {
position: absolute;
background: red;
width: 90px;
height: 50px;
left: 100;
top: 100;
}
It looks like you will creating more boxes of with same id #box. I would recommend you to create based on classes. And use css to apply the styles based on the classname.
function createBox() {
var box = document.createElement("DIV");
box.setAttribute("class", "boxes");
document.body.appendChild(box);
}
css:
.boxes {
position: absolute;
background: red;
width: 90px;
height: 50px;
left: 100;
top: 100;
}
demo
You can apply CSS to dynamicly created items the same way for usual HTML. All you need is to target the correct selector.
http://codepen.io/anon/pen/mnIhj
You can gather the properties you wish to apply on the div box in a class in external style sheet, and use:
function createBox() {
var box = document.createElement("DIV");
box.setAttribute("id", "box");
box.className = "boxStyle";
document.body.appendChild(box);
}
Try this chnages in your script,
function createBox() {
var box = document.createElement("DIV");
box.setAttribute("id", "box");
document.body.appendChild(box);
var boxStyle = document.getElementById("box").style;
boxStyle.position = "absolute";
boxStyle.background = '#'+Math.floor(Math.random()*16777215).toString(16);
boxStyle.width = Math.floor(Math.random()*50) + '%';
boxStyle.height = Math.floor(Math.random()*50) + '%';
boxStyle.top = Math.floor(Math.random()*100) + '%';
boxStyle.left = Math.floor(Math.random()*100) + '%';
}

Categories