Get reference to original element when dropped - javascript

I am using HTML5 native drag and drop for dropping images into a div. Here is an example: http://jsbin.com/ipojuk/1/
The problem is, once dropped the same image should not be dropped again. How to prevent this from happening? For this purpose i have set a data-inplan attribute in image, and i was planning to set it to true once an image is dropped, but i can't find an easy way to get a reference to the original image in function dragDrop. I thought about using an id, but these images are created at runtime, and generating id's will be hard for me.

This will allow you to drop only one image per type (checking the src)
function dragDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // Stops some browsers from redirecting
}
var $item = $(e.dataTransfer.getData('text/html'));
var exists = false;
$(".divRendezvous img").each(function()
{
if($(this).attr("src")==$item.attr("src"))
{
exists = true;
return;
}
});
if(!exists)
$item.appendTo(e.target);
return false;
}
jsBin: http://jsbin.com/ipojuk/12/edit

Related

Calling a function or focusing a programmatically generated Iframe from an HTML5 canvas

I have an HTML5 canvas controlled and generated by a library of JavaScript files (Craftyjs library mostly).
The canvas generates 2 regular html iframes (same domain) which are stacked on top of each other.
The canvas switches between the two iframes based on calls from the iframes to the parent so I know the code controlling the canvas is easily accessed by their common parent.
I want the parent canvas to either call a function in the iframes to have them focus on a specific element in them or to somehow just have the iframes get focus in general.
I would also prefer to not have to constantly reload/recreate the iframes to get focus.
---- In the Iframe ----
//The head has a function "focusThis()" to focus on an element in the iframe
//body also has onfocus="focusThis();"
//Call the parent to change to the other iframe
parent.changeIframe();
---- In the parent's canvas JS code ----
// I know the function and will hide/show the iframe, but it won't focus
function changeIframe(){
//For now, just switch randomly
MODE = Math.floor(Math.random()*2);
//I am hiding the iframes here, then showing the one that should be seen
Crafty("Game1").each(function () {this.visible = false});
Crafty("Game2").each(function () {this.visible = false});
//Switch the iframes
if(MODE){
//Show this iframe
Crafty("iframe1").each(function () {this.visible = true});
These are things I have tried to get to work
When it doesn't throw an error it doesn't do anything in chrome or FireFox.
(Object [object global] has no method 'focusThis') is a common error
//document.getElementById('iframe1').focus();
//document.getElementById("iframe1").contentWindow.focusThis();
//document.getElementById('iframe1').contentWindow.focusThis();
//var iframe_window = window.frames["iframe1"];
//iframe_window.focus();
//iframe_window.contentDocument.body.focus();
//window.parent.document.getElementById('iframe1').contentWindow.focusThis;
//window.parent.document.getElementById('iframe1').contentWindow.focusThis();
//window.frames["iframe1"].focus();
//window.frames["iframe1"].contentWindow.focus();
//window.frames["iframe1"].contentDocument.focus();
var frame = document.getElementById("iframe1");
if(frame){
alert("yep");
frame.contentWindow.focusThis();
}
}
else{
//....Same thing but for iframe2
}
}
Any help would be greatly appreciated.
I solved my problem after some more fiddling.
This also solved my problem without having to reload the iframe.
I set a timer in the onload function of each iframe that tries to focus itself onto an element in itself based on a parent flag variable (MODE) that tells the iframe if it is supposed to have focus and an internal variable (focused) that tells it to stop trying to focus once it finally has focus again.
Somewhere in the head...
var focused = false;
function focusThis(){
if(parent.MODE && !focused){
document.getElementById("SOME_ELEMENT_I_WANT_FOCUSED").focus();
focused = true;
}
}
Somewhere in onLoad...
var autoFocus =
setInterval(function(){if(parent.MODE && !focused) focusThis()},500);
Somewhere in script below the body...
parent.changeIframe();
changeImage();
if(!parent.MODE){
//This element is just to have a place for focus to go when out of focus
document.getElementById("NA").focus();
focused = false;
}
else
focused = true;

Drag and drop javascript event

