Please see the my test site here.
The script is written in the <head> so you will be able to see it there.
Instructions
If you click the blue area a new element will be made. Do this four or five times. Now click all the elements you've just created. They should all have a black outline. However, some do and some don't.
Additional Info:
Only tested on chrome so far.
Any ideas on what's going wrong here?
You are adding the click listener to all bubbles each time a new one is created.
Add the listener once with the live listener. It can be set before any of the bubbles are created.
And don't use numeric id attributes, it's disallowed by HTML.
Also, you are toggling the active class -- there's a shorter function for this -- toggleClass.
You can simplify using this:
$(function () {
// CREATE A NEW BUBBLE
$('.drop').click(function(event){
Bubble(event);
});
var newBubbleId = 0;
function Bubble(event,bubbleClass){
// Create Element
var id = newBubbleId++;
var bubble = $('<div class="bubble" id="b_'+id+'" draggable="true"><input id="bubbleText" type="text" name="text" value="'+id+'" /></div>');
$('body').append(bubble);
// Position Element
var bubbleWidth = bubble.width();
var bubbleHeight = bubble.height();
var x = event.pageX - (bubbleWidth*0.5);
var y = event.pageY - (bubbleHeight*0.5);
bubble.offset({top:y, left:x});
bubble.click(function () {
$(this).toggleClass("active");
});
}
});
I see a few other issues. Number ids as mentioned before. Also, all your input elements have the same ID, that is not allowed. One ID per document only. You can use the Name attribute if you want them to have the same name.
Also, your counter function isn't ideal.
But this should solve your problem.
Related
let wrapperSt = document.querySelector(".wrapper");
for(i=0; i<100; i++){
let divGroup = document.createElement('div');
wrapperSt.append(divGroup);
divGroup.className= 'pixel';
divGroup.textContent= '';
}
I've created the div element called "pixel" by using loop because, i need couple hundreds of them. (I'll use them as a little boxes that could change color)
But, i want these boxes ("pixel" div) to turn brown and sustain (style.backgroundColor ="brown";)
So, i created another div that will replace the previous div ("pixel").
let selectPx = document.getElementsByClassName("pixel");
selectPx.addEventListener("mouseover", function(){
let pxChange = createElement("div");
//This is where i got stuck!
})
I could not finish my code, i found it a bit complicated even if it is probably something very simple.
Any suggestions or piece of information would be very helpful. Thank you.
Not sure exactly what you are trying to do... I think you are trying to change the color of the div that your mouse is over? If so, you have a couple of issues with your code. Instead of adding the event listener to the list of divs, you need to add it to each one individually. Also, you should only need to change the background color of each element instead of creating a new one each time.
let selectPx = document.querySelectorAll(".pixel");
selectPx.forEach(pixel => {
pixel.addEventListener("mouseover", () => {
pixel.style.backgroundColor = "brown";
});
});
I'm not sure why you have to create a new div inside the first one. In your code, when you trigger the mouseover event you can get the div under the mouse and apply the style to it:
let selectPx = document.getElementsByClassName("pixel");
selectPx.addEventListener("mouseover", function(evt){
let divUnderMouse = evt.target;
divUnderMouse.style.backgroundColor ="brown";
})
I haven't tried it but it should work
I'm working off of a tutorial from codrops. There is a hover event for each item, as well as a click event that triggers an anime.js function.
I'm trying to work this so certain items (grid cells) don't trigger the anime.js function when clicked, but the hover function still works.
I've tried simple css pointer-events, but that disables the hover function.
I've constructing the two groups as separate items in JS, but then the animation doesn't work the same (it staggers the two different classes).
I've tried things to stop the default javascript behavior, but it seems to have no impact on the code.
Help!!!
I've made a functioning codepen - in the option there I'm trying to disable click event for any grid item with the id="noClick" - to no avail.
$('noClick').observe('click', function(event) {
Event.stop(event);
});
This is the primary function that creates the event
this.DOM.items.forEach((item, pos) => {
// The item's title.
const title = item.dataset.title;
// Show the title next to the cursor.
item.addEventListener('mouseenter', () => cursor.setTitle(title));
item.addEventListener('click', () => {
// Position of the clicked item
this.pos = pos;
this.title = title;
// Start the effect and show the content behind
this.showContent();
// Force to show the title next to the cursor (it might not update because of the grid animation - the item under the mouse can be a different one than the one the user moved the mouse to)
cursor.setTitle(title);
});
});
where 'item' is
this.DOM.grid = this.DOM.el.querySelector('.grid');
// Thr grid items
this.DOM.items = [...this.DOM.grid.children];
// totla number of grid items
this.itemsTotal = this.DOM.items.length;
I've tried to create multiple items
this.DOM.grid = this.DOM.el.querySelector('.grid');
this.DOM.yesClick = this.DOM.el.querySelector('.yes-click');
this.DOM.yesClickTwo = this.DOM.el.querySelector('.yes-click-2');
this.DOM.noClick = this.DOM.el.querySelector('.no-click');
// Thr grid items
this.DOM.items = [...this.DOM.yesClick.children, ...this.DOM.yesClickTwo.children];
this.DOM.itemsNo = [...this.DOM.noClick.children];
this.DOM.allItems = [...this.DOM.noClick.children, ...this.DOM.yesClick.children, ...this.DOM.yesClickTwo.children];
// totla number of grid items
this.itemsTotal = this.DOM.allItems.length;
This works, but messes with the animaton.
Here is the codepen
I feel this is really simple and I'm missing something. Looking to learn, so a push in the right direction or any help would be greatly appreciated!
1. You have multiple elements with the same ID. But ID attribute must be unique.
2. You used $('noClick'), but ID selector would look like #noClick
If you want to mark few elements, use a class and select them like .elementclass. It is possible for element to have multiple classes, separated by space.
Your selector doesn't seem correct so you either need #noClick or .noClick as the selector however you can stop the javascript from bubbling like this :-
$(".noClick").click(function(e) {
// Do something?
e.stopPropagation();
});
I have an AJAX call that when it's done i have this code:
$(".results").append('<div class="horizontal result_element"><div class="result_photo"></div><div id="'+user_id+'" class="result_data">'+user_name+'</div></div>');
Later i want something to happen when i click on the class result_element:
$(".result_element").click(function(){
var url = "profile.php?user_id="+$(this).children("[class='result_data']").attr("id");
$(location).attr('href',url);
});
But it doesn't work and my thought is that jQuery create the html elements but doesn't appends them to the DOM.Any idea on how can i make this work with that method?
I assume that you mean with 'later' the time in the user-sight an not the time in the script.
The problem is that the jQuery doesn't know about the element if you create it after explaining that jQuery shell do x on event y. So if you set the click-event in $(document).ready(function(){*here*}) and you create an element afterwards (after the document-ready was fired), jQuery doesn't know these fresh elements.
So to solve your problem, try to add the event after you created the element (creation not equal to appending!):
// created the element
var newElement = $('<div class="horizontal result_element"><div class="result_photo"></div><div id="'+ user_id +'" class="result_data">'+ user_name +'</div></div>');
// now set the event
newElement.click(function () {
var url = "profile.php?user_id="+ $(this).children("[class='result_data']").attr("id");
$(location).attr('href',url);
})
// now append it
newElement.appendTo($(".results"))
// or: $(".results").append(newElement)
And you can reorder the two last steps, so you first append it and then set the event, thats not the point. The point is, that you create the element first and then set the event.
I believe, click is not working on result_element class which is added dynamically. Try with following code snippet.
$(document).on("click",".result_element", function(){
var url = "profile.php?user_id="+$(this).children("[class='result_data']").attr("id");
$(location).attr('href',url);
});
I am trying to add a class to the siblings of a nested div depndant on the length of a scope attached to the dom in itself, for the purpouse of demonstration i have just declared a variable with a number assigned to it, so here is my current js:
var countdates = $('.date').length;
var minstay = 5;
alert(countdates);
$('.date').on('click', function () {
$(this).addClass('dateset' + minstay);
});
and here is a example fiddle basically my question is if i click on a div i want the next 5 divs to have a class added to them even if they span across the nested divs??
I have tried to google this but i can't seem to get the terminology right.
Get the index of the current one, add the minstay, and use a selector that selects everything inbetween ?
var minstay = 5;
$('.date').on('click', function () {
var start = $(this).index('.date'),
end = start + minstay;
$('.date:lt('+end+'):gt('+(start-1)+')').addClass('dateset');
});
FIDDLE
I have an application in which the user needs to see the changes that have been made during the latest edit.
By changes I mean, the changes made in all inputs like a textarea, dropdowns.
I am trying to implement this by showing a background image on the right top and then when the user clicks this background image, a popup is shown which shows the difference.
I am using prototype 1.7.0.
My First question would be:-
1. What would be the best approach to implement this functionality?
2. Can I put a onClick on the background image?
There some functions in the jQuery library that I believe would be helpful to you. If you are using prototype, I would guess that there is some similar functionality you may utilize.
I would suggest writing some code like this:
var $input = $('input').add('textarea').add('select');
$input.each(function() {
var id = $(this).attr('id');
var value = $(this).val();
var hiddenId = 'hidden' + id;
var newHiddenInput = $("<input type='hidden'").val(value).attr('id',hiddenId);
$(this).after(newHiddenInput);
});
The above code will create a new hidden input for each input, textarea, and select on your page. It will have the same value as the input it duplicates. It will have an id equivalent to prepending the id with the word 'hidden'.
I don't know if you can attach a click handler to a background image. If your inputs are enclosed inside a <div>, you may be able to get the result you want by attaching the click handler to your div.
In any case, you should now have the old values where you can easily compare them to the user's input so that you can prepare a summary of the difference.
Prototype gives us the Hash class which is almost perfect for this but lacks a way of calculating the difference with another hash, so let's add that...
Hash.prototype.difference = function(hash)
{
var result = this.clone();
hash.each(function(pair) {
if (result.get(pair.key) === undefined)
// exists in hash but not in this
result.set(pair.key, pair.value);
else if (result.get(pair.key) == pair.value)
// no difference so remove from result
result.unset(pair.key);
// else exists in this but not in hash
});
return result;
};
This is no way to tell if an element was clicked on just it's background image - you can find out the coordinates where it was clicked but that is not foolproof, especially since CSS3 adds complications like multiple backgrounds and transitions. It is better to have an absolutely positioned element to act as a button.
$('button-element').observe('click', function() {
var form_values = $H($('form-id').serialize(true));
if (old_values) {
var differences = old_values.difference(form_values);
if (differences.size()) {
showDiffPopup(differences);
}
}
window.old_values = form_values;
});
// preset current values in advance
window.old_values = $H($('form-id').serialize(true));
All that remains is to implement showDiffPopup to show the calculated differences.