I know how to drag and drop in one window with html5. But how to drag and drop across frames?
Here is my script which can work in one window. Can someone help me?
<script>
var drag = document.getElementById("drag");
var drop = document.getElementById("drop");
drag.onselectstart = function () {
return false;
}
drag.ondragstart = function (ev) {
ev.dataTransfer.effectAllowed = "move";
ev.dataTransfer.setData("text", ev.target.innerHTML);
}
drag.ondragend = function (ev) {
var text = ev.dataTransfer.getData("text");
alert(text);
ev.dataTransfer.clearData("text");
return false;
}
drop.ondragover = function (ev) {
ev.preventDefault();
return true;
}
drop.ondragenter = function (ev) {
this.background = "#ffffff";
return true;
}
drop.ondrop = function (ev) {
}
</script>
#Nickolay: oh, ok.
There's an example at http://www.useragentman.com/blog/2010/01/10/cross-browser-html5-drag-and-drop/ .
Added:
I'm not sure why the OP's code didn't work - maybe it wasn't loaded in both frames? I modified their Javascript a little to give more indications:
window.onload = function () {
var drag = document.getElementById('drag');
var drop = document.getElementById("drop");
if (drag) {
drag.style.backgroundColor = '#00ff00';
drag.onselectstart = function () {
return false;
}
drag.ondragstart = function (ev) {
ev.dataTransfer.effectAllowed = "move";
ev.dataTransfer.setData("text", ev.target.innerHTML);
}
drag.ondragend = function (ev) {
var text = ev.dataTransfer.getData("text");
alert(text);
//ev.dataTransfer.clearData("text");
return false;
}
}
if (drop != null) {
drop.style.backgroundColor = '#0000ff';
drop.ondragover = function (ev) {
ev.preventDefault();
return false;
}
drop.ondragenter = function (ev) {
this.style.backgroundColor = "#ff0000";
return false;
}
drop.ondrop = function (ev) {
return false;
}
}
}
It works between iframes and between browser windows (only tested in Firefox 11 and IE9 on Windows 7 x64).
I modified your script to work in the case that the iframe name is "frame1". Please check it now.
<script type="text/javascript">
window.onload = function ()
{
var drag = document.getElementById("drag");
var drop = frame1.document.getElementById("drop");
drag.draggable = true;
drag.onselectstart = function () {
return false;
}
drag.ondragstart = function (ev) {
ev.dataTransfer.effectAllowed = "move";
ev.dataTransfer.setData("text", ev.target.innerHTML);
}
drop.ondragover = function (ev) {
ev.preventDefault();
return true;
}
drop.ondragenter = function (ev) {
this.background = "#ffffff";
return true;
}
drop.ondrop = function (ev) {
var data = ev.dataTransfer.getData("text");
drop.innerHTML += data;
ev.preventDefault();
}
}
Check out the tutorial for Cross-Frame Drag and Drop. It explains the events required and the basic flow when working with multiple frames.
http://blog.dockphp.com/post/78640660324/cross-browser-drag-and-drop-interface-development-using
How are the iframes hosted? are you just using html files? as this could potentially be the issue.
I created a couple of html files with the drag and drop code in your question, this didn't work when just referencing each other. However when I added the files to IIS server and referenced the files using localhost it then started to work.
Related
I just started experimenting with IndexedDB. I copied an example and pared it down to a small HTML page: Push a button; add a record; dump all the records to the console after the transaction completes.
It runs fine in IE11, but not on Chrome.
The request=transaction.objectstore("store").add({k:v})is always executing the request.onsuccess() method, but the transaction is always resolved with transaction.onabort() by Chrome. Same with .put().
This is the code:
<!DOCTYPE html>
<html>
<head>
<script>
//--- globals
var db;
// The initialization of our stuff in body.onload()
function init() {
var dbVersion = 1;
//--- Try to delete any existing database
var delRequest = indexedDB.deleteDatabase("notesDB");
delRequest.onsuccess = function (de) {
dbOpen(); // .... then open a new one
};
delRequest.onerror = function (de) {
dbOpen(); // ... or open a new one if one doesn't exist to delete
};
function dbOpen () {
var openRequest = indexedDB.open("notesDB", dbVersion);
openRequest.onupgradeneeded = function (e) {
var ldb = e.target.result;
console.log("running onupgradeneeded; always start with a fresh object store");
if (ldb.objectStoreNames.contains("note")) {
ldb.deleteObjectStore("note");
}
if (!ldb.objectStoreNames.contains("note")) {
console.log("creating new note data store");
var objectStore = ldb.createObjectStore("note", { autoIncrement: true });
objectStore.createIndex("title", "title", { unique: false });
}
};
openRequest.onsuccess = function (e) {
db = e.target.result;
db.onerror = function (event) {
// Generic error handler for all errors targeted at this database
alert("Database error: " + event.target.errorCode);
console.dir(event.target);
};
console.log("Database opened; dump existing rows (shouldn't be any)");
displayNotes();
};
openRequest.onerror = function (e) {
console.log("Open error");
console.log(e);
console.dir(e);
};
}
function displayNotes() {
console.log("TODO - print something nice on the page");
var tx = db.transaction("note", "readonly");
tx.oncomplete = function (event) { console.log("read only cursor transaction complete"); }
tx.onerror = function (event) { console.log("readonly transaction onerror"); }
tx.onabort = function (event) { console.log("readonly transaction onabort"); }
// --- iterate cursor
console.log("---Start cursor dump---")
var ds = tx.objectStore("note");
ds.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log(cursor.key);
console.dir(cursor.value);
cursor.continue();
}
else {
console.log("---End cursor dump---");
}
};
}
document.querySelector("#test").addEventListener("click", function (clickevent) {
try {
var transaction = db.transaction("note", "readwrite");
transaction.oncomplete = function (event) {
console.log("Cursor dump in 'add' read/write transaction oncomplete");
displayNotes();
console.log("add transaction oncomplete done!");
};
transaction.onerror = function (event) {
console.log("add transaction onerror");
};
transaction.onabort = function (event) {
console.log("add transaction onabort");
};
var objectStore = transaction.objectStore("note");
var request = objectStore.add({
title: "note header",
body: "this is random note body content " + Math.floor(Math.random() * 1000)
});
request.onsuccess = function (event) {
console.log("add request onsuccess");
};
request.onerror = function (event) {
console.log("add request onerror");
console.dir(event);
};
}
catch (e) {
console.log('catchall exception');
console.log(e);
alert("bad things done");
}
});
}
</script>
</head>
<body onload="init()">
<h1>IndexedDB simplest example</h1>
<p>
<button id="test">Push To Add Row To IndexedDB</button>
</p>
</body>
</html>
I clicked the button a bunch of times and it worked every time.
What error are you getting when it aborts? Look in event.target.error in the onabort handler to see. It could be a QuotaExceededError, which would mean that either you have very low hard drive space or you have a lot of data stored in Chrome for your domain. If that's the case, it's good you're running into it now, because you do need to gracefully handle this case, otherwise users will hit it and be confused.
My app uses Silverlight 8.0 SDK, the MSGestureHold event works on Windows 8, but if the same is tested on 8.1 the event is not triggered.
This code works fine in webview for WPhone 8.1 apps :
var init = function(){
var myState = // context
var target = // DOM variable target
var msg = new MSGesture();
msg.target = target;
target.addEventListener("MSGestureHold", function (evt) { buttonTactileListener.apply(myState, [evt, msg]); }, false);
target.addEventListener("pointerdown", function (evt) { buttonTactileListener.apply(myState, [evt, msg]); }, false);
target.addEventListener("MSGestureEnd", function (evt) { buttonTactileListener.apply(myState, [evt, msg]); }, false);
}
var buttonTactileListener = function (evt, msgesture) {
var myState = this;
if (evt.type == "pointerdown") {
msgesture.addPointer(evt.pointerId);
return;
}
if (evt.type == "MSGestureHold") {
///do something
return;
}
if (evt.type == "MSGestureEnd") {
// renew instance of handler
msgesture = new MSGesture();
msgesture.target = evt.target;
return;
}
}
I am trying to load my google map asynchronously and it works but it is loading the map in twice. If I remove "box.onload = initialize;" this stops that problem but then the infobox doesn't show...how do I fix my code so it only loads the map once AND shows the infobox.
function loadScript() {
var map = document.createElement('script');
map.type = 'text/javascript';
map.src = 'https://maps.googleapis.com/maps/api/js?key=key_goes_here&sensor=false&callback=initialize';
document.body.appendChild(map);
map.onload = function() {
var box = document.createElement('script');
box.type = 'text/javascript';
box.src = 'https://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js';
document.body.appendChild(box);
box.onload = initialize;
};
}
window.onload = loadScript;
The map appears twice because you're calling initialize twice.
Before fixing that, let's simplify your code a bit. Never let yourself repeat blocks of code like that; instead make it into a common function.
Also, don't load infobox.js from googlecode.com; Google Code is not a CDN. Load your own copy.
So, the code may look like this:
function addScript( url, callback ) {
var script = document.createElement( 'script' );
if( callback ) script.onload = callback;
script.type = 'text/javascript';
script.src = url;
document.body.appendChild( script );
}
function loadMapsAPI() {
addScript( 'https://maps.googleapis.com/maps/api/js?key=key_goes_here&sensor=false&callback=mapsApiReady' );
}
function mapsApiReady() {
addScript( 'infobox.js', initialize );
}
window.onload = loadMapsAPI;
I created this script. You can call this and add any callback function, so you have to just include this to your scripts and call
googleMapsLoadAsync(function(){ alert('google maps loaded'); });
script
var googleMapsAsyncLoaded = false;
var googleMapsAsyncCallback = function(){ };
function googleMapsLoadAsync(callback) {
if (typeof callback !== 'undefined') { googleMapsAsyncCallback=callback; }
if(!googleMapsAsyncLoaded) {
$.getScript('https://maps.googleapis.com/maps/api/js?sensor=false&async=2&callback=googleMapsAsyncLoadedFunction');
} else {
googleMapsAsyncLoadedFunction();
}
}
function googleMapsAsyncLoadedFunction() {
googleMapsAsyncLoaded = true;
if(googleMapsAsyncCallback && typeof(googleMapsAsyncCallback) === "function") {
googleMapsAsyncCallback();
}
googleMapsAsyncCallback = function(){ };
}
I have a code for a menu which is implemented for Click.
function DropDown(el) {
this.dd = el;
this.initEvents();
}
DropDown.prototype = {
initEvents : function() {
var obj = this;
var loc = window.location.pathname;
var filename = loc.match(/([^\/]+)(?=\.\w+$)/)[0];
console.log("sssss" + $(this).attr("id"));
obj.dd.on('click', function(event){
console.log($(this).attr("id"));
if(!($(this).hasClass("active")) && ( $(this).attr("id")) === filename) {
console.log("Hiding");
$(this).toggleClass('active');
event.stopPropagation();
}
});
}
}
$(function() {
var dd1 = new DropDown( $('#value') );
var dd2 = new DropDown( $('#diagnostics') );
var dd3 = new DropDown( $('#design') );
var dd4 = new DropDown( $('#delivery') );
//$('.wrapper-dropdown-5').on('click', function(e){ console.log(e); });
$(document).click(function() {
// all dropdowns
$('.wrapper-dropdown-5').removeClass('active');
});
});
If you see obj.dd.on('click', function(event){, that is where the click action is being intercepted. But I want to implement hover state, and to my surprise, it is not working, I tried using hover, mouseover and mouseout there, but nothing works. Only click is working.
Do you have any idea what might be the problem or how could I implement Hover in this scenario?
Thanks
I have a Dynamic table that I want to give color to on alternative rows. How can I achieve this with css? I need the code to work in IE7+
Look into using even/odd rules in CSS3.
Reference: https://developer.mozilla.org/en/CSS/:nth-child
For instance,
tr:nth-child(odd) will represent the CSS for every 2n + 1 child, whereas tr:nth-child(even) will represent the CSS for every 2n child.
i came across this same problem Friday, i used the jquery solution of
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
a stack overflow solution .js posted here
Detect changes in the DOM
so essentially you add the .js script in the head and fire the jquery rules on dom change.
My finished .js looked like this
<script type="text/javascript">
(function (window) {
var last = +new Date();
var delay = 100; // default delay
// Manage event queue
var stack = [];
function callback() {
var now = +new Date();
if (now - last > delay) {
for (var i = 0; i < stack.length; i++) {
stack[i]();
}
last = now;
}
}
// Public interface
var onDomChange = function (fn, newdelay) {
if (newdelay)
delay = newdelay;
stack.push(fn);
};
// Naive approach for compatibility
function naive() {
var last = document.getElementsByTagName('*');
var lastlen = last.length;
var timer = setTimeout(function check() {
// get current state of the document
var current = document.getElementsByTagName('*');
var len = current.length;
// if the length is different
// it's fairly obvious
if (len != lastlen) {
// just make sure the loop finishes early
last = [];
}
// go check every element in order
for (var i = 0; i < len; i++) {
if (current[i] !== last[i]) {
callback();
last = current;
lastlen = len;
break;
}
}
// over, and over, and over again
setTimeout(check, delay);
}, delay);
}
//
// Check for mutation events support
//
var support = {};
var el = document.documentElement;
var remain = 3;
// callback for the tests
function decide() {
if (support.DOMNodeInserted) {
window.addEventListener("DOMContentLoaded", function () {
if (support.DOMSubtreeModified) { // for FF 3+, Chrome
el.addEventListener('DOMSubtreeModified', callback, false);
} else { // for FF 2, Safari, Opera 9.6+
el.addEventListener('DOMNodeInserted', callback, false);
el.addEventListener('DOMNodeRemoved', callback, false);
}
}, false);
} else if (document.onpropertychange) { // for IE 5.5+
document.onpropertychange = callback;
} else { // fallback
naive();
}
}
// checks a particular event
function test(event) {
el.addEventListener(event, function fn() {
support[event] = true;
el.removeEventListener(event, fn, false);
if (--remain === 0) decide();
}, false);
}
// attach test events
if (window.addEventListener) {
test('DOMSubtreeModified');
test('DOMNodeInserted');
test('DOMNodeRemoved');
} else {
decide();
}
// do the dummy test
var dummy = document.createElement("div");
el.appendChild(dummy);
el.removeChild(dummy);
// expose
window.onDomChange = onDomChange;
})(window);
$(document).ready(function () {
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
onDomChange(function () {
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
});
});
</script>
I would like to caveat this answer that this probably is not the greatest solution but worked for what i needed it to do. :-)
CSS3 nth-child selector:
tr:nth-child(odd) {
background: red /* or whatever */;
}
You can use a CSS3 selector:
tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}
or jQuery:
$("tr:even").css("background-color", "#CCC");
$("tr:odd").css("background-color", "#FFF");
or do it on the server side.