I have a div that I append with the following code:
function generateBall(){
var colors = ["fe0ba5", "00c0ff", "21f1a5", "f13e21", "e819fb", "3ae319", "ff9900", "512e5e", "284184"];
var width = $('.reaction_area').width() - 40;
var height = $('.reaction_area').height() - 40;
var a = Math.floor(Math.random()*(width - 40 + 1) + 40);
var b = Math.floor(Math.random()*(height - 40 + 1) + 40);
var size = Math.floor(Math.random()*(32 - 24 + 1) + 24);
var color = colors[Math.floor(Math.random() * colors.length)];
$('.reaction_area').append('<div class="ball_2" style="left: '+a+'px; top: '+b+'px; height: '+size+'px; width: '+size+'px; background: #'+color+'" data-id="'+wave+'"></div>');
}
And then I have this:
$('.ball_2').on('click', function(){
$(this).remove();
wave--;
});
And it's not working. I have other elements that I append like that and clicking them works, why this doesn't?
I've tried also with $('document').on('click', '.ball_2', function(){ //code }); and it didn't work either.
That would be $(document) (without the quotes).
$('.ball_2').on('click', ...) doesn't work because the element .ball_2 doesn't exist yet at the time of execution. However, $(document).on('click', '.ball_2', ...) works because it puts the handler on an ancestor element and takes advantage of a phenomenon called "event bubbling". In simple terms, an ancestor is considered clicked when a descendant is clicked.
Since element with class ball_2 is generated dynamically.
$(document).on('click','.ball_2', function(){
$(this).remove();
wave--;
});
add following line in generateBall() function. Because the div is created dynamically, so we should bind the function when it being create. And this statement can let every '.ball_2' got it own remove function, assume there may be more than one '.ball_2'.
$('.ball_2:last').on('click', function(){$(this).remove());});
use delegate :
$('.reaction_area').delegate('.ball_2', 'click', function (event) {
$(this).remove();
wave--;
});
Related
I've got a JS function that edits fill inputs' values.
I'm fetching the input's value by an ID that is the parameter of the function and the functions is called on click.
My problem is that when I click to edit the first input, it works, but then I want to edit the third one.. it edits the first and the third one?
How can I reset my functions to only edit the third ?
Here's my JS function
function editTicket(id) {
let toEdit = id;
document.getElementById("inputRow" + toEdit).style.backgroundColor = "#6C63FF";
document.getElementById("inputRow" + toEdit).style.color = "#fff";
$("#imgtoCenter").click(function (e) {
var offset = $("#imgtoCenter").offset();
var relativeX = (e.pageX - offset.left);
var relativeY = (e.pageY - offset.top);
sessionStorage.removeItem('x' + toEdit);
sessionStorage.removeItem('y' + toEdit);
document.getElementById("inputRow" + toEdit).style.backgroundColor = "#fff";
document.getElementById("inputRow" + toEdit).style.color = "#000";
sessionStorage.setItem('x' + toEdit, Math.round(relativeX));
sessionStorage.setItem('y' + toEdit, Math.round(relativeY));
document.getElementById("x" + toEdit).value = sessionStorage.getItem('x' + toEdit);
document.getElementById("y" + toEdit).value = sessionStorage.getItem('y' + toEdit);
});
}
If I console.log(id), I've got the value of my last click and the new one.
Thanks.. !
From jQuery click documentation
Additional Notes:
As the .click() method is just a shorthand for .on( "click", handler ), detaching >is possible using .off( "click" ).
Each time you're calling editTicket method, you're attaching a click event on #imgtoCenter element. All theses click events accumulate on the element, and when you're clicking on #imgtoCenter, all the handlers are fired with the previous ids they kept.
Just $("#imgtoCenter").off('click') at the end of editTicket method.
here is a problem i am facing in my progressbar. i have data-percent attribute in my "pro-bar" class . each data-percent is different but when in browser i'am getting first pro-bar's data-percent value applied to all
Here is my code:
$('.pro-bar').each(function( i, elem ){
var percent = $('.pro-bar').attr('data-percent'),
barparcent = Math.round(percent*5.56),
$elem = $(this);
console.log(percent);
$elem.animate({'width':barparcent}, 2000, 'easeInOutExpo');
});
Your problem is how you are referring to your pro-bar inside the each. Use "this" to refer to the current element, not a general class selector.
$('.pro-bar').each(function( i, elem ){
var percent = $(this).attr('data-percent'),//change here
barparcent = Math.round(percent*5.56),
$elem = $(this);
console.log(percent);
$elem.animate({'width':barparcent}, 2000, 'easeInOutExpo');
});
Further explanation:
$(".pro-bar").attr("data-percent") gets all of the .pro-bar, then .attr("data-percent") gets the value of the first element (as does most other similar jquery methods). Then as you loop through each element, this same effect is called multiple times.
I am trying to move a div -200px from his original position when I press a button. Now I want to be able to do this multiple times.
function leftAnimate(){
original = document.getElementById("sliderzelf").setAttribute("style", "margin-left: -200px;");
}
This piece of code ( I assume, correct me if Im wrong.) really sets the attribute ONCE to -200px. Is there any way I can make this do -200px from every new starting position?
Since you have used the jquery-animate tag, I shall presume you have jQuery. In which case the following should work:
function leftAnimate() {
$("#sliderzelf").css("margin-left", "-=200");
}
call this function however you like, add a css transition on the element if you want it to slide or whatever. happy coding!
function leftAnimate(){
var el = document.getElementById("section");
var curMargin = window.getComputedStyle(el)['margin-left'].replace('px', '');
var newPos = Number(curMargin - 200);
original = el.setAttribute("style", "margin-left:" + newPos + "px;");
}
if you element is an absolute element, try use the Left instead margin-left, or
You can try with jQuery:
function leftAnimate(){
var actualPosition = $("#sliderzelf").css("left");
original = document.getElementById("sliderzelf").setAttribute("style", "margin-left: " + (actualPosition - 200).toString() + "px;");
}
Using pure javascript:
function leftAnimate(){
//get the button
var btn = document.getElementById("sliderzelf");
//get the current margin
var currentMargin = btn.style.marginLeft.replace("px", "");
//calculate the new margin
var newMargin = currentMargin - 200;
//check if the new margin is valid (optional)
if (newMargin >= 0)
btn.setAttribute("style", "margin-left: " + newMargin + "px;") //set the new margin
}
<button id="sliderzelf" style="margin-left: 600px" onclick="leftAnimate()">
Click me!
</button>
With jquery just change the function to:
$("#sliderzelf").css('margin-left', '-= 200');
i have one question regarding creation of divs:
I have button, when user clicks on it, javascript (or jquery) needs to create a div. But when user clicks again, it should create another div, but with different id. So, every time user clicks should be created div with different id.
I partialy know how to create div, but i have no idea how to make divs with different id's.
var c = 0; // Counter
$('#add').on('click', function() {
c += 1;
$('#parent').append('<div id="child'+ c +'">'+ c +'</div>');
});
#child1{color:red;}
#child2{color:blue;}
#child3{color:orange;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add">ADD</button>
<div id="parent"></div>
var divcount = 1;
$('button').click(function(){
$('<div/>', { id:'comment'+divcount++ })
});
Here's a random ID generator for you.
function createParanoidID() {
return 'id_' + Math.floor(Math.random() * 9e99).toString(36);
}
createParanoidID(); // id_1js7ogi93ixt6x29w9svozegzhal67opdt3l3cf1iqidvgazlyaeh1ha7a74bswsg
createParanoidID(); // id_1fleq6chguuyyljhy39x3g7mg661mg845oj8fphnxgvm0bdgz7t3w0q01jptogvls
createParanoidID(); // id_ajz1ft17ml4eyz08gd3thcvq3fx1ycr927i0h2zgyw8bzq9wurv1gdfogly8tbls
Using a variable as counter and the "attr" function to set the id attribute.
HTML
<button id="button">Create Div</button>
<div class="container"></div>
jQuery:
$('#button').on('click', function() {
var count = $('div.container div').length,
id = count + Math.floor(Math.random() * 100);
$('div.container').append('<div id="'+ id+'">ID of this div is: '+ id +' </div>');
});
DEMO
Here's the easy way to do this.
Firstly, you'll need a button:
<button id="onClickOfThisButtonAnewDivWithArandomIDwillBeInserted"></button>
Then the javascript:
$("#onClickOfThisButtonAnewDivWithArandomIDwillBeInserted").on('click', function() {
var myID = 'randomIDnumber_'+Math.random()+Math.random()+Math.random()+Math.random()+Math.random()+Math.random();
var MyNewElement = document.createElement('div');
MyNewElement.id = myID.replace(/\./g, '');
$(MyNewElement).appendTo('body');
});
Here's a FIDDLE
If you don't want to use global counter like in previous answers you can always get number of children and use that as relative value from which you will create another id.
Something like this (with jQuery):
function add_another_div() {
var wrap_div = document.getElementById("#id_of_div_who_contain_all_childrens");
var already_childs = $("#id_of_div_who_contain_all_childrens").children().length;
var div = document.createElement('div');
var divIdName = 'new_div-'+ (already_childs+1);
div.setAttribute('id', divIdName);
wrap_div.appendChild(div);
}
Of course, this requires for all of your children to have same parent (same wrapper). If that is not the case, and they are separated across multiple wrappers, then just use unique class name for all of them, and count them like that. I found this approach much better and easier instead of using global counters which I need to take care about.
So I need to add tooltips for some input fields and textareas. Currently, I have it setup like this:
$(document).ready(function(){
$('input').focus(function(){
var p = $(this);
var position = p.position();
var input_name = $(this).attr('id');
var name = '#'+input_name+'_help';
$('#apply_tooltip').css("left", position.left - 310 );
$('#apply_tooltip').css("top", position.top -15 );
$(name).show();
$('#apply_tooltip').show();
});
$('input').blur(function(){
$('.tooltip_inner').hide();
$('#apply_tooltip').hide();
});
$('textarea').focus(function(){
var p = $(this);
var position = p.position();
var input_name = $(this).attr('id');
var name = '#'+input_name+'_help';
$('#apply_tooltip').css("left", position.left - 310 );
$('#apply_tooltip').css("top", position.top -15 );
$(name).show();
$('#apply_tooltip').show();
});
$('textarea').blur(function(){
$('.tooltip_inner').hide();
$('#apply_tooltip').hide();
});
});
This works, but obviously there is probably a more efficient solution than simply duplicating the functions... Is there anyway to target both input fields and textareas with the same functions?
Instead of this:
$('input').focus(function(){
you can use this to get both types of objects with the same jQuery object and thus the same function:
$('input, textarea').focus(function(){
Though this isn't needed here, you ought to know that you can also put common code in a function and call that one function from multiple places rather than copying code into multiple places. Basically, you should pretty much never copy the same block of code into multiple places.
Another option is to refactor. In this specific case, jfriend00's answer is suitable, but if you needed to pass arbitrary arguments, e.g., the top or left positions, you can always pull out a method.
function tt(p) {
var position = p.position();
var input_name = p.attr('id');
var name = '#'+input_name+'_help';
$('#apply_tooltip').css("left", position.left - 310 );
$('#apply_tooltip').css("top", position.top -15 );
$(name).show();
$('#apply_tooltip').show();
}
$('input').focus(function() {
tt($(this));
});
$('textarea').focus(function() {
tt($(this));
});
My approach would be to do the alignment with CSS (with position: absolute if necessary) and set the tool tip to:
display: none;
Then in jquery you would only have to navigate the DOM and show/hide (or fadeIn fadeOut if you want to get sexy with it).
$('input').focus(function(){
$(this).siblings('.tip').show();
}).blur(function(){
$(this).siblings('.tip').hide();
});