I'm trying to make a range slider but it's working in single direction(to right) only and dragging out of parent container(#volume). How can I fix this?
I've attached a demo fiddle link.
Markup
<div id="volume">
<div class="progress">
<div class="volumeslider"></div>
</div>
</div>
CSS
#volume{
width:300px;
background: #ddd;
cursor:pointer;
}
.progress{
height:10px;
background:#999;
position:relative;
width:0;
}
.volumeslider {
background: #808080;
position: absolute;
width: 20px;
height: 20px;
border-radius: 15px;
right: -10px;
top: -5px;
}
JS
$('.volumeslider').bind('mousedown', function(e){
$('.volumeslider').bind('mousemove', function(e){
$('.progress').width(e.pageX - $('.progress').offset().left + 'px');
$(this).css('left', e.pageX - ($(this).width()/2) );
});
$('.volumeslider').bind('mouseup',function(){
$('.volumeslider').unbind('mousemove');
});
});
JS Fiddle:
http://jsfiddle.net/2mYm7/
You have not taken into consideration the padding you have given to the body element.
I have made some changes to the code.
$('.volumeslider').bind('mousedown', function (e) {
console.log('binded');
$('.volumeslider').bind('mouseup', function (e) {
console.log('unbinded');
$('.volumeslider').unbind('mousemove');
});
$('.volumeslider').bind('mousemove', function (e) {
console.log('mousemove');
$('.progress').width(e.pageX - $('.progress').offset().left + 'px');
$(this).css('left', e.pageX - 25- $(this).width());
});
});
Check this jsFiddle http://jsfiddle.net/2mYm7/1/
Here's an example of how to make it work always and everywhere. Right now it will stay dragging forever if you leave the element.
It includes border checks and makes sure the body is large enough so it stops dragging wherever on the page.
http://jsfiddle.net/2mYm7/5/
var dragging = null;
function startDrag(){
console.log('started dragging', this);
var $this = $(this);
dragging = $this;
$(document.body).bind('mouseup', stopDrag);
$(document.body).bind('mousemove', drag);
}
function stopDrag(){
console.log('stopped dragging', dragging[0]);
$(document.body).unbind('mouseup', stopDrag);
$(document.body).unbind('mousemove', drag);
dragging = null;
}
function drag(e){
var slider = dragging;
var progress = slider.parent();
var container = progress.parent();
var maxOffset = container.width();
progress.width(Math.min(e.pageX - progress.offset().left, maxOffset) + 'px');
}
$('.volumeslider').bind('mousedown', startDrag);
Related
I'm having an issue transforming my horizontal scroll logic into positional one. To summarize my problem; I have a div which has overflowing elements, which need to be scrollable, but not with scrollbars/overflow, but position:left. I had OK solutions, but it all went downhill after resetting on click.
The following snippet is where I was left stranded, when you click and drag the child, it should act the same as if you were horizontally scrolling.
Also, please note, I must use mousedown/mousemove/mouseup events so that I can port the logic over to touch
Thanks in advance!
var $scrollWithin = $('#child');
var clicked = false, clickX;
$(document).on({
'mousemove': function(e) {
clicked && updateScrollPos(e);
},
'mousedown': function(e) {
clicked = true;
clickX = e.pageX;
},
'mouseup': function() {
clicked = false;
}
});
var lastLeft = 0;
var updateScrollPos = function(e) {
var left = lastLeft + (clickX - e.pageX);
$scrollWithin.css('left', left + 'px');
lastLeft = left;
}
#child {
height:200px;
width:4000px;
background: linear-gradient(to right, rgba(169,3,41,1) 0%,rgba(0,80,255,1) 100%);
position:relative;
}
#parent {
width:300px;
overflow:hidden;
border:solid 4px #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent">
<div id="child"></div>
</div>
How to move or drag the span into the Div element. My element structure is the Div -> Span. Here I need to drag the Span inside the div element without drag beyond that div. I have tried this by calculating pixels but didn't give a solution. I don't need a native onDrag method.
I need to calculate pixels and drag the Span inside the Div. Here is my code.
var handleClick = false;
window.dragging = function(event) {
if (handleClick) {
var bar = document.getElementsByClassName('bar')[0],
handle = document.getElementsByClassName('handle')[0];
var left = bar.offsetWidth - handle.offsetWidth;
tops = (bar.offsetWidth - handle.offsetWidth);
pixel = left < ((pixel - 0) / 1.233445) ? left : ((pixel - 0) / 1.233445);
handle.style.left = pixel + "px";
}
}
document.addEventListener('mouseup', function() {
handleClick = false;
});
window.handlersDown = function() {
handleClick = true;
}
.bar {
width: 100px;
height: 30px;
border: 1px solid;
position: relative;
}
.handle {
width: 20px;
height: 20px;
left: 2px;
top: 5px;
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
}
<div class="bar">
<span class="handle" onmousedown="handlersDown()" onmousemove="dragging(event)"></span>
</div>
I have modified your code a bit and changed the selectors from class to ID. I also would advice you to use external libraries to make it more easy for you. Besides that I also removed the event listeners inside your HTML and translate them to Javascript. Is this what you want?
window.onload = addListeners();
function addListeners(){
document.getElementById('handle').addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
}
function mouseUp()
{
window.removeEventListener('mousemove', spanMove, true);
}
function mouseDown(e){
window.addEventListener('mousemove', spanMove, true);
}
function spanMove(e){
var bar = document.getElementById('bar')
var span = document.getElementById('handle');
// variables
var bar_width = bar.offsetWidth;
var handle_width = span.offsetWidth;
// stop scroll left if the minimum and maximum is reached
if(e.clientX < bar_width - handle_width - 1 && e.clientX > 1){
span.style.left = e.clientX + 'px';
}
}
#bar {
width: 100px;
height: 30px;
border: 1px solid;
position: relative;
}
#handle {
width: 20px;
height: 20px;
left: 2px;
top: 5px;
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
}
<div id="bar">
<span id="handle"></span>
</div>
In 2020, following solution works perfectly on last version of Chrome, Opera, Firefox and Edge Chromium.
window.onload = addListeners();
function addListeners()
{
var div = document.getElementById('div');
var span = document.getElementById('span');
span.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
//compute space between left border of <div> and left border of <span>
// this value is also used to compute space at right
iMinLeft = span.offsetLeft;
// compute max left value allowed so that span remains in <div>
iMaxLeft = div.clientWidth - span.offsetWidth - iMinLeft;
}
function onMouseDown(e)
{
if (e.which === 1) // left button is pressed
{
e.preventDefault();
window.addEventListener('mousemove', onMouseMove, true);
// save mouse X position to compute deplacement
posMouseX = e.clientX;
span.style.background = "yellow";
}
}
function onMouseMove(e)
{
e.preventDefault();
//compute mouse deplacement
deltaX = posMouseX - e.clientX;
//compute new left position of <span> element
iNewLeft = span.offsetLeft - deltaX;
if (iNewLeft < iMinLeft)
{
iNewLeft = iMinLeft;
}
else
{
if (iNewLeft > iMaxLeft)
{
iNewLeft = iMaxLeft;
}
}
span.style.left = iNewLeft + 'px';
// save mouse X position to compute NEXT deplacement
posMouseX = e.clientX;
}
function onMouseUp(e)
{
if (e.which === 1) // left button is pressed
{
e.preventDefault();
span.style.background = "white";
window.removeEventListener('mousemove', onMouseMove, true);
}
}
#div
{
width: 200px;
height: 50px;
border: 1px solid;
position: relative;
left: 50px;
}
#span
{
cursor: pointer;
font-size: 30px;
width: auto;
height: 40px;
left: 2px;
top: 5px;
position: absolute;
}
<div id="div">
<span id="span">😃</span>
</div>
JavaScript line e.preventDefault(); is necessary to avoid <span> to become 'blue' when dragging.
CSS code cursor: pointer; is only to see that unicode is clickable.
Javascript line if (e.which === 1) has been added to prevent emoticon to move when RIGHT mouse button is clicked.
The rectangle around emoticon when <span> is dragged move without being shifted (see previous solution) and space remaining in left or in right are equal.
Thanks to w3schools-exemple
Hi i have a div which is draggable .My requirement is
1. I want the start value and end value of the div after dragging in a text box
2.Now its is only drag in right side only i want it drag also from left side of the div
i tried some steps but it is not perfect because the value is not displaying and the dragging from left is not working middle table is my parent div
$(function () {
var container = $('.middletablediv'),
base = null,
handle = $('.handle'),
isResizing = false,
screenarea = screen.width;
handle.on('mousedown', function (e) {
base = $(this).closest(".scalebar");
isResizing = true;
lastDownX = e.clientX;
offset = $(this).offset();
xPos = offset.left;
});
$(document).on('mousemove', function (e) {
// we don't want to do anything if we aren't resizing.
if (!isResizing)
return;
p = parseInt(e.clientX - base.offset().left),
// l = parseInt(p * (3 / 11));
base.css('width', p);
k = parseInt(xPos - base.offset().left);
$("#startvalue").value(k)
$("#stopvalue").value(p)
}).on('mouseup', function (e) {
// stop resizing
isResizing = false;
});
});
.handle{
position: absolute;
top:1px;
right: 0;
width: 10px;
height: 5px;
cursor: w-resize;
}
.middletablediv{
float:left;
width:35%;
}
.scalebar{
margin-top: 13px;
height: 7px;
position: relative;
width:20px;
background-color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="middletablediv">
<div id="newvalue1" class="scalebar">
<div class="handle" style="left:0"></div> <div class="handle"></div>
</div>
</div>
<input id="startvalue" type="text">startvalue</input>
<input id="stopvalue" type="text" />stopvalue</input>
how i solve this issue
You should use val() instead of value(). Also, the way dragging works the end value can be smaller than the start value, so I added a couple of things to handle that problem in a simple way (just switch values). Finally, to drag from the left, you should handle the left dragging differently, so I gave the left handle a unique id and also padded the whole parent div a bit to make it more apparent.
$(function () {
var container = $('.middletablediv'),
base = null,
handle = $('.handle'),
isResizing = false,
isLeftDrag = false;
screenarea = screen.width;
handle.on('mousedown', function (e) {
base = $(this).closest(".scalebar");
isResizing = true;
if($(this).attr('id')=='lefthandle')isLeftDrag=true;
else isLeftDrag=false;
lastDownX = e.clientX;
offset = $(this).offset();
xPos = offset.left;
});
$(document).on('mousemove', function (e) {
// we don't want to do anything if we aren't resizing.
if (!isResizing)
return;
if(isLeftDrag){
p = parseInt(base.offset().left - e.clientX);
k = parseInt(base.offset().left - xPos);
base.css('margin-left',-p);
base.css('width',p);
}
else{
p = parseInt(e.clientX - base.offset().left),
// l = parseInt(p * (3 / 11));
base.css('width', p);
k = parseInt(xPos - base.offset().left);
}
//if(k>p){var temp = k; k = p; p = temp;}
$("#startvalue").val(k)
$("#stopvalue").val(p)
}).on('mouseup', function (e) {
// stop resizing
isResizing = false;
});
});
.handle{
position: absolute;
top:1px;
right: 0;
width: 10px;
height: 5px;
cursor: w-resize;
}
.middletablediv{
float:left;
width:35%;
}
.scalebar{
margin-top: 13px;
height: 7px;
position: relative;
width:20px;
background-color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="middletablediv" style="padding-left:100px; overflow:visible;">
<div id="newvalue1" class="scalebar">
<div class="handle"id="lefthandle" style="left:0"></div> <div class="handle"></div>
</div>
</div><br><br>
<input id="startvalue" type="text">startvalue</input>
<input id="stopvalue" type="text" />stopvalue</input>
Check out this fiddle, here I can drag and drop images on .drop-zone but I want to improve it such that if I drag image on it, the .drop-zone div expands to the position where I am putting the image. Scrollable would be fine.
<div class="drag"><img src="http://www.causingeffect.com/images/made/images/example/cow_50_50_c1.jpg" /></div>
<div class="drag"><img src="http://www.coffeecup.com/images/software/feature-icons/image_editing.png" /></div>
<div class="drag"><img src="http://www.neatimage.com/im/Neat-Image-Logo-64.png" /></div>
<div class="clear"></div>
<div class="drop-zone"></div>
JS
jQuery(function($) {
$('.drop-zone').droppable({
accept: '.drag',
drop: function(event, ui) {
var $clone = ui.helper.clone();
if (!$clone.is('.inside-drop-zone')) {
$(this).append($clone.addClass('inside-drop-zone').draggable({
containment: '.drop-zone'
}));
}
}
});
$('.drag').draggable({
helper: 'clone'
});
});
CSS
.drop-zone{border: 1px solid #9C9898;height:350px;width:400px;margin:0 auto;margin-top: 10px; overflow:auto;}
.clear{clear:both;}
You need some way to detect those edges. I'm using some child divs inside .drop-zone. Next problem is that you need .drop-zone to have position: relative and that messes up the drag/drop library. I applied the fix described here.
Next you find out that mouseover no longer propagates through the .drag element while dragging it, so you need to make sure .drop-zone-edge divs are above it, thus the custom z-index values. Try it out here.
Apply the same technique for top, left and right and make .drop-zone-edges transparent.
HTML:
<div class="drop-zone">
<div class="drop-zone-edge drop-zone-top"></div>
<div class="drop-zone-edge drop-zone-bottom"></div>
</div>
CSS:
.drag {
z-index: 100;
}
.drop-zone-edge {
width: 100%;
height: 10px;
background-color: red;
position: absolute;
z-index: 200;
}
.drop-zone-top {
top: 0;
}
.drop-zone-bottom {
bottom: 0;
}
JS:
var isDown = false;
$(document).mousedown(function() {
isDown = true;
})
.mouseup(function() {
isDown = false;
});
$('.drop-zone').droppable({
accept: '.drag',
drop: function(event, ui) {
var $clone = ui.helper.clone();
if (!$clone.is('.inside-drop-zone')) {
$(this).append($clone.addClass('inside-drop-zone').draggable({
containment: '.drop-zone'
}));
}
var parent = $('.drop-zone');
var leftAdjust = $clone.position().left - parent.offset().left;
var topAdjust = $clone.position().top - parent.offset().top;
$clone.css({left: leftAdjust, top: topAdjust});
}
});
$('.drag').draggable({
helper: 'clone'
});
var shouldEnlargeBottom = false;
$('.drop-zone-bottom').on('mouseover', function(e) {
if(isDown) {
shouldEnlargeBottom = true;
}
});
$('.drop-zone-bottom').on('mouseout', function(e) {
shouldEnlargeBottom = false;
});
function enlarge() {
if(shouldEnlargeBottom) {
var newHeight = $('.drop-zone').height() + 3;
$('.drop-zone').height(newHeight);
}
}
setInterval(enlarge, 100);
i have a function that creates an album and with jquery's post function and then it create the necessary HTML elements and append them to the document.
the problem is that the elements are a link and its target, while the link woks fine when i refresh the page it seems like the browser couldn't found the added target which was created with jquery.
how could i target an element with javascript that was created with either jquery or javascript.
thanx in advance.
EDIT:
the jsfiddle code
code:
btn = document.getElementById('add_album_btn');
btn.addEventListener('click', add_album_btn_func, false);
function add_album_btn_func(){
div = $('<div>').addClass('albums_div');
a = $('<a>').addClass('albums');
a.attr('onclick', 'return false;');
a.attr('onmousedown', 'autoScrollTo("new_section");').attr('href', '#');
a.append('★ New Album');
div.append(a);
section = $('<section>').attr('id', 'new_section');
header = $('<header>').addClass('inner_header');
header.append($('<h4>').append('New Album'));
inner_section = $('<section>').append($('<h5>').append('Images List :'));
footer = $('<footer>').addClass('inner_footer');
upload_btn = $('<a>').attr('id', 'new_section').addClass('upload_file ajax');
upload_btn.attr('href', 'some/link/');
upload_btn.append('Upload a file');
footer.append(upload_btn);
section.append(header);
header.after(inner_section);
inner_section.after(footer);
$('#wrap').append(div);
$('#separator').after(section);
}
var scrollY = 0;
var distance = 40;
var speed = 24;
function autoScrollTo(el){
var currentY = window.pageYOffset;
var targetY = document.getElementById(el).offsetTop;
var bodyHeight = document.body.offsetHeight;
var yPos = currentY + window.innerHeight;
var animator = setTimeout('autoScrollTo(\'' + el + '\')', speed);
if(yPos >= bodyHeight){
clearTimeout(animator);
}else{
if(currentY < targetY - distance){
scrollY = currentY + distance;
window.scroll(0, scrollY);
}else{
clearTimeout(animator);
}
}
}
EDIT:
apparently i wasn't clear enough what i want is the following:
i have this javascript code:
$(document).ready(function(){
$('.lightbox').click(function(){
$('.backdrop').animate({'opacity': '.50'}, 300, 'linear');
$('.box').animate({'opacity': '1.00'}, 300, 'linear');
$('.backdrop, .box').css('display', 'block');
});
$('.close').click(function(){
close_box();
});
$(".backdrop").click(function(){
close_box();
});
function close_box(){
$('.backdrop, .box').animate({'opacity': '.0'}, 300, 'linear', function(){
$('.backdrop, .box').css('display', 'none');
});
}
a = $('<a>').addClass('lightbox').attr('href', '#').append('<br>Click to Test.');
$('body').append(a);
});
the html:
<h1>jquery light-box</h1>
<a href=# class=lightbox>open lightbox</a>
<div class="backdrop"></div>
<div class="box"><div class="close">X</div>this is the light box</div>
the CSS:
body{
font-family: Helvetica, Arial;
}
.backdrop{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
opacity: .0;
z-index: 50;
display: none;
}
.box{
position: absolute;
top: 20%;
left: 30%;
width: 500px;
height: 300px;
background: #ffffff;
z-index: 51;
padding: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
-khtml-border-radius: 10px;
border-radius: 10px;
box-shadow: 0 0 5px #444444;
display: none;
}
.close{
float: right;
margin-right: 6px;
cursor: pointer;
}
the jsfiddle link
the problem when the second link is added with javascript it seems to be llike its invisible to the function.
any help thanx in advance.
NOTE: this lightbox code is from the PHPacademy tutorials.
NOTE: if you'r going to give the answer about re_writing the function and re-assign it to the new created element i already know that i need another way.
thanx in advance.
Try this:
$(".lightbox").live("click", function() {
$('.backdrop').animate({
'opacity': '.50'
}, 300, 'linear');
$('.box').animate({
'opacity': '1.00'
}, 300, 'linear');
$('.backdrop, .box').css('display', 'block');
});
DEMO HERE
UPDATE
Since the lightbox class element is added dynamically, you need to use event delegation to register the event handler like:-
// New way (jQuery 1.7+) - .on(events, selector, handler)
$(document.body).on('click', '.lightbox', function (e) {
e.preventDefault();
$('.backdrop').animate({
'opacity': '.50'
}, 300, 'linear');
$('.box').animate({
'opacity': '1.00'
}, 300, 'linear');
$('.backdrop, .box').css('display', 'block');
});
DEMO HERE
As far as I understand, you want to trigger the same lightbox animation when you click on "Click to Test." as when you click on "open lightbox"?
In that case, the .click() just bind the event handler to the CURRENT set of matched elements. What you are looking for is .on() or .delegate()
Fiddle
How about to target element in callback function of jQuery post?
In this callback function, append element to document first, then target it.