jQueryUI draggable element inside iframe - bad behavior with scrolled iframes - javascript

I am experiencing troubles while having a draggable div inside an (scrolled) iframe. Please have look at this fiddle: http://jsfiddle.net/CqE43/
This is the used code:
$('#test').contents().find('body').append('<div id="wrapper" style="width: 300px; height: 900px; background: #ff0000; display: block; margin-top:50px;"><div id="drag" style="width: 100px; height: 100px; background-color: blue;" ></div></div>');
$('#test').contents().find('#drag').draggable({
iframeFix: true,
start: function( event, ui ) {
console.log('start');
},
drag: function( event, ui ) {
console.log('drag');
},
stop: function( event, ui ) {
console.log('stop');
}
});
The strange behavior is: if the iframe is not scrolled everything works like expected but if one scrolls the iframe a bit, an offset appears while dragging.

Ok, I've got a (not the but a) solution.
Here is the fiddle: http://jsfiddle.net/CqE43/17/
and this is the source code:
$(function () {
$('#test').contents().find('body').append('<div id="wrapper" style="width: 300px; height: 900px; background: #ff0000; display: block; margin-top:50px;"><div id="drag" style="width: 100px; height: 100px; background-color: blue;" ></div></div>');
var myDraggable = $('#test').contents().find('#drag').draggable({iframeFix: true}).data('ui-draggable');
myDraggable._mouseDrag = function(event, noPropagation) {
if ( this.offsetParentCssPosition === "fixed" ) {
this.offset.parent = this._getParentOffset();
}
//Compute the helpers position
this.position = this._generatePosition(event);
this.positionAbs = this._convertPositionTo("absolute");
//Call plugins and callbacks and use the resulting position if something is returned
if (!noPropagation) {
var ui = this._uiHash();
if(this._trigger("drag", event, ui) === false) {
this._mouseUp({});
return false;
}
this.position = ui.position;
}
if(!this.options.axis || this.options.axis !== "y") {
this.helper[0].style.left = this.position.left+"px";
}
if(!this.options.axis || this.options.axis !== "x") {
this.helper[0].style.top = $('#test').contents().find('body').scrollTop()+this.position.top+"px";
}
if($.ui.ddmanager) {
$.ui.ddmanager.drag(this, event);
}
return false;
}
});
Yes, it is not beautiful ubt it does work quite well!

Related

jQuery flip plugin switch function fails on switch

