I have a navigation with mouseover and mouseout animations. They work. I also have a statement for the click listener that adds a CSS class. The class sets the height of a div, the issue is that the mouseout also alters this div. So I'm trying to figure out a way to disable the mouseout listener when the link is clicked.
I tried to unbind it with no luck
js
var currentDiv;
function slideMenu(e) {
if(e.type === "mouseover"){
// console.log("mouseover");
TweenMax.to($(this).find('div') , 0.25, {height:20});
}
else if(e.type === "mouseout"){
// console.log("mouseout");
TweenMax.to($(this).find('div') , 0.25, {height:1});
}
else if(e.type === "click"){
console.log("click");
if (currentDiv !== undefined){
$(currentDiv).removeClass("selected");
}
currentDiv = $(this).find('div');
$(currentDiv).addClass("selected");
$(currentDiv).unbind('mouseout'); // not working
}
}
$(".menu a").click(slideMenu);
$(".menu a").mouseover(slideMenu);
$(".menu a").mouseout(slideMenu);
css
.selected{
height: 20px;
}
Would this accomplish your goal? Instead of worrying about the binding of click events, you could just check the "selected" class before you do anything else within that click event. Like the following...
var currentDiv;
function slideMenu(e) {
if(e.type === "mouseover"){
// console.log("mouseover");
var child_div = $(this).find("div")
if (!$(child_div).hasClass("selected")) {
TweenMax.to($(this).find('div') , 0.25, {height:20});
} else {
$(child_div).attr("style", "") // remove inline styles attr, so that height is based on css instead of JS
}
}
else if(e.type === "mouseout"){
// console.log("mouseout");
var child_div = $(this).find("div")
if (!$(child_div).hasClass("selected")) { // check to see if selected/clicked on
TweenMax.to($(this).find('div') , 0.25, {height:1})
} else {
$(child_div).attr("style", "") // remove inline styles attr, so that height is based on css instead of JS
}
}
else if(e.type === "click"){
console.log("click", this);
if (currentDiv !== undefined){
$(currentDiv).removeClass("selected");
}
currentDiv = $(this).find('div');
$(currentDiv).addClass("selected");
}
}
$(".menu a").click(slideMenu);
$(".menu a").mouseover(slideMenu);
$(".menu a").mouseout(slideMenu);
If I'm understanding you correctly, you want the height of the element to remain the same size when you click on it and move the mouse off the element. You can try using
var currentDiv;
// add a state
var hasBeenClicked = false;
function slideMenu(e) {
if(e.type === "mouseover"){
TweenMax.to($(this).find('div') , 0.25, {height:20});
}
else if(e.type === "mouseout"){
// only resize if the element hasn't been clicked
if (!hasBeenClicked) {
TweenMax.to($(this).find('div') , 0.25, {height:1});
}
}
else if(e.type === "click"){
// assuming all this stuff is what you want and wasn't testing code
if (currentDiv !== undefined){
$(currentDiv).removeClass("selected");
}
currentDiv = $(this).find('div');
$(currentDiv).addClass("selected");
// set state to true
hasBeenClicked = true;
}
}
Note that this will only work for one element, if you plan to use this function for multiple elements you'll need to have a var hasBeenClicked set up for every element.
Related
I use jQuery UI to drag div elements. There is a div, it is draggable, when I drag with the left mouse button. I'd like to drag it with the right mouse button, too. So I want the item to be dragged with the left and the right mouse button. But only this div element, other elements are draggable only with left mouse button.
I modify the jQuery UI js file, like this:
$(document).ready(function () {
//override jQuery UI draggable
$.extend($.ui.draggable.prototype, {
_mouseDown: function (event) {
// we may have missed mouseup (out of window)
(this._mouseStarted && this._mouseUp(event));
this._mouseDownEvent = event;
var that = this,
btnIsLeft = (event.type === 'mousedown'),
// event.target.nodeName works around a bug in IE 8 with
// disabled inputs (#7620)
elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
return true;
}
this.mouseDelayMet = !this.options.delay;
if (!this.mouseDelayMet) {
this._mouseDelayTimer = setTimeout(function () {
that.mouseDelayMet = true;
}, this.options.delay);
}
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
this._mouseStarted = (this._mouseStart(event) !== false);
if (!this._mouseStarted) {
event.preventDefault();
return true;
}
}
// Click event may never have fired (Gecko & Opera)
if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
$.removeData(event.target, this.widgetName + ".preventClickEvent");
}
// these delegates are required to keep context
this._mouseMoveDelegate = function (event) {
return that._mouseMove(event);
};
this._mouseUpDelegate = function (event) {
return that._mouseUp(event);
};
$(document)
.bind("mousemove." + this.widgetName, this._mouseMoveDelegate)
.bind("mouseup." + this.widgetName, this._mouseUpDelegate);
event.preventDefault();
mouseHandled = true;
return true;
}
});
});
The change is here:
btnIsLeft = (event.type === 'mousedown'),
With this code my specific div element works fine, it works with the left and right mouse button, too, but other elements are draggable with both mouse button what I don't want.
My div element is this (I'd like to apply only this with the right and left draggable function):
$('.mydiv_with_right_and_left_drag').draggable({
scroll: false,
delay: 0,
distance: 0,
cursor: 'hand',
snap: false,
cursor: 'pointer',
stack: '.mydiv_with_right_and_left_drag',
containment: 'parent',
opacity: 0.35,
});
JSFIDDLE SOURCE
It can be workable somehow? Thanks.
Somehow I can't make the var "turn" change.
--------------'#a3' is a div-----------------
For all of the code go here.
Here is some of the js/jquery:
var turn = 1;
if (turn === 1) {
//----------------------------red
if (da3 === false) {
$('#a3').click(function () {
$(this).css("background-color", "red");
turn = 0;
});
}
if (turn === 0) {
//----------------------------blue
if (da3 === false) {
$('#a3').click(function () {
$(this).css("background-color", "blue");
turn = 1;
});
}
Here is some css I used:
div {
display: inline-block;
background-color:grey;
width : 150px;
height: 150px;
}
It is because you only add one event handler that only does one thing. It is not magically going to add the other one.
Do the if/else logic inside of the click events.
If you want to toggle the background-color by clicking the a3-element, you need to do the if/else checking inside of the event-handler:
bg_state = 0;
$('#a3').click(function () {
if (bg_state===0) {
$(this).css("background-color", "blue");
bg_state=1;
} else {
$(this).css("background-color", "red");
bg_state=0;
}
});
http://jsfiddle.net/ADUV9/
The setting of the event-handler is only executed one time, when the page loads!
Your current code is structured like this:
var turn = 1; // red turn first
if (turn === 1) {
// assign click handlers for red moves
}
if (turn === 0) {
// assign click handlers for blue moves
}
The problem with this is that the only click handlers that will ever be used here are the ones defined in the if (turn === 1) block. The code will not be re-evaluated when you modify turn so the click handlers for blue will never be used.
Instead it should look something like this:
var turn = 1; // red turn first
// example click handler:
$('#a3').click(function () {
// check whose turn it is *inside* of the click handler
if (turn === 0) {
$(this).css("background-color", "blue");
turn = 1;
} else {
$(this).css("background-color", "red");
turn = 0;
}
});
// other click handlers like the above (or better yet, reuse the same function)
I have a search suggestion div that appears when you keyUp an input. This works fine, but now I am trying to make keyboard shortcuts in action.
I want a behavior like when you click down keyboard arrow button a span gets selected and if it is selected then another span that is after gets selected, similarly, if you click up arrow an upward span gets selected, when you click enter then link opens.
I am stuck because I could not remove a:hover and could not add classes to it. Even after I have basically no idea how to do it. But I really tried hard and a lot..
Here is a jsfiddle link (type anything in field). maybe somebody will help me.
This code should go when the request is made and data is being returned:
<script type="text/javascript">
$(document).ready(function(){
total = 3;
$(".result-item").mouseenter(
function(){
hovered = $(this).attr("id");
total = 3;
$(".result-item").each(function(){
$(this).children("a").css({
'background-color':'#e4e4e4',
'color':'#000000'
});
$(this).find(".searchheading").css({
'color':'#191919'
});
$(this).find(".searchcaption").css({
'color':'#555555'
});
});
$(this).children("a").css({
'background-color':'#b7b7b7',
'color':'#ffffff'
});
$(this).find(".searchheading").css({
'color':'#ffffff'
});
$(this).find(".searchcaption").css({
'color':'#f1f1f1'
});
}
);
});
</script>
And this code on a page where request is made:
$("#suggestions").hide();
$("#search").bind('keyup', function(event){
if (event.which == 40 || event.which == 38 || event.which == 13) return false;
else
{
hovered = undefined;
lookup($(this).val());
}
});
$("#search").bind('keydown', 'down', function(evt){
if ($("#suggestions").is(":visible"))
{
if (typeof hovered == 'undefined')
{
$("#result-item-0").trigger("mouseenter");
return;
}
count = parseInt($("#"+hovered).attr("count"));
next = (count + 1);
if (next == total)
next = 0;
$("#result-item-"+next).trigger("mouseenter");
}
});
$("#search").bind('keydown', 'up', function(evt){
if ($("#suggestions").is(":visible"))
{
if (typeof hovered == 'undefined')
{
$("#result-item-"+(total-1)).trigger("mouseenter");
return;
}
count = parseInt($("#"+hovered).attr("count"));
prev = (count - 1);
if (prev == -1)
prev = (total-1);
$("#result-item-"+prev).trigger("mouseenter");
}
});
$("#search").bind('keydown', 'return', function(evt){
if ($("#suggestions").is(":visible"))
{
if (typeof hovered == 'undefined')
{
str = $("#search").val();
window.location.href = urlencode(str); // urlencode is a custom function
return false;
}
count = parseInt($("#"+hovered).attr("count"));
current = count;
$("#result-item-"+current).trigger("mouseenter");
$("#suggestions").fadeOut();
window.location.href = $("#"+hovered).children("a").attr("href");
}
});
})
;
Also I removed onkeyup="" attribute on element, this approach is nicer.
Now I have a webpage function that is trigger in the window everywhere exclude the restrictArea. I have make the restrictArea overlap the main content. How can I specific this area do not trigger the function? I tried e.preventDefault(); but it seems that does not work.
Thanks
$(document).swipe(function(){
...............
};
$('#flip').swiperight(function(e){
e.stopPropagation();
e.preventDefault();
});
Update: all the revelant code:
css:
*
{
-webkit-user-select: none; /* disable auto selection (select/selectall when long tap)*/
-webkit-touch-callout: none; /* disable magnifier*/
}
#flip
{
position:absolute;
background-color:red;
z-index:10;
height: 100%;
width:60%;
left:20%;
}
js:
$(document).swipeleft(function(){
//check the case when popup and thumbnail slide bar is not exist
if ($("#popup").length == '0' && parseInt($('#all_pages').css('left')) != '0'){
if (checkOrientation (orientation)== 'landscape'){
var pageLand = $('#book').turn('view');
pageLand = pageLand[1];
if (pageLand + 1 < countImage && pageLand != '0')
$('#book').turn('page', pageLand + 1);
}
else{
var pagePort = $('#book').turn('page');
if (pagePort + 1 < countImage && pagePort != '0')
$('#book').turn('page', pagePort + 1);
}
}
});
$(document).swiperight(function(){
//check the case when popup and thumbnail slide bar is not exist
if ($("#popup").length == '0' && parseInt($('#all_pages').css('left')) != '0'){
if (checkOrientation (orientation)== 'landscape'){
var pageLand = $('#book').turn('view');
pageLand = pageLand[0];
if (pageLand - 1 > 0)
$('#book').turn('page', pageLand - 1);
}
else{
var pagePort = $('#book').turn('page');
if (pagePort - 1 > 0)
$('#book').turn('page', pagePort - 1);
}
}
});
$('#flip').swiperight(function(e){
alert ('test');
e.stopPropagation();
e.preventDefault();
});
$('#flip').swipeleft(function(e){
alert ('test');
e.stopPropagation();
e.preventDefault();
});
Try the following code. You need to stop the bubbling of the event from the child node to the parent document.
$('#restrictArea').swipe(function(e){
e.stopPropagation();
e.preventDefault();
});
Instead of $(document) can't you bind .swipe on some DIV (which might be height/width 100%)? Then you simply make #restrictArea with a higher z-index than the DIV and you should be fine.
Also, in your code, you try to do preventDefault, but the variable e is not defined/passed in your function.
In your code you don't have your function closed properly:
$(document).swipe(function(){
...............
});
//^-----------you missed out this
$('#restrictArea').swipe(function(e){
//---------------^-----------you missed out this
e.preventDefault();
});
//-^---------------------------------this too
jQuery doesn't have a .swipe handler but jQuery mobile has so your code should be like this:
$(document).bind("pageinit", function(event, data) {
$('#restrictArea').swipe(function(e) {
e.preventDefault();
});
});
Say I have Div1 and Div2. I want to make that when a user is dragging around Div1, Div2 should also drag along. Any ideas how do I make it?
Here's what I got so far...
$(document).ready(function() {
$("#apDiv1").draggable();
$("#apDiv2").draggable(); //<- how do I link it do Div1 ?
});
EDIT ------------------------------------------------------------------
Thanks, I looked into the docs and got so far:
<script>
$(document).ready(function() {
$("#apDiv1").draggable();
});
$( "#apDiv1" ).bind( "drag", function(event, ui) {
$( "#apDiv2" ).css({ top: event.offsetY, left: event.offsetX });
</script>
Seems to be right, but... hmm, isn't' working. any ideas?
have a look at http://docs.jquery.com/UI/Draggable#event-drag to see how to bind to a draggable event. Bind the draggable event of div1 to a function that changes the coordinates of div2
Cheers.
Regarding your edit I've made some changes that can be viewed here http://jsfiddle.net/9FrXr/2/
You weren't closing the "drag" bind and instead of event.offsetY and event.offsetX I've used ui.offset.top and ui.offset.x. The drag bind has also been moved into the document.ready function.
$("#apDiv1").bind( "drag", function(event, ui) {
div.css({ top: ui.offset.top + 52, left: ui.offset.left });
});
// JavaScript Document
//This is an easy draggable javascript frameworkt
//There is no license for it so you can modify it how ever you like
//Coding started: 2011-05-28 and finished 2011-05-09
//The code can contain bugs. I only use an array to store the ID:s of the draggables
//Create an array for the draggers// I am not using an class because it is not nesesery for this easy thing
/////////////////////////////////////////////////////////////////////////////////////////////////////////
var Elements=new Array('draggable2','draggable3','draggable4','draggable5','draggable6','draggable7','draggable8','draggable9','draggable10');
//Set ID wher to do select disabeled
var textDisabling="body";
//Set drag TAG exeption//
var dragException=new Array('input','SPAN');
//////////////////////////////////////Start the framework
document.onmousemove=drag;
document.onmousedown=mouseDown;
document.onmouseup=mouseUp;
var parent;
//Offset vars//
var offsetY,offsetX;
//Setup the timeout event holder here//
var timeout=null;
//Set a var that will hold the dragged object//
var ObjectDrag;
//Set boolean vars to elerate//
var clickStage=true;
var XPos, YPos;//<--Setting up the position vars//
//////////////////////////////////////
//Get the browser name for your own needs//
//////////////////////////////////////
function getBrowserName(){
var Navigator=navigator.userAgent;
if(Navigator.indexOf("MSIE")>=0){
Navigator="MSIE";
}else if(Navigator.indexOf("Netscape")>=0){
Navigator="Netscape";
}else if(Navigator.indexOf("Firefox")>=0){
Navigator="Firefox";
}else if(Navigator.indexOf("Opera")>=0){
Navigator="Opera";
}else if(Navigator.indexOf("Safari")>=0){
Navigator="Safari";
}else{
Navigator="NULL";
}//IF
return Navigator;
}//Function
//END//
/////////////////////////////////////
//Get browser version to your neads//
/////////////////////////////////////
function getBrowserVersion(){
var browserName=getBrowserName(),
findIndex,
browserVersion;
browserVersion=navigator.userAgent;
findIndex=browserVersion.indexOf(browserName) + browserName.length+1;
browserVersion=parseFloat(browserVersion.substr(findIndex,findIndex + 3));
return browserVersion;
}//Function
//END//
function getMousePos(event){
var event=event || window.event;
//Get the position of the mouse with an offset of the top page
//////////////////////////////////////////////////////////////
if(event.pageX && event.pageY){
//We get the mouse position in newer browsers//
XPos=event.pageX;
YPos=event.pageY;
}else{
//We gat the same value as abow, but this is for older browsers//
XPos=event.clientX + document.body.scrollLeft - document.body.clientLeft;
YPos=event.clientY + document.body.scrollTop - document.body.clientTop;
}
//This is only for debugging the mouse position//
document.getElementById('X').value=XPos;/////////
document.getElementById('Y').value=YPos;/////////
return {XPos:XPos, YPos:YPos};
}
//Function for disabling text selections//
function disableTextSelection(event){
var event=event || window.event;
var object;
if(getBrowserName() != "MSIE"){object=event.target;}else{object=event.srcElement;}
if (typeof document.getElementById(textDisabling).onselectstart!="undefined"){ //IE route
document.getElementById(textDisabling).onselectstart=function(){return false}
object.onselectstart=function(){return false}
}else if (typeof document.getElementById(textDisabling).style.MozUserSelect!="undefined"){ //Firefox route
document.getElementById(textDisabling).style.MozUserSelect="none"
object.style.MozUserSelect="none"
}else{ //All other route (ie: Opera)
document.getElementById(textDisabling).onmousedown=function(){return false}
object.onmousestart=function(){return false}
}
}
//Allow text selection funtion. Call this when you do muse up//
function allowTextSelection(){
if (typeof document.getElementById(textDisabling).onselectstart!="undefined"){ //IE route
document.getElementById(textDisabling).onselectstart=function(){return true}
ObjectDrag.onselectstart=function(){return true}
}else if (typeof document.getElementById(textDisabling).style.MozUserSelect!="undefined"){ //Firefox route
document.getElementById(textDisabling).style.MozUserSelect="text"
ObjectDrag.style.MozUserSelect="text"
}else{ //All other route (ie: Opera)
document.getElementById(textDisabling).onmousedown=function(){return true}
ObjectDrag.onmousestart=function(){return true}
}
}
//Setup the global function that we will start from//
function drag(event){
var mousePos=getMousePos(event);
}
//Make an exception function //
function exception(event){
if(getBrowserName() != "MSIE"){
for(items in dragException){if(event.target.nodeName == dragException[items].toUpperCase())return {contin:false};}
}else{
for(items in dragException){if(event.srcElement.nodeName == dragException[items].toUpperCase())return {contin:false};}
}
return true;
}
//This function checks if you are pulling the click inside the element
function isInside(event){
var event=event || window.event;
var object;
if(getBrowserName() != "MSIE"){object=event.target;}else{object=event.srcElement;}
if(object.nodeName=="HTML")return false;
parent=object;
var i,l=0;
for(i=0;i<=l;i++){
if(parent.nodeName != "BODY"){
for(items in Elements){
if(Elements[items] == parent.id){
return {contin:true, id:parent};
}
}
parent=parent.parentNode;
l++;
}else{
return false;
}
}
}
//Here we get the offset position so the element will follow the mouse where you
//did (mouseDown) event. If we noe capturing the offset, the element will lie line to line with the
//mouse. NO OFFSET
function offsetObject(YPos,XPos){
offsetY=YPos-ObjectDrag.offsetTop;
offsetX=XPos-ObjectDrag.offsetLeft;
return false;
}
//Set the objects on a good z-index//
function setZIndex(event){
var event=event || window.event;
var object;
if(getBrowserName() != "MSIE"){object=event.target;}else{object=event.srcElement;}
for(items in Elements){
document.getElementById(Elements[items]).style.zIndex="1";
}
object.style.zIndex="20";
}
//Capture mouse down//
function mouseDown(event){
var event=event || window.event;
/*if(getBrowserName() != "MSIE"){ */
timeout=null;
clickStage=true;
//Store the event if it´s not null and can be dragged//
var inside=isInside(event);
if(inside.contin == true && exception(event) == true){
/*Function that disables the text selection on drag*/
disableTextSelection(event);
ObjectDrag=inside.id;
offsetObject(YPos,XPos);
//Set the z-indexes//
setZIndex(event);
moveObject();
}
/*}else{
alert("Browser is not suported");
}*/
}
//Start moving the object//
function moveObject(){
//Stor the mouse event in this var//
if(clickStage == true)timeout=setTimeout(moveObject,0);
//Change it back to true if the mouseUp event has not trigged//
clickStage=true;
//Store the event if it´s not null and can be dragged//
if(clickStage==true){
//This is the place where we set the position of the element
document.getElementById(ObjectDrag.id).style.left=XPos-offsetX+"px";
document.getElementById(ObjectDrag.id).style.top=YPos-offsetY+"px";
}
}
//Capture mouse up//
function mouseUp(event){
var event=event || window.event;
if(exception(event) == true ){
allowTextSelection();
timeout=null;
clickStage=false;
}
}
Thanks again, got it fully working on the webpage. You can see it in action by moving the menu around at www[dot]skyeye[dot]cc .
<script>
$(function() {
$("#apDiv3").draggable();
$("#apDiv3").bind("drag", function(event, masterdrag) {
$("#apDiv5").css({ top: masterdrag.offset.top, left: masterdrag.offset.left-20 });
});
});
</script>