I want to create two animations in css. In my project, I use two button, one object. I care, that the first button is being clicked, the first animation on the object is being run.
I know, what I should do, when I have one button and one animation, but I do not know how to solve problem with two different animations on the same object.
Edit 3. I find problem!
Does this meet your requirements?
let btn_a = document.getElementById('a')
let btn_b = document.getElementById('b')
let btn_c = document.getElementById('c')
let div = document.getElementById('obj')
btn_a.addEventListener('click', function() {
div.className = 'anim-a'
})
btn_b.addEventListener('click', function() {
div.className = 'anim-b'
})
btn_c.addEventListener('click', function() {
$('#obj').animate({}, function(){
$('#obj').css({transform: 'rotate(30deg) translate(200px)'})
})
})
div {
background-color: pink;
width: 100px;
transition: all linear 0.5s;
}
.anim-a {
background-color: yellowgreen;
width: 150px;
}
.anim-b {
background-color: grey;
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='obj'>animated</div>
<button id='a'>anim-a</button>
<button id='b'>anim-b</button>
<button id='c'>anim-c</button>
EDIT
Without css fields, assuming that you're using jQuery, you can use .animate(). However, .animate() won't take transform as its property. We'll do this in the callback.
btn_c.addEventListener('click',function() {
$('#obj').animate({}, function(){
$('#obj').css({transform: 'rotate(30deg)'})
})
})
Related
i'm trying to change each of my div's background color to black when my mouse enters the div using an eventlistener. it currently is only switching the first div to black but not any other div. why is my eventlistener only applying to the first 'contentDivs' div?
example:
this is my html code:
<body>
<div id="mainContainer"></div>
<script src="index.js"></script>
</body>
this is my javascript code:
for(x=0; x<64; x++) {
const contentDivs = document.createElement('div');
contentDivs.id = 'contentDivs';
document.getElementById('mainContainer').appendChild(contentDivs);
}
document.getElementById('contentDivs').addEventListener('mouseenter', () => {
document.getElementById('contentDivs').style.background = 'black';
})
this is what shows up when inspecting the elements in google chrome:
If you want to select many elements you can use querySelectorAll. If you want to select one please use querySelector.
I've used minimal changes for your example. Ideally you should take advice of comments and change the identifying method to be class rather than id.
Lastly, I've added another effect using css alone, so you can compare how to make style changes using :hover class.
for (x = 0; x < 64; x++) {
const contentDivs = document.createElement('div');
contentDivs.id = 'contentDivs';
document.getElementById('mainContainer').appendChild(contentDivs);
}
document.querySelectorAll('#contentDivs').forEach(function(elem) {
elem.addEventListener('mouseenter', () => {
elem.style.background = 'black';
})
})
#contentDivs {
width: 20px;
height: 20px;
background: pink;
float: left;
margin: 10px;
transition: 500ms all;
}
#contentDivs:hover {
transform: scale(1.5);
}
<body>
<div id="mainContainer"></div>
</body>
I'm pretty sure this is currently infeasable.
I have an animation that involves an element moving from an absolute position to an inline one. For reasons, I can not know how the container is sized, nor how the element I'm animating is sized.
What I need to know is what the size of the HTML Element will be after the transformation, without any jittery drawing.
This makes the problem very difficult (likely undoable) because I have no way to know if adding the element will resize the parent, or resize the element itself.
What I need is a means of looking into the future.
const byId = (id) => document.getElementById(id);
#container {
height: 3em;
min-width: 50%;
background: teal;
}
#mystery {
background: purple;
}
<div id="container">
<div id="mystery">Some Text</div>
</div>
<button onClick='byId("mystery").style.position = "relative"'>Position Relative</button>
<button onClick='byId("mystery").style.position = "absolute"'>Position Absolute</button>
Currently, these are the only solutions I can imagine (they're all absurd):
Clone the entire webpage HTML, make the clone have opacity: 0; pointer-events: none and render what the future will be secretly.
Capture the paint data of the current page (basically screenshot), overlay that while secretly modifying the page, get my future, revert, and remove the screenshot overlay.
Similar to number 2, is there a way to ❄️freeze❄️ rendering of a page for 3-4 frames?
I remember seeing a "sizing worker" something-or-rather a long time ago. Couldn't find any information on it now, but it seems like it might be useful?
You can simply change the property, measure the sizes you want and then change the property back. JS is fast enough to do it all between renderings, as long as you keep it all in the same thread. Have you tried that at all?
Asker Edit:
Here's the code to prove it works.
function byId(id){ return document.getElementById(id); }
const tweenyEl = byId("tweeny");
function appendTweeny() {
tweenyEl.style.opacity = "1";
const startingWidth = tweenyEl.clientWidth + "px"
tweenyEl.style.position = "relative";
const targetWidth = tweenyEl.clientWidth + "px";
console.log(startingWidth, targetWidth);
tweenyEl.style.width = startingWidth;
requestAnimationFrame(() =>
requestAnimationFrame(() =>
tweenyEl.style.width = targetWidth
)
);
}
function resetTweeny() {
tweenyEl.style.position = "";
tweenyEl.style.width = "";
tweenyEl.style.opacity = "0.1";
}
#container {
display: inline-block;
height: 3em;
min-width: 150px;
background: teal;
}
#tweeny {
font-family: arial;
color: white;
position: absolute;
background: purple;
transition: all 0.5s ease;
opacity: 0.1;
}
<div id="container">
<div id="tweeny">I'm Tweeny</div>
</div>
<br>
<button onClick='appendTweeny()'>Append Tweeny</button>
<button onClick='resetTweeny()'>Reset Tweeny</button>
I would suggest cloning the page into an iframe and then positioning the iframe off the screen.
<iframe style="width:100vw;height:100vh;left:-101vw;positionabsolute"><iframe>
Also bear in mind that the user can zoom in-and-out at will! Different browsers might render the same thing in different ways. You really don't know how big an element will be until it does so.
I don't know if you can get anywhere by specifying display: none; ... whether or not the browser would bother to make these calculations for an object that isn't visible.
You can clone on the fly an element with same transformation with delay 0 and then calculate it's width and height, then do what you want with your actual element it's still animating
Currently, I have a button class which lets me place a clickable button inside a sentence, and a div class which lets me add content to the button which I placed at the end of the paragraph containing the sentence.
This is an example of how I use them
Try to click <button class="col">THIS</button> and see what happens.
<div class="con">nice!</div>
Did you try?
When this text is displayed on the page, the two sentences are placed inside two different paragraphs, so the div object is placed between them.
Here is a snippet with the css classes and the javascript.
( function() {
coll = document.getElementsByClassName("col");
conn = document.getElementsByClassName("con");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].setAttribute('data-id', 'con' + i);
conn[i].setAttribute('id', 'con' + i);
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = document.getElementById(this.getAttribute('data-id'));
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
} )();
.col {
cursor: help;
border-radius: 0;
border: none;
outline: none;
background: none;
padding: 0;
font-size: 1em;
color: red;
}
.con {
padding: 0 1em;
max-height: 0;
overflow: hidden;
transition: .3s ease;
background-color: yellow;
}
Try to click <button class="col">THIS</button> and see what happens.
<div class="con">nice!</div>
Did you try?
I wonder if it is possible to implement a shortcut to place the two objects with one command, that is to obtain the previous example by using something like this
Try to click [[THIS|nice!]] and see what happens.
Did you try?
What I mean is that the command [[THIS|nice!]] should place the object <button class="col">THIS</button> in the same position and the object <div class="con">nice!</div> at the end of the paragraph containing the command.
Is it possible to implement such a command (or a similar one)?
EDIT
I forgot to say that the content of the button, ie what is written inside the div, should also be possible to be a wordpress shortcode, which is a shortcut/macro for a longer piece of code or text.
Using jQuery, closest() find the nearest <p> element and add <div class="con">nice!</div> after <p> element. To toggle you can use class active and add or remove .con element.
$('.col').click(function(){
let traget = $(this).closest('p');
if(traget.hasClass('active')) {
traget.removeClass('active');
traget.next('.con').remove();
} else {
traget.addClass('active');
traget.after(`<div class="con">${$(this).data('message')}</div>`);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Try to click <button class="col" data-message="Hello">THIS</button> and see what happens.</p>
<p>Did you try?</p>
You usually dont use div to type text. you use it to define areas or group items. you could obtain what youre asking for in a 1 sentence like this:
html
<h1> some random text <a class="btnID">button</> some more text<h1>
css
.btnID {
color: red;
}
I appended a few divs with inside img tags. Every tag has own unique id = "theImg"+i where "i" is number. I want to mouseover on specific img and show the content of span (which also have specific id with number). Here is my code so far but not working.
var j;
document.onmouseover = function(r) {
console.log(r.target.id);
j = r.target.id;
}
$(document).on({
mouseover: function(e){
$("span").show();
},
mouseleave: function(e){
$("span").hide();
}
}, "img#"+j);
If you have a span after every img, maybe it's a good idea to not use JavaScript at all? ;-)
You could use :hover pseudoclass in CSS, making your thing always work reliably.
Consider the following example:
img + span {
display: none;
}
img:hover + span {
display: block;
}
/*/ Optional styles /*/
div {
position: relative;
float: left;
}
div img + span {
position: absolute;
color: #fff;
background: #27ae60;
border: solid 1px #2ecc71;
border-radius: 50px;
z-index: 1;
bottom: 1em;
width: 80%;
left: 50%;
margin-left: -43%;
padding: 2% 3%;
text-align: center;
}
<div>
<img src="https://placehold.it/400x200">
<span>This is an image of a gray rectangle!</span>
</div>
<div>
<img src="https://placehold.it/200x200">
<span>This is an image of a gray square!</span>
</div>
<div>
<img src="https://placekitten.com/g/400/200">
<span>This is an image of a cute kitten inside a rectangle!</span>
</div>
<div>
<img src="https://placekitten.com/g/200/200">
<span>This is an image of even cuter kitten inside a square!</span>
</div>
So the issue is that you are trying to set your handler on a dynamic selector ("img#"+j) but this will not work. For one thing, that equation will be evaluated only once, on page load, when j is undefined.
So you want to do this instead:
target only img tags for your mouse over... Better yet, give your special images all the same css class so you can attach the event handlers only to those. That will be more efficient.
When an image is moused over or out of, grab it's id attribute, extract the number from it, then use that to build a selector for the appropriate span to show.
var get_span_from_image = function(image) {
var image_id = image.attr("id");
var matches = image_id.match(/theImg(\d+)/);
if(matches) return $("theSpan" + matches[1]);
return $(); // nothing found, return an empty jQuery selection
};
$("img").hover(
function() { // mouse over
get_span_from_image($(this)).show();
},
function() { // mouse out
get_span_from_image($(this)).hide();
}
);
Note: There are better ways to "link" two nodes together, but this is just to answer your question with the current structure you have.
UPDATE: Some ideas to link two nodes together
So instead of trying to extract a number from an id attribute, a better way would be to tell either one of the image or span about it's sibling. You could output your html like this, for instance:
<img id="theImg1" data-target="theSpan1" class="hoverable" src="..."/>
....
<span id="theSpan1">...</span>
Of course now your ideas could be anything - you don't have to use numbered values or anything.
Then your hover code becomes quite simply:
var get_span_from_image = function(image) {
var span_id = image.data("target");
return $("#" + span_id);
};
$("img").hover(
function() { // mouse over
get_span_from_image($(this)).show();
},
function() { // mouse out
get_span_from_image($(this)).hide();
}
);
Hope this helps!
I'm trying to write a code that toggles the opacity of a div but I'm running into trouble with it. If I click this button, I want it to set the opacity of #infodiv to 1.0, where it's set at 0.0 right now, like so.
#infodiv{
width: 250px;
height: 0px;
margin-top: 10%;
opacity: 0.0;
}
This is the function that I'm trying to call.
function toggles(){
infodiv.css('opacity', '1.0');
}
It's probably the function that it's need of some tweaking, maybe? Thanks to anyone willing to take a look to help out. Here's a fiddle
You must set style of element with jQuery:
function toggles() {
$('#infodiv').css('opacity', '1.0');
}
If you use pure javascript, your function will be look like that
function toggles(){
document.getElementById('infodiv').style.opacity = '1.0';
}
Use Element.classList
var infodiv = document.querySelector("#infodiv");
function clickToggle(){
this.classList.toggle("active")
}
infodiv.addEventListener("click",clickToggle, false);
#infodiv{
width: 250px;
height: 250px;
background: red;
opacity: 1;
}
#infodiv.active{opacity: 0}
<div id=infodiv></div>
The simplest way to toggle whether something is displayed in jQuery is with .toggle()
$('#infodiv').click(function(){
$(this).toggle();
})
if you need to change opacity then try toggleClass() and create a new CSS class that has opacity 1
// CSS
.opaque{
opacity: 1;
}
// jQuery
$('#infodiv').click(function(){
$(this).toggleClass('opaque');
})
$(function() {
$('#btn').click(function() {
$('#infodiv').toggleClass('active');
});
});
#infodiv {
width: 250px;
margin-top: 10%;
opacity: 0.0;
}
#infodiv.active {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="infodiv">
<div class="infotext">This is a test.</div>
</div>
<button type="button" id="btn">btn</button>
You need to use with ID selector which returns a jQuery object as the method .css() is a jQuery function
function toggles() {
$('#infodiv').css('opacity', '1.0');
}
DEMO
However I would recommend you to create a CSS class like
.higheropacity {
opacity: 1.0 !important
}
Then use .toggleClass() method
function toggles() {
$('#infodiv').toggleClass('higheropacity');
}
DEMO
Well, besides the jQuery one, you can always do something like
function toggles() {
document.getElementById('infodiv').style.opacity = 1;
}
if you feel like using pure javascript.
Does it have to be a function?
Why not use:
$('#infodiv').toggle();
From the api - "The .toggle() method animates the width, height, and opacity of the matched elements simultaneously."