I'm a java guy trying my hand in javascript and need some help. I came across an amazing tutorial on image uploads here Mozilla Tutorial and need some help figuring it out. I am currently working on the drag and drop image upload feature. Every time I drag an image onto my area the mouse turns green so it's activated. But then when I let go it should send me an alert that says one image was found. However it always just alerts 0. So the size of the array is 0. Any ideas? Thanks for taking a look. What I've tried with no success...
Copying and pasting the code from the tutorial into my javascript file exactly
Moving the code to add the listeners outside of a function and into a window onload
Every browser I have
...
function toggleStrideMedia()
{
if(getDisplay("strideMediaWrapper") == "" || getDisplay("strideMediaWrapper") == "none")
{
show("strideMediaWrapper");
getElement("strideMediaDropZone").addEventListener("dragenter", dragenter, false);
getElement("strideMediaDropZone").addEventListener("dragover", dragover, false);
getElement("strideMediaDropZone").addEventListener("drop", drop, false);
}
else
{
hide("strideMediaWrapper");
}
}
function dragenter(e)
{
e.stopPropagation();
e.preventDefault();
}
function dragover(e)
{
e.stopPropagation();
e.preventDefault();
}
function drop(e)
{
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
// THIS SHOULD BE GIVING ME A ONE BUT IT ALWAYS GIVES ME A ZERO INSTEAD
alert(files.length);
handleFiles(files);
}
.
UPDATE - Fiddle Results
UPDATE
The actual problem turned out to be that if you try to drag images directly from one web browser tab to this web based drag and drop interface, the event will fire but no files will be dropped. The asker noted this issue on OSX and I was able to replicate the same behavior in Windows 7.
Without seeing your HTML, it's hard to tell what you were having difficulty with. If the ondragover/ondragenter piece wasn't set up correctly then dropping won't work, but you wouldn't see an alert at all, you'd just see the browser render the image from the local filesystem. That also means that you're almost certainly successfully adding the drop event to the correct element.
Try this Fiddle and see if it works for you: http://jsfiddle.net/qey9G/4/
HTML
<div>
<div id="dropzone" style="margin:30px; width:500px; height:300px;
border:1px dotted grey;">
Drag & drop your file here...
</div>
</div>
JavaScript
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.stopPropagation();
event.preventDefault();
}
dropzone.ondrop= function drop(e)
{
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
alert(files.length);
}

How do I make the entire div clickable using plain javascript?

I don't need to write this in jQuery but I'm not versed enough in plain javascript to figure it out. Chris Coyier wrote a nice explanation of what I'm talking about here.
The reason I want to convert it is because I don't need to include an entire jQuery library for this one piece of code. I can save that extra request by using plain old javascript.
This is the example code that I want to convert:
$(document).ready(function() {
$(".featured").click(function(){
window.location=$(this).find("a").attr("href"); return false;
});
});
Here's what I've come up with so far:
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("div.feature").click(function(){
window.location=$(this).find("a").setAttribute("href");
return false;
});
});
One thing which isn't correct in this, as far as I know, are the querySelectorAll, which is looking for just a div element, right? The other thing is the $(this), which I don't know how to translate into plain javascript.
Assuming...
you know the browser support for querySelectorAll and yet you still use it
that addEventListener only works for standards compliant browsers
I believe you meant:
//get all a's inside divs that have class "featured"
var feat = document.querySelectorAll("div.featured a"),
featlen = feat.length,
i;
//loop through each
for(i=0;i<featlen;++i){
//add listeners to each
feat[i].addEventListener('click',function(){
window.location = this.href;
},false);
}
Or you can have the <div> wrapped in <a>. No JS required. It's perfectly valid HTML and browsers do work as intended despite the rule that inline elements should not contain block elements. Just make sure to have display:block on <a> as well as adjust its size.
<a href="location">
<div> content </div>
</a>
You can select with this.querySelectorAll(...):
IE8:
window.onload = function() {
// get all dom elements with class "feature"
var aFeatures = document.querySelectorAll(".feature");
// for each selected element
for (var i = 0; i < aFeatures.length; i++) {
// add click handler
aFeatures[i].onclick = function() {
// get href of first anchor in element and change location
window.location = this.querySelectorAll("a")[0].href;
return false;
};
}
};
IE9 and other current browser:
document.addEventListener("DOMContentLoaded", function() {
// get all dom elements with class "feature"
var aFeatures = document.querySelectorAll(".feature");
// for each selected element
for (var i = 0; i < aFeatures.length; i++) {
// add click handler
aFeatures[i].addEventListener('click', function() {
// get href of first anchor in element and change location
window.location = this.querySelectorAll("a")[0].href;
return false;
});
}
});
=== UPDATE ===
For IE7 support you should add following (untested) script before (also see here):
(function(d){d=document,a=d.styleSheets[0]||d.createStyleSheet();d.querySelectorAll=function(e){a.addRule(e,'f:b');for(var l=d.all,b=0,c=[],f=l.length;b<f;b++)l[b].currentStyle.f&&c.push(l[b]);a.removeRule(0);return c}})()
It is possible that it only supports document.querySelectorAll not element.querySelectorAll.

Create multiple tiles that fade into different images using javascript