I have a piece of code where I have two buttons and when I press one button I want a div to flip on the y-axis and when I press the other button I want the same div to flip on the x-axis. this works just fine when I use the button for the y-axis even if the previous flip was on the x-axis. But when I want to switch from the y-axis to the x-axis I need to press the x button twice because the first time nothing happens.
So desired behavior is:
click y button flip the div on the y-axis.
click x button flip the div on the x-axis.
current behavior is:
click y button div flips on the y-axis.
click x button nothing happens
click x button again div flips on the x-axis.
I have no idea what the problem is, this is the best i got so far.
All help is appreciated.
var ax = 'x';
$(document).ready(function() {
$('#card').flip({
trigger: 'manual',
axis: 'x'
});
$('#left').click(function() {
if (ax != 'y') {
$("#card").flip({
axis: 'y'
});
$("#card").on('flip:change', function() {
$('#card').flip('toggle');
});
ax = 'y';
} else {
$("#card").flip('toggle');
}
});
$('#right').click(function() {
if (ax != 'x') {
$("#card").flip({
axis: 'x'
});
$("#card").on('flip:change', function() {
$('#card').flip('toggle');
});
ax = 'x';
} else {
$("#card").flip('toggle');
}
});
});
#card {
position: fixed;
left: 50px;
top: 50px;
width: 200px;
height: 200px;
}
.front {
width: 100%;
height: 100%;
background-color: red;
}
.back {
width: 100%;
height: 100%;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<button id="left">y</button>
<button id="right">x</button>
<div id="card">
<div class="front">Front content</div>
<div class="back">Back content</div>
</div>
You over-complicated the problem. Here is a solution inspired by the documentation. All you have to do is to call flip to change the axis on click on he buttons, and to listen on flip:change event which is fired every time you call flip to change the orientation in order to actually flip it.
// Configure it to be manually flipped
$("#card").flip({
trigger: 'manual'
});
// Change the axis
$('#left').click(function() {
$("#card").flip({
axis: 'y'
});
});
$('#right').click(function() {
$("#card").flip({
axis: 'x'
});
});
// Toggle it on change
$("#card").on('flip:change', function() {
$('#card').flip('toggle');
});
#card {
position: fixed;
left: 50px;
top: 50px;
width: 200px;
height: 200px;
}
.front {
width: 100%;
height: 100%;
background-color: red;
}
.back {
width: 100%;
height: 100%;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<button id="left">y</button>
<button id="right">x</button>
<div id="card">
<div class="front">Front content</div>
<div class="back">Back content</div>
</div>
Here you go with a solution
var ax = 'x';
$(document).ready(function() {
$('#card').flip({
trigger: 'manual',
axis: 'x'
});
$("#card").on('flip:change', function() {
$('#card').flip('toggle');
});
$('#left').click(function() {
if (ax != 'y') {
$("#card").flip({
axis: 'y'
});
ax = 'y';
} else {
$("#card").flip('toggle');
}
});
$('#right').click(function() {
if (ax != 'x') {
$("#card").flip({
axis: 'x'
});
ax = 'x';
} else {
$("#card").flip('toggle');
}
});
});
#card {
position: fixed;
left: 50px;
top: 50px;
width: 200px;
height: 200px;
}
.front {
width: 100%;
height: 100%;
background-color: red;
}
.back {
width: 100%;
height: 100%;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<button id="left">y</button>
<button id="right">x</button>
<div id="card">
<div class="front">Front content</div>
<div class="back">Back content</div>
</div>
You should keep the flip:change outside the click event.
Hope this will help you.
You ended up binding the flip:change event multiple times with each click. That caused x to flip twice when clicked after Y was clicked twice. Hence it looks like nothing is happening.
You can see that happening when adding a debugger; at the start of $('#right').click(function() { and using the console to debug your code.
Anyway, adding the event binding ones only fixes it as that is all you need.
Removing all instance of $("#card").on('flip:change', function() { in your code and only adding it one time, fixes the problem.
In this example I added it at the bottom of your code.
var ax = 'y';
$(document).ready(function() {
$('#card').flip({
trigger: 'manual',
axis: 'y'
});
$('#left').click(function() {
//debugger;
if (ax != 'y') {
$("#card").flip({
axis: 'y'
});
ax = 'y';
} else {
$("#card").flip('toggle');
}
});
$('#right').click(function() {
//debugger;
if (ax != 'x') {
$("#card").flip({
axis: 'x'
});
ax = 'x';
} else {
$("#card").flip('toggle');
}
});
// Only bind ones.
$("#card").on('flip:change', function() {
$('#card').flip('toggle');
});
});
#card {
position: fixed;
left: 50px;
top: 50px;
width: 200px;
height: 200px;
}
.front {
width: 100%;
height: 100%;
background-color: red;
}
.back {
width: 100%;
height: 100%;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<button id="left">y</button>
<button id="right">x</button>
<div id="card">
<div class="front">Front content</div>
<div class="back">Back content</div>
</div>

Creating links for page transitions

I'm writing a single page website. It has 3 'slides' like About/Music/Contact. The access to these slides is created with a dropdown menu. When you click the link in menu, the current page wrapper go visibility: hidden and through animation the following becomes visible. This works quite well, but everything happens on the root page, without changing the URL, which isn't user-friendly as if you want to share the link to the page you will always be redirected to the root.
So the question is: "How to make the url change without reloading the page (maybe through hash or smth) on the click?". Thanks in advance.
P.S. No code needed, just give me your way to make this, and I will add it into the code.
Just check with this and take it if you want this
function isElementInViewport (el) {
//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
// click-to-scroll behavior
$("a").click(function (e) {
e.preventDefault();
var section = this.href;
var sectionClean = section.substring(section.indexOf("#"));
$("html, body").animate({
scrollTop: $(sectionClean).offset().top
}, 1000, function () {
window.location.hash = sectionClean;
});
});
// listen for the scroll event
$(document).on("scroll", function() {
//console.log("onscroll event fired...");
// check if the anchor elements are visible
$(".common").each(function (idx, el) {
if ( isElementInViewport(el) ) {
// update the URL hash
if (window.history.pushState) {
var urlHash = "#" + $(el).attr("id");
window.history.pushState(null, null, urlHash);
}
}
});
});
body {
float: left;
width: 100%;
padding-bottom: 0px;
}
.common {
width: 100%;
float: left;
height: 100vh;
display: table;
}
.allbody {
float: left;
width: 100%;
}
a {
display: inline-block;
padding: 15px;
}
header {
float: left;
width: 100%;
position: fixed;
top: 0;
left: 0;
background: #fff;
}
.common h2 {
font-size: 30px;
color: #fff;
text-align: center;
padding-top: 10%;
display: table-cell;
vertical-align: middle;
}
#firstDestination {
background: #000;
}
#secondDestination {
background: #999;
}
#thirdDestination {
background: #ccc;
}
#fourthDestination {
background: #c1c1c1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<header>
first page
<a href="#secondDestination" >second page</a>
third page
fourth page
</header>
<div class="allbody">
<div class="common" id="firstDestination" ><h2>First Page</h2></div>
<div class="common" id="secondDestination"><h2>Second Page</h2></div>
<div class="common" id="thirdDestination" ><h2>Third Page</h2></div>
<div class="common" id="fourthDestination" ><h2>Fourth Page</h2></div>
</div>

after scrolling, detect when element returns to original position

I am trying to, sort of, emulate the effect here. Essentially, during scrolling, change the css (drop shadow), and when the element comes back to original position (remove shadow).
I am able to detect scroll, but not able to figure out how to detect the return to the original un-scrolled state.
HTML
<div id="container">
<ul>
<li id="one">el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li><li>el</li>
</ul>
</div>
CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#container {
height: 100px;
width: 500px;
border: 1px solid #000000;
overflow: scroll;
}
JS (with jquery)
var p = $('#one');
var position0 = p.position().top;
$('#container').scroll(function () {
if (p.position().top != position0) {
console.log('p.position: ' + p.position().top);
$('#container').css('background-color', 'pink');
}
});
JSFIDDLE: http://jsfiddle.net/nrao89m3/
PS: From console.log it doesn't seem to return to its original value at all.
Just add an else block:
var p = $('#one');
var position0 = p.position().top;
$('#container').scroll(function () {
if (p.position().top != position0) {
console.log('p.position: ' + p.position().top);
$('#container').css('background-color', 'pink');
} else {
$('#container').css('background-color', 'white');
}
});
http://jsfiddle.net/vyjbwne2/

How to Animate (slide) content adjacent to content with jquery toggle()

I am setting up a page which the user can hide the side bar if they wish. I am trying to use the jqeuryui to do this with the following js code
// TOGGLE JS
$(function () {
function runEffect() {
var options = {};
$("#effect").toggle('slide', options, 500);
};
$("#button").click(function () {
runEffect();
return false;
});
});
I have this working in a JSFiddle here http://jsfiddle.net/jwg4U/
However, when you look at the JSFiddle you will notice that my main content area which is a DIV called #content does not animate, it just jumps into place when I toggle the sidebar.
I would like the content div to also slide into place seamlessly and follow the toggle as it if it attached to it.
I have looked at jquery animate, but not sure how to implement this with the slide?
A Second part I am struggling with is how to change the button text when the sidebar is closed to say "Show Sidebar" - Weather it is open or closed right now it just says "Hide Sidebar"
Looking for some help
Thanks
See this updated fiddle : http://jsfiddle.net/jwg4U/23/
HTML:
<div id="container" style="width:800px">
<div id="header">
<h1>HEADER</h1>
</div>
<div class="toggler">
<div id="effect" class="ui-widget-content ui-corner-all">
<div id="menu" style="background-color:#FFD700;height:300px;width:100px;float:left;">
<h3>SIDEBAR</h3>
</div>
</div>
<div id="content" style="background-color:#EEEEEE;height:300px;">Main Content goes here</div>
</div>
Hide Sidebar
<div id="footer" style="background-color:#FFA500;clear:both;text-align:center;">
FOOTER</div>
</div>
​
JS:
// TOGGLE JS
$(function() {
var i = 0;
function runEffect() {
var options = {};
if (i === 0) {
i = 1;
$(".toggler").animate({
left: -100
}, {
duration: 500
});
}
else {
i = 0;
$(".toggler").animate({
left: 0
}, {
duration: 500
});
}
}
$("#button").click(function() {
if (i === 0) {
$(this).html("Show Sidebar");
}
else {
$(this).html("Hide Sidebar");
}
runEffect();
return false;
});
});
// TABS JS
$(function() {
$("#tabs").tabs();
});​
CSS:
.toggler {
float: left;
position: relative;
}
#button {
padding: .5em 1em;
text-decoration: none;
}
#effect {
position: relative;
float: left;
}
#content{
position: relative;
float: left;
width: 500px;
}
#button{
float: left;
clear: both;
}
#header{
background-color: #000;
color: #FFF;
}​
The jsfiddle for the complete answer : http://jsfiddle.net/jwg4U/22/
$('#effect').animate({
width: 'toggle',
height: 'toggle'
}, {
duration: 500,
specialEasing: {
width: 'linear',
height: 'linear'
},
complete: function() {
$("#content").animate(
{ left: '+=100px' },
60,
'easeInQuad',
function ()
{
if(isOpen)
{
isOpen=false;
$("#button").html('Show Sidebar');
}
else
{
isOpen=true;
$("#button").html('Hide Sidebar');
}
});
}
});

jQuery :: live hover problem

An example jsfiddle is here. Try to hover the red square and then hover the blue one. Why is it flickering? How can I prevent the blue square to disappear?
(This is actually a tab and it's ex icon, that appear only when hovered)
JavaScript:
$("#foo").live("mouseover mouseout", function(e) {
if (e.type == "mouseover") {
$("#foo").append("<div id='bar'>");
} else {
$("#bar").remove();
}
});
CSS:
#foo {
width: 100px;
height: 50px;
background: red;
}
#bar {
width: 10px;
height: 10px;
background: blue;
}
Thanks
Not sure what you intent todo, but is it what you're looking for: http://jsfiddle.net/PXExS/4/
$("#foo").live("mouseenter mouseleave", function(e) {
if (e.type == "mouseenter") {
$("#foo").append("<div id='bar'>");
} else {
$("#bar").remove();
}
});
You can achieve the same thing by doing
$("#foo").live("hover", function(e) {
$("#bar").toggle();
});
Check working example at http://jsfiddle.net/PXExS/9/

Categories

Resources