function Main(BombPosTopr, BompPosLeftr){
if (CheckRight == false){
//$("#Main").prepend('<div class="Effect" style="absolute; top:' + BombPosTopr + 'px; left: '+ BombPosLeftr +'px;"></div>');
ArrayEffects.push(new EffectVoorBom(BombPosTopr,BombPosLeftr));
BombPosLeftr += 30;
}
};
this.explosionTime2 = setTimeout( function(){
**self2.removeEffect();**
}
}
function EffectBom(BombPosTopr, BompPosLeftr){
var self2 = this;
this.el = $('<div/>');
this.el.addClass('Effect');
this.el.css({position : 'absolute', top : BombPosTopr + 'px', left : BompPosLeftr+'px'});
$("#Main").prepend(this.el);
self2.removeEffect = function(){
**self2.el.remove();**
}
I have 2 functions and in my main I need to add Effects, so I put them in an array and use the object EffectBom.
Now the big problem is that I need to use self2.removeEffect() in my other function but it can't find it!
Thnx for reading - helping!
You need to change the scope of the variable. Add
var self2;
to the top of the file and change
var self2 = this;
to be
self2 = this;
Related
I'm kinda newbie in JS objects, but I'd like to learn correct ways of doing things.
I'm writing a Class and it is mostly based on element that is passed to constructor. I want this element to have an event that updates the object.
I made it so it happens, but this just feels "hacky".
function SomeClass(element) {
this.element = element;
this.mouseX = 0;
this.mouseY = 0;
this.setMousePosition = function(posX, posY) {
this.mouseX = posX;
this.mouseY = posY;
};
this.listenMousePosition = function() {
var obj = this;
$(this.element).on('mousemove',null, {obj: obj}, function(e, obj) {
e.data.obj.setMousePosition(e.offsetX, e.offsetY);
$('#output').html('X: ' + e.data.obj.mouseX + '; Y: ' + e.data.obj.mouseY);
})
}
this.listenMousePosition();
return this;
}
window.contentDiv = new SomeClass($(".content")[0]);
Is there a better way of doing this or is this the way to roll?
As I checked - I can't just pass it to function as you see in link: https://jsfiddle.net/nooorz24/v6f1jydm/7/
At least a couple ways you could do this. The issue here is that when you get inside the function this changes from referencing the class instance to the method.
Reference another variable
By using an external variable, we don't care if this changes.
var self = this;
this.listenMousePosition = function() {
$(self.element).on('mousemove', function(e) {
self.setMousePosition(e.offsetX, e.offsetY);
$('#output').html('X: ' + self.mouseX + '; Y: ' + self.mouseY);
});
};
Use an arrow function
Arrow functions do not change what this references.
this.listenMousePosition = () => {
$(this.element).on('mousemove', e => {
this.setMousePosition(e.offsetX, e.offsetY);
$('#output').html('X: ' + this.mouseX + '; Y: ' + this.mouseY);
});
};
Take note though that arrow functions do not work in IE versions prior to Edge.
I am trying to figure out a way on how to store data in some kind of list or array in javascript. I have three variables called id, left and top. All are in the function
id: index of an element that is passed to the function as parameter.
left: calculated within the function
top: calculated within the function
What I am looking for is each time I call the function with different id, the function should be able to calculate and store left and top and in some way store id,left and top so that I can access them in another function call.
Or can I use objects to use the values?
function:
function getCoordinates(id) {
scroll_value_Y = document.getElementById("svg_editor").scrollTop;
scroll_value_X = document.getElementById("svg_editor").scrollLeft;
offset_x = 298;
offset_y = 102;
var p = $('#' + id);
var offset = p.offset();
var left = Math.round(offset.left - offset_x + scroll_value_X);
var top = offset.top - offset_y + scroll_value_Y;
//something to store
}
use in another function call :
drawAggregate(getCoordinates(a1).left, getCoordinates(a1).top, getCoordinates(a2).left, getCoordinates(a2).top);
Or something like that. How can I implement this?
Yeah, just return an Object.
function getCoordinates(id) {
scroll_value_Y = document.getElementById("svg_editor").scrollTop;
scroll_value_X = document.getElementById("svg_editor").scrollLeft;
offset_x = 298;
offset_y = 102;
var p = $('#' + id);
var offset = p.offset();
var left = Math.round(offset.left - offset_x + scroll_value_X);
var top = offset.top - offset_y + scroll_value_Y;
// Here we create and return an object with two keys: left and top
return {
top: top,
left: left
}
}
And, in order to avoid computing the values twice, you could store the values in other objects a1Coords and a2Coords:
var a1Coords = getCoordinates(a1);
var a2Coords = getCoordinates(a2);
drawAggregate(a1Coords.left, a1Coords.top, a2Coords.left, a2Coords.top);
I assume that your coordinates change every time, so you don't actually want to store coordinates inside the getCoordinates function but only compute and return them.
Shure you can use objects.
You can just pass object into function, like this:
(function(){
function incId(data){
var id = data.id;
data.id = id++;
}
function checkId(data){
console.log(data.id);
}
var data = {id:0};
incId(data);
checkId(data);
}());
You can return an object:
function getCoordinates(id)
{
var scroll_value_Y = document.getElementById("svg_editor").scrollTop;
var scroll_value_X = document.getElementById("svg_editor").scrollLeft;
var offset_x = 298;
var offset_y = 102;
var p = $('#' + id);
var offset = p.offset();
return {
left: Math.round(offset.left - offset_x + scroll_value_X),
top : offset.top - offset_y + scroll_value_Y
};
}
var coords1 = getCoordinates(a1);
var coords2 = getCoordinates(a2);
drawAggregate(coords1.left, coords1.top, coords2.left, coords2.top);
here i am posting a jquery code which is working but few lines are not clear to me .
js fiddle link.
full code
HTML:
<form method="post" action="WebForm1.aspx" id="ctl00">
<input type="submit" name="Button1" value="Fly DIV" id="Button1" class="toggleUPSContainer" />
</form>
CSS:
#UPSContainer{
position: absolute;
display: none;
background:red;
height:0;
width:0;
}
javascript:
$(document).ready(function () {
var $els = [];
var data = {
"UPSContainer": {
"height" : 100,
"width" : 100
},
"isAnimating" : false
};
$els.window = $(window);
$els.form = $('#ctl00');
$els.toggleUPSButtons = $('.toggleUPSContainer');
function addUPSOverlay(){
$els.form.append('<div id="UPSContainer"></div>');
$els.UPSContainer = $('#UPSContainer');
}
function getNewWindowCorner(){
data.windowWidth = parseInt($els.window.width());
data.windowHeight = parseInt($els.window.height());
if($els.UPSContainer.is(':hidden')){
$els.UPSContainer.css({
top: data.windowHeight + 'px',
left: data.windowWidth + 'px'
});
}else{
$els.UPSContainer.css({
left: ((data.windowWidth - data.UPSContainer.width) / 2) + 'px',
top: ((data.windowHeight - data.UPSContainer.height) / 2) + 'px'
});
}
}
function containerOpenComplete(){
// do what you want here when opening complete
}
function containerCloseComplete(){
// do what you want here when closing complete
}
function toggleUPSOverlay(e){
e.preventDefault();
if(!data.isAnimating){
if($els.UPSContainer.is(':hidden')){ // currently closed so open
$els.UPSContainer.show();
$els.UPSContainer.animate({
left: ((data.windowWidth - data.UPSContainer.width) / 2) + 'px',
top: ((data.windowHeight - data.UPSContainer.height) / 2) + 'px',
height: data.UPSContainer.height + 'px',
width: data.UPSContainer.width + 'px'
}, 200, function(){
containerOpenComplete();
});
}else{ // currently open so close
$els.UPSContainer.animate({
left: data.windowWidth + 'px',
top: data.windowHeight + 'px',
height: 0 + 'px',
width: 0 + 'px'
}, 200,
function () {
$els.UPSContainer.hide();
containerCloseComplete();
});
}
}
}
function attachEvents(){
$els.window.on('resize', getNewWindowCorner);
$els.toggleUPSButtons.on('click', toggleUPSOverlay);
}
function initialize(){
addUPSOverlay();
getNewWindowCorner();
attachEvents();
}
initialize();
});
this function's code is not clear
function getNewWindowCorner(){
data.windowWidth = parseInt($els.window.width());
data.windowHeight = parseInt($els.window.height());
}
just see windowWidth & windowHeight potion
var data = {
"UPSContainer": {
"height" : 100,
"width" : 100
},
"isAnimating" : false
};
data has been declared as object and it has property like height, width & isAnimating etc but how we can add two new property called windowWidth & windowHeight to data object ??
just seeing the below code it seems that we can add any property to any object with any name at runtime in javascript and here we are storing value to windowWidth & windowHeight property.
data.windowWidth = parseInt($els.window.width());
data.windowHeight = parseInt($els.window.height());
so just see my whole code and tell me from where these two property comes windowWidth & windowHeight ? thanks
EDIT 1
Need bit more help. what it is called in js var $els = [];? is it array or object? what is the difference between var $els = []; and var els = {}; ? if this is array var $els = []; then how one can push anything into array like this way $els.window = $(window); or $els.body = $('body');. please help me understand the usage with small sample. thanks
For normal ones you can add them on the fly. They don't have to be declared from the start with the object. If they are they'll only be overwritten.
So you could either add everything you want from the start...
var data = {
"UPSContainer": {
"height": 100,
"width": 100
},
"isAnimating": false
};
.. or create it as you go
var data = {};
data.UPSContainer = {};
data.UPSContainer.height = 100;
data.UPSContainer.width = 100;
data.isAnimating = false;
data.windowWidth = parseInt($els.window.width());
data.windowHeight = parseInt($els.window.height());
it seems that we can add any property to any object with any name at runtime in javascript
Yes. You can. You just assign the new values.
where these two property comes windowWidth & windowHeight
From the code you are asking about. The assignment creates those properties.
In ECMAscript3 and ECMAScript5 , any property can be added to any object,
either by dot assignment, or through an array type notation.
data.windowWidth = parseInt($els.window.width());
or
data['windowWidth'] = parseInt($els.window.width());
create 'windowWidth' property for the data object.
In ECMA5 , this behaviour can be altered by following function:
Object.preventExtensions( obj )
and you can use Object.isExtensible( obj ) to check the current behaviour of that object.
If you try adding property to such an object for which extensions have been prevented, you would get an error in strict mode.
For your second question, in javascript array is also an object having properties , date is also an object , hence you can add properties to the array.
How can I achieve this? Firstly the code...
function flutter() {
var random = Math.floor(Math.random()*5);
var $obj = $('.bird');
$obj.animate({ top :'-=' + random + 'px' }, 20, flutter);
}
</script>
In the code above, when the callback is executed, I want to reverse the value of random. My goal is thus to move the Class bird up and down and try to see if it create fluttering effect.
You can use some closure like this:
$obj.animate({ top :'-=' + random + 'px' }, 20, function(){
flutter(random*-1);
});
And this is the full code:
function flutter(offset) {
var random = ( isNaN(offset) ) ? Math.floor(Math.random()*5) : (offset) ;
var $obj = $('.bird');
$obj.animate({ top :'-=' + random + 'px' }, 20, function(){
flutter(random*-1);
});
}
And first call will be simple: flutter();
I just tweaked flutter above to make it more efficient and convenient.
function flutter(distance, target) {
// you can call flutter without argument. And no repetitive element finding is needed
var random = distance || Math.floor(Math.random()*5);
var $obj = target || $('.bird');
$obj.animate({ top :'-=' + random + 'px' }, 20, function(){
flutter(-random, $obj);
});
}
I have this function for adding a new item to the beginning of the list and removing the last one:
function addItem(id, text){
var el = $('#' + id);
var w = el.width();
el.css({
width: w,
overflow: 'hidden'
});
var ulPaddingLeft = parseInt(el.css('padding-left'));
var ulPaddingRight = parseInt(el.css('padding-right'));
el.prepend('<li>' + text + '</li>');
var first = $('li:first', el);
var last = $('li:last', el);
var fow = first.outerWidth();
var widthDiff = fow - last.outerWidth();
var oldMarginLeft = first.css('margin-Left');
first.css({
marginLeft: 0 - fow,
position: 'relative',
left: 0 - ulPaddingLeft
});
last.css('position', 'relative');
el.animate({ width: w + widthDiff }, 1500);
first.animate({ left: 0 }, 250, function() {
first.animate({ marginLeft: oldMarginLeft }, 1000, function() {
last.animate({ left: ulPaddingRight }, 250, function() {
last.remove();
el.css({
width: 'auto',
overflow: 'visible'
});
});
});
});
}
How can I make it work the other way around ? I want to add the item to the end and remove the first and also make it slide the other way around, like right to left.
Take a look at jQuery.append (and jQuery.prepend for beginning of list)
Your code seems really complicated. Simplifying it a little bit might give you something like this:
$("#whateverList").addItem("awesome")
jQuery.fn.addItem = function(text) {
var $li = $("<li>").text(text)
$(this).find("li:first").remove()
$(this).append($li)
}
jQuery plugin syntax is super easy to understand
append() to go to the bottom
var declarations at the top
Good luck!