I am working on a web project and I want to make a 3x2 row of tiles that when you mouse over them the tile will fade out and fade in with a new one containing the image.
I have multiple tiles that are images using the DIV class .previewBox. When you mouse over these images I use JQuery to fade out the image and fade back in with a new one (using a JQuery plugin called waitForImages which is specifically tailored for loading images in JavaScript) The problem is I want each tile to fade with a different set of images. I thought of putting all of the first set of images (The preview images) in an array and the second set of images (The flip images) in a different array and when you mouse over and it would want to set the flip image it would call flipArray.indexOf(this) but since the JavaScript is detecting the div I am not sure if that will work because "this" isn't referring to the image in the array.
I am still really learning javascript and I am not really sure how to detect which image you are hovering over and take its index number to switch it out with another picture.
I have the script for fading images but right now I have the image location hard coded.
$(document).ready(function() {
//Document is ready to load
var hov = false;
//Since there is more then one tile using the .previewBox I use the .each command
$('.previewBox').each(function() {
var previewBox = $(this); // Won't create as many objects this way.
previewBox.mouseenter(function() // On mouse enter
{
if (hov === false) //Keeps animation from repeating
{
hov = true; // Sets boolean for mouse leave
previewBox.fadeOut(function() //Fades out
{
previewBox.waitForImages(function() //Loads images
{
previewBox.stop().fadeIn(); //Fades in
});
previewBox.attr("src", "Images/Portfolio/Art_Bike_Flip.png"); //New image location.
});
};
});
});
$('.previewBox').each(function() {
var previewBox = $(this);
previewBox.mouseleave(function() {
if (hov === true) {
hov = false;
previewBox.fadeOut(function() {
previewBox.waitForImages(function() {
previewBox.stop().fadeIn();
});
previewBox.attr("src", "Images/Portfolio/Art_Bike_Preview.png");
});
};
});
});
});

Z-Index on Absolute Positioned Element Shows Above Higher Z-Index Elements

I am trying to create some javascript that when an object is added to the window, a listener listens for any click on the body except for the placed object and removes the object if anywhere on the window except the actual object itself is clicked.
Through numerous unsuccessful attempts, the idea I came up with is to dynamically add an overlay div to the screen called overlay2 (or whatever, it doesnt matter) and then listen for clicks on that div. When I add the overlay to the window and set the zIndex to a higher number than the top element already placed (say 5000) and then set the zIndex of the only object to be placed above the overlay to an even higher number (say 6000), the overlay still appears on top of everything and I cannot select any of the objects in the div I meant to place above it.
var overlayDiv = document.createElement('div');
overlayDiv.setAttribute('id', 'overlay2');
overlayDiv.style.zIndex = '5000';
overlayDiv.style.width = '100%';
overlayDiv.style.height = '100%';
overlayDiv.style.left = '0';
overlayDiv.style.top = '0';
overlayDiv.style.position = 'absolute';
document.body.appendChild(overlayDiv);
$(container).append(template);
template.style.zIndex = '6000';
//Listeners
//Page click listener. Closes the tool when the page is clicked anywhere but inside the parent.
var initialClick = false;
$('body').on('click.editObjectListeners', function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
console.log(target.id);
if(target.id == 'overlay2' && target.id != '') {
$(overlayDiv).remove();
finish();
};
}
initialClick = true;
});
I've determined that this has everything to do with the absolute positioning of the overlayDiv. While testing, if I used absolute positioning to place the template and if I append the template object directly to the body like I did the overlayDiv, the zIndex works above the overlayDiv as I originally anticipated. Unfortunately absolutely positioning this element doesn't make much sense for me beyond testing purposes. Is there a way to get around this?
Turns out that z-index can really only be used successfully with absolute placed elements. Therefore the original plan to solve the body click listener will not work. Instead, I decided to use jQuery and listener objects to listen for the click instead. Its a much cleaner solution, I just had to wrap my head around it. You can view my other solution here.
I don't know how much this will help your particular problem, but I just happened to notice that you may have a problem with your use of jQuery's "on()" method.
First off, you are using jQuery version 1.7+ with that, correct?
Unlike "live", I believe that the on() parameters are event, selector, function.
So where you have this:
$('body').on('click.editObjectListeners', function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
console.log(target.id);
if(target.id == 'overlay2' && target.id != '') {
$(overlayDiv).remove();
finish();
};
}
initialClick = true;
});
I think you want this:
$('body').on('click.editObjectListeners', [SOME SELECTOR], function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
console.log(target.id);
if(target.id == 'overlay2' && target.id != '') {
$(overlayDiv).remove();
finish();
};
}
initialClick = true;
});
Hope that helps in some small way.
Good luck!
Try setting the zIndex before appending it to container.
template.style.zIndex = '6000';
$(container).append(template);

Categories

Resources