The following code is working fine, but I'm looking for a way to animate/interpolate between the two creating a slide effect. How can I achieve this?
(I need to have the odd click function as is probably because of how the rest of the site works, otherwise I would have used the jqueryUI slide function)
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-' + boxwidth + 'px');
var oddClick = $(this).data("oddClick");
$(this).data("oddClick", !oddClick);
if (oddClick) {
$(".box").css('margin-left', ('-' + boxwidth + 'px'));
}
});
Related
Hello everyone this is my first question so I might have done it wrong.
What I am trying to achieve is is have multiple <aside> elements all with the same ID Class and of course Tag be able to be moved anywhere on the screen with drag and drop characteristics. I have found a JSFiddle demonstrating the code I am basing this around that uses one aside element with the ability to be moved anywhere, but will not work when multiple elements are used. The code controlling the movement is here:
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain",
(parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' +
(parseInt(style.getPropertyValue("top"),10) - event.clientY));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementById('dragme');
dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';
event.preventDefault();
return false;
}
var dm = document.getElementById('dragme');
dm.addEventListener('dragstart',drag_start,false);
document.body.addEventListener('dragover',drag_over,false);
document.body.addEventListener('drop',drop,false);
The part I am having trouble with is the drop system which requires the elements to have individual ids. I also need to have all aside elements have to same id and I don't want to use classes. I have tried and thought and searched the web for the past three days with no luck of finding an answer as all link back to this same code. I have looked into getting the index of the last element clicked but cannot find a way to get all elements with the same ID. Thanks in advanced - bybb
Update: Have broken the dnd system need help with that:
var dragindex = 0;
$(document).ready(function(){
$("aside").click(function(){
dragindex = $(this).index();
});
});
function drag_start(event) {
var style = window.getComputedStyle(event.target, null);
event.dataTransfer.setData("text/plain",
(parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
}
function drag_over(event) {
event.preventDefault();
return false;
}
function drop(event) {
var offset = event.dataTransfer.getData("text/plain").split(',');
var dm = document.getElementById('#winborder');
dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';
event.preventDefault();
return false;
}
function makewindow(content, storevar) {
storevar = document.createElement('aside');
storevar.setAttribute("dragable", "true");
storevar.setAttribute("id", "winborder");
var content = document.createElement('div');
content.setAttribute("id", "wincontent");
storevar.appendChild(content);
document.body.appendChild(storevar);
storevar.addEventListener('dragstart',drag_start,false);
document.body.addEventListener('dragover',drag_over,false);
document.body.addEventListener('drop',drop,false);
}
Have tried with and without '#' on getelementbyid
The following code will allow drag and drop; I'm sorry it doesn't follow your previous coding style.
Here is a JSFiddle showing it in action: https://jsfiddle.net/6gq7u8Lc/
document.getElementById("dragme").onmousedown = function(e) {
this.prevX = e.clientX;
this.prevY = e.clientY;
this.mouseDown = true;
}
document.getElementById("dragme").onmousemove = function(e) {
if(this.mouseDown) {
this.style.left = (Number(this.style.left.substring(0, this.style.left.length-2)) + (e.clientX - this.prevX)) + "px";
this.style.top = (Number(this.style.top.substring(0, this.style.top.length-2)) + (e.clientY - this.prevY)) + "px";
}
this.prevX = e.clientX;
this.prevY = e.clientY;
}
document.getElementById("dragme").onmouseup = function() {
this.mouseDown = false;
}
On a side note, you won't be able to give them all the same id. The DOM doesn't support such a thing. If you want to add multiple elements of the same type, I would suggest a 'container' parent div, adding the elements as children of the div, and iterating through the .children attribute to access each.
Don't know if you want to use Jquery or not, but I know it's way simpler than the raw javascript solution. I've been searching the internet and Stack Overflow for a simple drag-and-drop anywhere on a web page solution, but I couldn't find one that worked. The other answers to this question have been weird for me. They sometimes work, sometimes don't. However, a friend suggested using the Jquery version, and wow, it's so much simpler. Just one line of code!
var dragme = document.getElementsByClassName("dragme");
for (var i = 0; i < dragme.length; i++) {
$(dragme[i]).draggable();
}
.dragme {
cursor: move;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<h1 class="dragme">Try dragging me anywhere on this sample!</h1>
<h2 class="dragme">Drag me, too!</h2>
IMPORTANT NOTE: This code does not work with just Jquery, it also requires the Jquery UI file.
If the above sample does not work for you, please comment the error it show below. Note that this works for an unlimited amount of elements. This specific example is for elements with the class "dragme", so just replace that with your own class. For one element, it is a single line of code: $("#yourid").draggable();.
This code works for me on Google Chrome. Hope this helps anyone coming on to this page late, like me!
How do you get this result in css, javascript or jquery, or a combination of all:
I asked and posted a similar question before, but no one answered it.
Someone said:
"Maybe you can use javascript (or bether JQuery) for this.
If you use JQuery, you can use the scroll event. If you are scrolling, do a
check if it hits the other div. https://api.jquery.com/scroll/
Checking the positions of the divs is possible with offset/position.
http://api.jquery.com/offset/ https://api.jquery.com/position/
If you want to change the background, you give the div a background color
that is pink. If it hits then you can add an additional background-image
that has a specific background-position
(http://www.w3schools.com/cssref/pr_background-position.asp xpos ypos).
I don't have tried it yet, but I guess it is possible that way."
So my question is, how would you go about doing it to get this result or regardless of what way?
I came up with this after a couple of hours trying to make it work. It was pretty fun doing it, so I'm sharing it.
$(document).ready(function() {
var initScrollTop = $(window).scrollTop();
$('.div1').css('top', (initScrollTop+100)+"px");
$(window).scroll(function () {
var top = parseInt($('.div1').css('top').split("px")[0]);
// I GIVE A FIXED TOP TO .DIV1
var scrollTop = $(this).scrollTop() + 100;
$('.div1').css('top', scrollTop+"px");
// GETTING SOME VALUES
// DIV1
var div2Top = parseInt($('.div2').css('top').split('px')[0]);
var div2Height = parseInt($('.div2').css('height').split('px')[0]);
var div2Bottom = parseInt($('.div2').css('bottom').split('px')[0]);
// DIV2
var div1Width = parseInt($('.div1').css('width').split('px')[0]);
var div1Height = parseInt($('.div1').css('height').split('px')[0]);
var div1Top = parseInt($('.div1').css('top').split('px')[0]);
var div1Bottom = parseInt($('.div1').css('bottom').split('px')[0]);
var div1Left = parseInt($('.div1').css('left').split('px')[0]);
// WE ARE GOING THROUGH THE GREEN BOX
if(scrollTop + div1Height > div2Top) {
// OUTSIDE OF THE GREEN BOX (.div2)
if(scrollTop + div1Height > div2Height + div2Top) {
var div3Height = div2Top + div2Height - scrollTop;
$('.div3').css('top', scrollTop+ "px")
// .css('bottom', div2Bottom + "px")
.css('width', div1Width + "px")
.css('height', div3Height + "px")
.css('visibility','visible');
console.log("I'm out");
}
// INSIDE OF THE GREEN BOX (.div2)
else {
var div3Height = (div1Top > div2Top) ? div1Height : scrollTop + div1Height - div2Top;
var div3Top = (div1Top > div2Top) ? div1Top : div2Top;
$('.div3').css({
'top' : div3Top + "px",
'left': div1Left + "px",
'width': div1Width + "px",
'height': div3Height + "px",
'visibility':'visible'
});
}
} else {
$('.div3').css('visibility','hidden');
}
// WE ARE ABSOLUTELY OUT OF THE GREEN BOX (FROM THE BOTTOM GOING DOWN)
if(scrollTop > div2Top + div2Height) {
$('.div3').css('visibility','hidden');
}
});
});
Here's there a fiddle so you can test it http://jsfiddle.net/5076h670/2/
So basically what it does is create three divs, two of them will be visible and 'collide' between each other, the other one starts hidden and it shows only when the position of the div1 is in the range of the div2. This div3 (the third div) will be shown over the div1 (see the z-index). When it's absolutely out of the box div3 will be hidden.
I don't know what else to explain about the code, I don't know if (and I don't think, it took me a while to make it work) it's understandable what it does. If you have something to ask I'll be reading ;)
Hope it helps
I am trying to use video.js which is awesome, and it uses a custom icon font for the interface.
However I need a few more icons, we already use font-awesome on our site, so thought it would be great if we could just use those icons, and since the video.js already uses a custom icon font I thought it should be easy.
So, I added a custom button:
vjs.QuickClip = vjs.Button.extend({
/** #constructor */
init: function (player, options) {
vjs.Button.call(this, player, options);
}
});
vjs.QuickClip.prototype.buttonText = 'Quick Clip';
vjs.QuickClip.prototype.buildCSSClass = function () {
return 'vjs-quickclip-control ' + vjs.Button.prototype.buildCSSClass.call(this);
};
vjs.QuickClip.prototype.onClick = function () {
var offset = 10;
var time = this.player_.currentTime();
var clipStart = time < 10 ? 0 : time - 10;
var clipEnd = time + offset > this.player_.duration() ? this.player_.duration() : time + offset;
console.log('Clipped at ' + time + ' so from ' + clipStart + ' to ' + clipEnd);
};
and tried replacing vjs-quickclip-control with icon icon-crop which partially works.
The little highlighted button is the output.
So, this obviously didn't work, so now I am wondering, how can I do this?
I tried to create a JS fiddle but it doesn't seem to load properly...
Ah, got it,
for my new links I use
.vjs-default-skin .vjs-control.vjs-quickclip-control:before {
font-family: FontAwesome;
content:"\f125";
}
I've seen this so many times on the internet. People say to don't repeat yourself in programming languages. I wrote this script for my webpage but I repeated myself quite a bit.
Is it really that big of a deal?
Should I make a function?
How do I do it?
var active = '.teachers';
var disabled = '.teacher-link';
var width = $('.teachers .staff-outer-container').children().size() * 180;
$('.staff-outer-container').css('width', width + 'px');
$('.teacher-link').click(function() {
if (active != '.teachers') {
$(active).hide();
active = '.teachers';
$(active).show();
width = $('.teachers .staff-outer-container').children().size() * 180;
$('.teachers .staff-outer-container').css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text('Teachers');
}
});
$('.admin-link').click(function() {
if (active != '.administrators') {
$(active).hide();
active = '.administrators';
$(active).show();
width = $('.administrators .staff-outer-container').children().size() * 180;
$('.administrators .staff-outer-container').css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text('Administrators');
}
});
$('.support-link').click(function() {
if (active != '.support') {
$(active).hide();
active = '.support';
$(active).show();
width = $('.support .staff-outer-container').children().size() * 180;
$('.support .staff-outer-container').css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text('Support Staff');
}
});
edit
Thanks for everyone's input! I'm confused on how to implement these functions. This is what I got: $('.teacher-link').click(handle_click('.teachers', 'Teachers')); I tried this out and it didn't work.
Also where do I place the function? Do I place it inside or outside $(document).ready ? Is it best to put functions at the start or the end of my script?
You could build a function like this, and call it like:
handle_click('.teachers', 'Teachers');
handle_click('.adminstrators', 'Administrators');
etc.
Function:
function handle_click(target, target_text) {
if (active != target) {
$(active).hide();
active = target;
$(active).show();
width = $(target + ' .staff-outer-container').children().size() * 180;
$(target + ' .staff-outer-container').css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text(target_text);
}
}
"Is it such a big deal"?
It is NOT a big deal as long as everything works ok.
It is a big deal if something breaks down or you have to change/add some features.
It is NOT a big deal if it's a small piece of code which you handle all by yourself
It is a big deal if someone else needs to work with your code and it will be extended in the future.
Personaly I think that if you are hours after deadline and stuff needs to be published ASAP, you can keep messy and redundant code - but only if it is refactored afterwards. The problem is that, probably, once the code is published no one will look and refactor it, unless it get's broken or generates bugs.
Look at your code - what if someone decides that a new feature would be generating dynamic objects and handling them with those functions, using loops and stuff?
With your code this is impossible and after all you'll need to make it automatic. So why not make it correct in the first place? I think that making the code automatic will cost muuuuuch less time than fixing it if something bad happens.
function switchActive(tag,name)
{
if (active != tag) {
$(active).hide();
active = tag;
$(active).show();
width = $(tag+' .staff-outer-container').children().size() * 180;
$(tag+' .staff-outer-container').css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text(name);
}
}
$('.teacher-link').click(function(){switchActive('.teacher','Teachers');});
$('.admin-link').click(function(){switchActive('.administrators','Administrators');});
$('.suppport-link').click(function(){switchActive('.support','Support Staff');});
That's one of the basics of sotware engineering. If a task has to be made twice, it has to be automatized. There you got a pattern that can be put in a function, or a class method, depending on the context of usage. I can give you an example of such a function, but that wouldn't be a good example, without having a thorough thought of that in the execution context.
function link_click(linkClass, targetClass, text) {
$(linkClass).click(function() {
if (active != targetClass) {
$(active).hide();
active = targetClass;
$(active).show();
width = $(linkClass + ' .staff-outer-container').children().size() * 180;
$(linkClass + ' .staff-outer-container').css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text(text);
}
});
There are so many different ways to do it (as you can see in the different answers over here), and I'm pretty sure none of them is totally a fit for your usage. You may prefer to make a class that has one or more methods for that purpose, so you can make different ways to execute your function, or create a new event or something else I don't think of now...
Take a break, look overall at your code, what you would need for potential future improvements so the stuff you write today don't get in the way tomorrow.
You are doing well. However you can improve that your code be more productivity and reusability. It is not good solution but it will help you for some idea.
<script>
$(function(){
$('.tab-link').click(function() {
if($(this).hasClass("active") == false) {
var target = $( $(this).attr("href") );
$(".tab-section").hide();
target.show();
$(".tab-link").removeClass("active").addClass("clickable");
$(this).removeClass("clickable").addClass("active");
var container = target.find("staff-outer-container");
var width = container.children().size() * 180;
container.css("width", width + "px");
$("#type").text($(this).html());
}
});
});
</script>
<a class="tab-link" href="#staff-teacher">Teachers</a>
<a class="tab-link" href="#staff-admin">Administrators</a>
<a class="tab-link" href="#staff-support">Support Staff</a>
<h1 id="type">Teachers</h1>
<div id="staff-teacher" class="tab-section">
<div class="staff-outer-container">
#Teacher List
</div>
</div>
<div id="staff-admin" class="tab-section">
<div class="staff-outer-container">
#Admin List
</div>
</div>
<div id="staff-support" class="tab-section">
<div class="staff-outer-container">
#Staff List
</div>
</div>
You could write something like this, fully extensible:
(only defined active,disabled variables so this actually works in jsfiddle)
jsfiddle: http://jsfiddle.net/8RaXv/2/
var active=document.getElementById('active'),
disabled=document.getElementById('disabled'),
teacher = {
$link: $('.teacher-link'),
selector: '.teachers',
text: 'Teachers'
},admin = {
$link: $('.admin-link'),
selector: '.administrators',
text: 'Administrators'
},support = {
$link: $('.support-link'),
selector: '.support',
text: 'Support Staff'
};
bindHandler([teacher, admin, support]);
//bind handlers
function bindHandler(items) {
for (var i in items) {
items[i].$link.on('click', items[i], clickHandler);
}
}
//generic handler
function clickHandler(event) {
var context = event.data;
if (active !== context.selector) {
$(active).hide();
active = context.selector;
$(active).show();
var $container = $(context.selector + ' .staff-outer-container');
width = $container.children().size() * 180;
$container.css('width', width + 'px');
$(disabled).removeClass('active').addClass('clickable');
disabled = this;
$(disabled).removeClass('clickable').addClass('active');
$('#type').text(context.text);
}
}
I am looking for some native JavaScript, or jQuery plugin, that meets the following specification.
Sequentially moves over a set of images (ul/li)
Continuous movement, not paging
Appears infinite, seamlessly restarts at beginning
Ability to pause on hover
Requires no or minimal additional plugins
I realize this sounds simple enough. But I have looked over the web and tried Cycle and jCarousel/Lite with no luck. I feel like one should exist and wanted to pose the question before writing my own.
Any direction is appreciated. Thanks.
you should check out Nivo Slider, I think with the right configuration you can it to do what you want.
You can do that with the jQuery roundabout plugin.
http://fredhq.com/projects/roundabout/
It might require another plugin.
Both answers by MoDFoX and GSto are good. Usually I would use one of these, but these plugins didn't meet the all the requirements. In the end this was pretty basic, so I just wrote my own. I have included the JavaScript below. Essentially it clones an element on the page, presumably a ul and appends it to the parent container. This in effect allows for continuous scrolling, right to left, by moving the element left and then appending it once out of view. Of course you may need to tweak this code depending on your CSS.
// global to store interval reference
var slider_interval = null;
var slider_width = 0;
var overflow = 0;
prepare_slider = function() {
var container = $('.sliderGallery');
if (container.length == 0) {
// no gallery
return false;
}
// add hover event to pause slider
container.hover(function() {clearInterval(slider_interval);}, function() {slider_interval = setInterval("slideleft()", 30);});
// set container styles since we are absolutely positioning elements
var ul = container.children('ul');
container.css('height', ul.outerHeight(true) + 'px');
container.css('overflow', 'hidden')
// set width and overflow of slider
slider_width = ul.width();
overflow = -1 * (slider_width + 10);
// set first slider attributes
ul.attr('id', 'slider1');
ul.css({"position": "absolute", "left": 0, "top": 0});
// clone second slider
var ul_copy = ul.clone();
// set second slider attributes
ul.attr('id', 'slider2');
ul_copy.css("left", slider_width + "px");
container.append(ul_copy);
// start time interval
slider_interval = setInterval("slideleft()", 30);
}
function slideleft() {
var copyspeed = 1;
var slider1 = $('#slider1');
var slider2 = $('#slider2');
slider1_position = parseInt(slider1.css('left'));
slider2_position = parseInt(slider2.css('left'));
// cross fade the sliders
if (slider1_position > overflow) {
slider1.css("left", (slider1_position - copyspeed) + "px");
}
else {
slider1.css("left", (slider2_position + slider_width) + "px");
}
if (slider2_position > overflow) {
slider2.css("left", (slider2_position - copyspeed) + "px");
}
else {
slider2.css("left", (slider1_position + slider_width) + "px");
}
}