I want to use jQuery to add an image that is on a div to another div, but when I do it the image disappears from the original div. I would like the image to be copied and not moved. Here is the current code.
$( ".rectangle" ).click(function() {
$('.bigRectangle').css('display','block');
$(".notBig").css('opacity',0.2);
var x = $(this).find('img');
$('.bigRectangle').append(x);
});
This is because a DOM node can only have one parent. Appending it to another element will move it to being a child of the other element. Use the .clone method to clone the img element before appending it.
$('.bigRectangle').append(x.clone());
All you would need to do is perform this:
var x = $(this).find('img').clone();
I would recommend you check out the function clone "https://api.jquery.com/clone/"
In your code you are essentially moving the image, when you assign the image in the variable "x" it holds the dom element in that variable. It is a reference. Matter of fact you are holding all images in the document.
Hope this helps, please let me know.
Mr Alexander
Related
My issue is that if I create a clone variable on page load, jQuery will only append it once. Weird!
<p>Click to copy</p>
<div id="container">
<div class="element">This is an element!</div>
</div>
$(document).ready(function () {
var obj = $(".element").clone(true);
$("p").click(function () {
//alert(obj); //Just to see if the variable is still an object.
$("#container").append(obj);
});
});
Here is my CodePen link http://codepen.io/anon/pen/Fwduf
This is what I'm getting after 5 clicks:
Click to copy
This is an element!
This is an element!
What I should be seeing:
Click to copy
This is an element!
This is an element!
This is an element!
This is an element!
This is an element!
This is an element!
Interestingly, if I move the variable deceleration inside the click event, the append works completely as expected.
You need to clone it every time
Codepen Demo
$(document).ready(function () {
var obj = $(".element");
$("p").click(function () {
//alert(obj); //Just to see if the variable is still an object.
$("#container").append(obj.clone(true));
});
});
In your case you are creating a new cloned element only once, after that you are just moving the existing element from one place to another
Arun's answer is correct but does not explain why you need to clone your template element each time you want a new element.
One feature of an individual DOM element, that you may not have been aware of, is that it can only have one parent. This makes sense as the DOM tree connects elements up, down, and sideways to each other and only have a single parent-element link (and a single next and single prev sibling element link) but a list of multiple children.
When you clone an element, you create a new DOM element that is effectively a new branch in a DOM tree (if only a small one). Calling append adds the element to its new parent, but it also points a parent link of your clone to its new parent. By appending the same element over and over you are simply changing the parent of a single element (i.e. moving it in the DOM tree).
As the interaction only runs at user interface speed (i.e. mouse click), you might as well simplify your code to:
$("p").click(function () {
$("#container").append($(".element:first").clone(true));
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/7h8MK/1/
The image gallery that I'm making uses jquery clone to duplicate the image thumbnail that is clicked on and appends it to the #big div, this helps with centering and fixed positioning. The problem I'm having is when I click #right_arrow or #left_arrow, I can't seem to figure out how to select the next or previous item in the list and append that to the body.
I know jquery has .next() but I'm having trouble figuring out how that works.
here's the jsFiddle: http://jsfiddle.net/reveries/UgQre/
$(document).ready
$('img, div.wrapper').each( function() {
var $img = $(this);
$img.addClass('thumbnail');
$img.wrap('<li></li>');
$img.click(function() {
$img.clone().appendTo('#big');
$('#big').fadeToggle('slow');
$('#right_arrow').fadeIn('slow');
$('#left_arrow').fadeIn('slow');
});
$('#big').click(function(){
$img.addClass('thumbnail');
$('#big').fadeOut('slow');
$(this).html('');
$('#right_arrow').fadeOut('slow');
$('#left_arrow').fadeOut('slow');
})
$('#right_arrow').click(function(){
$('#big').html('');
})
$('#left_arrow').click(function(){
$('#big').html('');
})
});
Here is a fixed version of your fiddle: http://jsfiddle.net/abeisgreat/fu3fX/
Your code has a few issues that keep it from working properly. Firstly, your .click() calls are within your .each, which means that #big, #right_arrow, #left_arrow will all have multiple bindings of the same function, which isn't what you want.
Secondly, you're right in assuming that .next() and .prev() is what you want to use, the problem is that $img.next() doesn't exist because you're wrapping each img in an li tag in your .each(). Because of this $img has no sibilings and .next() and .prev() will be not return the next img tag. So you really need to call $img.parent().next().children(), to get the next image.
The only major change I made was to add a global called $selected_li, which contains the li of the selected image. Once we have that, we can do this.
$('#left_arrow').click(function(){
$('#big').html('');
$selected_li.prev('li').children('img').clone().appendTo('#big');
$selected_li = $selected_li.prev('li')
})
To progress backwards or the exact same with .next() to move forward. You were very close, like I said I think the big issue was the wrapping with li which removed any sibilings from your img tags!
Hope this helps,
Abe
I am trying to make the following:
On click of each image (thumbnail) source should be writen into specified input.
I have done that sort of... Not working quite fine just yet!
It doesn't add correct source, just first source all the time, no matter what image is clicked.
It doesn't remove added source if clicked again on same/different image.
// Piece of jQuery script:
var imgSource = $('#textures li').find('img').attr('src');
$('ul#textures li img').on('click', function() {
$('input#imgPath').val($('input#imgPath').val() + imgSource);
});
Fiddle for better understanding:
JS Fiddle link
P.S. Explanation of your answer will be appreciated!
attr only returns a attribute of the first matched element, you can use this keyword which refers to the clicked element.
$('ul#textures li img').on('click', function() {
$('#imgPath').val(this.src)
});
http://jsfiddle.net/Uz6rc/
use: $(this) - that mean the attribute of the click element
$('ul#textures li img').on('click', function() {
$('input#imgPath').val($('input#imgPath').val() + $(this).attr('src'));
});
Take a look: http://jsfiddle.net/e3HzQ/
From the jQuery docs:
The .attr() method gets the attribute value for only the first element
in the matched set.
Your imgSource variable is declared outside of the event handler, so it doesn't vary its value according to the clicked image - it just maintains the value from the first image.
Also, the previous value isn't removed because you are appending the value to what is already there.
Here you go:
$('ul#textures li img').on('click', function() {
var imgSource = $('#textures li').find('img').attr('src');
$('input#imgPath').val($(this).attr("src"));
});
DEMO
The reason it was not working for you is because you have defined
var imgSource = $('#textures li').find('img').attr('src');
outside of on function. And then further you were everytime setting the same value inside the text box using:
$('input#imgPath').val($('input#imgPath').val() + imgSource);
I modified this line to get the img src by using this operator.
I have the following code which swaps out one divs innerHTML for the others on a DND based situation.
dragSrcEl = //This is the var that is assigned to the object that is being dragged, appears outside of this code below.
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
What would I have to do, if i wanted it to change everything, namely the whole container, all its rels, propertys, classnames, id's, data attributes e.t.c
I cannot re-order it within the dom, due to the dynamic way that each of these will be dragged and dropped about...
Many thanks!
This will do the moving:
$(dargSrcEl).replaceWith(this);
Update: Everyone that contributed, it's well appreciated, you all are very kind and generous and all of you deserve my dear respect. Cheers.
Note: I'm making a simple jQuery tooltip plugin, the tooltip will fire on mouseover. The mouseover will create an instance of the div tool-tip that will be specific to each anchor that launched the div tool-tip. So each anchor with the class .c_tool will have its own created div that will erase after mouseout. Anyway all those details are irrelevant. What is important is how to create a div with .append() or .add() on and then find a way to call it and apply actions to that div without setting an identifier (id), class, or any means to identify it.
I know theres a way you could find the div by counting, so if you gave every created div the same class and then counted them to find that one, however I don't know if this is the most efficient method that is why I'm asking for help.
I'm not going to post the whole plugin script thats unnecessary, so I'll paste a simplified version.
hover me
hover me
$(document).ready(function() {
obj = $('a.c_tool');
obj.mouseover(function() {
/// append div to body it will be specific to each item with class c_tool, however I don't want to set an ID, or CLASS to the appended div
}).mouseout(function() {
/// remove added div without setting ID or class to it.
});
});
Working example:
http://jsfiddle.net/xzL6F/
$(document).ready(function() {
var tooltip;
obj = $('a.c_tool');
obj.mouseover(function() {
var element = $('<div>', {
html: "I'm a tooltip"
});
tooltip = element.appendTo($("body"));
/// append div to body it will be specific to each item with class c_tool, however I don't want to set an ID, or CLASS to the appended div
}).mouseout(function() {
tooltip.remove();
/// remove added div without setting ID or class to it.
});
});
To create a new DOM node you can use the jQuery constructor, like
$(document).ready(function() {
obj = $('a.c_tool');
obj.mouseover(function() {
if(!$.data(this, 'ref')) {
$.data(this, 'ref', $ref = $('<div>', {
html: 'Hello World!'
}).appendTo(document.body));
}
}).mouseout(function() {
$.data(this, 'ref').remove();
});
});
.appendTo() returns the DOM node of invocation (in this case, the newly created DIV) as jQuery object. That way you can store the reference in a variable for instance and access it later.
Referring your comment:
To remove all stored references, you should do this:
$('a.c_tool').each(function(index, node) {
$.removeData(node, 'ref');
});
you can use $.append(
);
http://api.jquery.com/append/
and to find the DOM created dynamically u can use
$("#dynamicallyCreatedDOMid").live("yourCustomTrigger",function(){
});
http://api.jquery.com/live/