I want to dynamically create divs, append them to the body and set a jQuery animation.
This is where the elements are created:
function drawSpot()
{
var myH1 = document.createElement("div");
myH1.style.position = "absolute";
myH1.style.top = GetRandom(0,100)+"%";
myH1.style.left = GetRandom(0,100)+"%";
myH1.style.width="40px";
myH1.style.height="40px";
$("body").append(myH1);
}
And from the time on they are appended to the body, I want to start the animation.
If you already using jQuery, you should do it all the way:
$('<div>', {
css: {
position: 'absolute',
top: GetRandom(0,100)+'%',
left: GetRandom(0,100)+'%',
width: '40px',
height: '40px'
}
}).appendTo( document.body ).animate({
left: '100%' // for instance
}, 2000);
By using .appendTo() you still have a reference to your original object and be able to chain methods on it.
Ref.: jQuery constructor, .appendTo(), .animate()
demo: http://jsfiddle.net/dkuVu/
Use jQuery for creation of elements, and animate it when appending:
function drawSpot() {
var myH1 = $("<div>").css({ position: "absolute",
top: GetRandom(0,100)+"%",
left: GetRandom(0,100)+"%",
width: 40,
height: 40 });
$("body").append(myH1.animate(...));
}
http://jsfiddle.net/nagCf/
That should work
function drawSpot()
{
var myH1 = '<div id="newDiv">Some Text</div>';
$("body").append(myH1);
$("#newDiv").css({'position' : 'absolute',
'top' : GetRandom(0,100)+"%",
'left' :GetRandom(0,100)+"%",
'width':'40px',
'height':'40px'
});
$("#newDiv").hide().fadeIn(500);
}
You can use : $(myH1).animate({left:'*randomvalue*', top:'*randomvalue*'},1000); after the append.
http://jsfiddle.net/Wumrr/2/
Related
I know we can use .style to apply css to DOM element like this:
document.getElementById("test").style.color="red";
I am wondering, if it is possible to apply a style object, something like this:
newStyle: {
position : 'fixed';
width : '300px';
height : '20px';
top : '0';
}
how to apply newStyle by using .style, is it possible? ( We are not using jQuery here)
You can use Object.assign:
Object.assign(myElement.style, {
width: '300px',
height: '20px'
});
Object.assign(document.getElementById("test").style, {
position: 'fixed',
width: '300px',
height: '100px',
top: '0'
});
<div id="test" style="background: green"></div>
you can loop through properties of styles as -
var newStyle = {
position : 'fixed',
width : '300px',
height : '20px',
top : '0'
};
for (i in newStyle)
document.getElementById("test").style[i] = newStyle[i];
Applying rule by rule is bad. It makes the browser re-render multiple times. You can apply all the changes in one shot - by using cssText
So, in your case, you need to convert the object into a string and then apply all the styles in one shot:
var newStyle = {
position: 'fixed',
width: '300px',
height: '20px',
top: '0'
}
var styles = [];
for(var rule in newStyle) styles.push(rule+': '+newStyle[rule]);
document.getElementById("test").style.cssText = styles.join(';');
Try this:
var mystyle = {
color: 'red'
};
for (var property in mystyle) {
if (mystyle.hasOwnProperty(property)) {
document.getElementById("updateStyle").style[property] = mystyle[property];
}
}
<p id="updateStyle">Hi This is demo text.</p>
replace updateStylewith your own id
You can extend the prototype of the "HTMLElement". Add a method to loop through a object containing the style information. You can do it like this:
HTMLElement.prototype.applyStyleObject = function (styleObject) {
for (var item in this.style) {
var objProp = styleObject[item];
if (objProp !== undefined) {
this.style[item] = objProp;
}
}
}
I've done a first prototype as an example how to use this in the wild :):
//The object containing the style elements
var obj = {
width: "200px",
height: "100px"
}
var spanobj = {
color: "red"
}
//Cached the div node
var divNode = document.getElementById("div");
//Extend the HTMLElement prototype
HTMLElement.prototype.applyStyleObject = function (styleObject) {
for (var item in this.style) {
var objProp = styleObject[item];
if (objProp !== undefined) {
this.style[item] = objProp;
}
}
}
//Execute the new method
divNode.applyStyleObject(obj);
document.getElementById("span").applyStyleObject(spanobj);
document.getElementsByTagName("figure")[0].applyStyleObject(obj);
div {
border: solid 1px black;
}
figure {
border: solid 1px black;
}
<div id="div"></div>
<span id="span">This is a span tag</span>
<figure></figure>
If you've extended the prototype of an javascript object, it applies to all newly created instances of that kind of object.
I want to detect clicks and move elements from off-screen right to off-screen left with jquery.
I achieved the general idea already (fiddle) but only for one div, once.
HTML:
<div class = "outer">
<div id = "box">
</div>
</div>
CSS:
body {
overflow-x: hidden;
height: 500px;
}
#box{
height: 100px;
width: 100px;
background: #FF00FF;
position: absolute;
right: -100px;
}
JS:
$(document).ready(function(){
$(document).click(function(){
var bodyHeight = document.body.clientHeight;
var randPosY = Math.floor((Math.random()*bodyHeight));
$('#box').css('top', randPosY);
$("#box").animate({left: '-100px'}, 5000);
});
});
How can make a new instance div appear (at random y-position) per click on the document?
My random y-position is calculated in jQuery the following way, but gets its value from my css height: 500px; - how can I make this value responsive?
Use a function constructor to add object instances of a div, where each one uses .box class instead of #box:
fiddle
function SlidingDiv(bodyHeight){
this.randPosY = Math.floor((Math.random()*bodyHeight));
this.$div = $("<div>").addClass('box').appendTo('.outer');
};
SlidingDiv.prototype.slide = function(){
this.$div.css('top', this.randPosY);
this.$div.animate({left: '-100px'}, 5000);
};
$(document).ready(function(){
$(document).click(function(){
var bodyHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var div = new SlidingDiv(bodyHeight);
div.slide();
});
});
Edit: To remove divs, you could try the complete function:
SlidingDiv.prototype.slide = function() {
this.$div.css('top', this.randPosY);
this.$div.animate({
left: '-100px',
duration: 5000,
complete: function() { this.$div.remove(); }.bind(this)
});
};
I am relatively new to all this so if you see anything I am doing wrong, or anyways to simplify any code please do not hesitate to say.
I have the following code to enlarge the div element:
var profilePostsClick = function () {
$('.largeBox, .smallBox, .longBox').click(function () {
$(this).animate({
width: '100%',
height: '40%'
}, 200);
$('.closePost', this).removeClass('closePostHide');
});
};
$(document).ready(profilePostsClick);
https://jsfiddle.net/jvkhmpbt/
I am wanting to close each div when the cross is clicked, returning it to it's original size and positioning (with height: auto if feasible).
Aslo is there a way to make it so each div opens above the smaller ones? (like the top left div does, i am aware this is because of it's positioning)
Thanks
You can do like following way by adding and removing class
JQuery:
$('.largeBox, .smallBox, .longBox').click(function (e) {
e.preventDefault();
$(this).addClass('increaseSize');
$('.closePost', this).removeClass('closePostHide');
});
$('.glyphicon-remove').click(function (e) {
e.stopPropagation()
$('.glyphicon-remove').parent().parent().removeClass('increaseSize');
$('.closePost', this).addClass('closePostHide');
});
CSS:
.increaseSize{
width: 100%;
height: 40%;
}
Check Fiddle Here.
You could save the animation properties/values in an cache-object and restore them after your animation.
http://jsfiddle.net/jvkhmpbt/4/
var animationResetCache = [];
var saveValues = function (node) {
animationResetCache.push({
node: node,
width: node.css('width'),
height: node.css('height')
});
};
var restoreValues = function (node) {
for (var i = 0; i < animationResetCache.length; ++i) {
var item = animationResetCache[i];
if (item.node.is(node)) {
return item;
}
}
};
var profilePostsClick = function () {
$('.largeBox, .smallBox, .longBox').click(function (e) {
var $this = $(this);
if ($this.hasClass('open')) return;
saveValues($this);
$this.addClass('open').animate({
width: '100%',
height: '40%'
}, 200);
$this.find('.closePost').removeClass('closePostHide');
});
$('.closePost').click(function () {
var $parent = $(this).parent('.largeBox, .smallBox, .longBox');
if ($parent.hasClass('open')) {
var cachedValues = restoreValues($parent);
$parent.animate({
width: cachedValues.width,
height: cachedValues.height
}, function () {
$parent.removeClass('open');
});
$parent.find('.closePost').addClass('closePostHide');
}
});
};
$(document).ready(profilePostsClick);
I think it's easier to use a toggle and do the animation in CSS3
$("img").click(function(){
$(this).toggleClass('expanded');
});
I would suggest to add one more identical class to each of smallBox,largeBox and longBox which will be called parentd to identify parent div and animate it back and add below js:
DEMO
$('.closePost').on('click',function(e)
{
$(this).closest('.parentd')
.animate({
width: '40%',
height: 'auto'
},200).removeAttr('style');
$(this).addClass('closePostHide');
e.stopPropagation();
});
If we continue on Rover his answer, we can use the switchClass function in jQuery Ui. (source)
This function let's you switch the classes of an object, creating an animation in the difference between those classes.
Example code: jsFiddle
<div class="large"></div>
CSS:
.large{
width: 100%;
height: 200px;
background-color: red;
}
.small {
width: 10%;
height: 50px;
background-color:green;
}
JS:
$("div").switchClass("large","small",500);
Below is a JS fiddle that I have been using to implement a tooltip on my website.
JSFiddle
However when I implement this on my website, the title attribute value appears on rollover (like an alt attribute) as well as the tooltip. I need it not to do this! The actual code from my website is below.
Javascript
$(function(){
$("ul.thumb li").hover(function() {
$(this)
.css('z-index', '10')
.find('img').addClass("hover")
.stop()
.animate({
marginTop: '-150px',
marginLeft: '-150px',
top: '50%',
left: '50%',
width: '300px',
height: '300px',
padding: '20px'
}, 200, function() {
var $this = $(this),
h = $this.height();
$caption = $('<div class="caption">' + this.title + '</div>')
.css('top', h.toString() + 'px');
$this.after($caption);
});
}, function() {
$('.caption').remove();
$(this)
.css('z-index', '0')
.find('img').removeClass("hover")
.stop()
.animate({
marginTop: '0',
marginLeft: '0',
top: '0',
left: '0',
width: '200px',
height: '200px',
padding: '5px'
}, 400);
});
});
HTML
<ul class="thumb">
<li> <img src="slide1image.png" width="200" height="229" title="come join us and have lots of fun with our clowns, tigers and magician" /></li>
Do not use the title attribute then.
Use data-title as the attribute name and access it with the $this.data('title')
Demo at http://jsfiddle.net/gaby/62NT7/1/
Since the essence of what you want to do is to prevent the default behavior of hovering over an image, the following should take care of it:
$('img').on('hover', function( e ) {
e.preventDefault();
});
WORKING JSFIDDLE DEMO
Other ways of resolving this include:
- removing the attribute: $('img').removeAttr('title')
- saving the value to a data attribute and removing it: $('img').data('title', function() { return this.title; }).removeAttr('title');
- editing your markup so that you use a data attribute instead of title attribute - as #GabyakaG.Petrioli's answer.
$(".fader").click(function (e) {
$('.fader').not('#' + $(this).attr("id")).fadeOut(function() {
$($(this).attr("id")).animate({width: "200",height: "200px", top: "-=-440px", left: "-=-367px"});
});
});
fading out works, animate() works too but with different elements.
Is it the syntax to blame or my CSS that is blocking animate()?
You do not need to do $($(this).attr("id")) as $(this) is fine.
Also, the inner jQuery selector changes the meaning of 'this' to be different. If you want it to stay the same, you need to keep a reference to it first e.g.
$(".fader").click(function (e) {
var self = this;
$('.fader').not(self).fadeOut(function() {
$(self).animate({width: "200",height: "200px", top: "-=440px", left: "-=367px"});
});
});