I would like to detect a click outside of the menu class .tab-nav-menu, on the rest of the window and add an event to close the menu with similar animation of closing.
// Menu
jQuery(function($) {
$('.header-menu-toggle').on('click', function(e){
e.preventDefault();
$('.tab-nav-menu >ul >li').animate({
opacity: 0
}, 200).animate({
bottom: '-25px'
}, 50);
if($('.tab-nav-menu').hasClass('tab-invisible') ){
$('.tab-nav-menu').css({'right':'-1em'});
$('.tab-nav-menu').removeClass('tab-invisible').addClass('tab-visible');
$(this).find('.burg').addClass('activeBurg');
}
else{
$('.tab-nav-menu').css({'right':'-100%'});
$('.tab-nav-menu').removeClass('tab-visible').addClass('tab-invisible');
$(this).find('.burg').removeClass('activeBurg');
}
var delay = 600;
var duration = 400;
if( $(".header-navigation-menu").hasClass("strip-header-menu") ){
delay = 250;
}
$('.tab-nav-menu >ul >li').each(function(){
$(this).delay(delay).animate({
opacity: 1,
bottom: 0,
}, duration);
delay += 150;
});
})
});
Thanks for your help
A simplified "on outside click" jQuery script:
$(document).ready(function () {
$(document).on('click', function (e) {
var clickedEl = $(e.target);
var outsideClicker = $('#clicker');
if ( !(clickedEl.is(outsideClicker)
|| outsideClicker.has(clickedEl).length > 0) ) { // I flipped this so you can just omit the else
console.log('I clicked outside the target!'); // do whatever you need to do here-- maybe call a function that closes the menu...
} else {
console.log('all good'); // if you don't have an else just get rid of this
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1> A title </h1>
<p> A paragraph and a <b id="clicker">thing <span>to</span> click </b></p>
</div>
You can extrapolate this for your purposes.
I am attaching a scroll event listener to a wrapper div, and then for each div with the class of "js-chart" it will check to see if that particular js-chart is within view and will execute a function on it. It will then remove the js-chart class from that element so that it won't keep on firing the function.
This all works fine, but what I'd like to do is that when all of the js-charts have been triggered (and thus there are no more elements with js-chart, to completely remove the scroll event listener so I'm not firing off pointless checks all the time.
$('#wrapper').scroll(function() {
var $wrapper = $(this);
$('.js-chart').each( function (n) {
var $this = $(this);
if ( $this.position().top + $this.height() > 100 && $this.position().top < $wrapper.height() ) {
console.log("Test");
createChart($this);
$this.removeClass('js-chart');
}
});
});
Add something like this:
$('#wrapper').on("scroll", function() {
var $wrapper = $(this);
$('.js-chart').each( function (n) {
var $this = $(this);
if ( $this.position().top + $this.height() > 100 && $this.position().top < $wrapper.height() ) {
console.log("Test");
createChart($this);
$this.removeClass('js-chart');
}
});
if (!$('.js-chart').length) {
$wrapper.off("scroll");
}
});
I think you can do so:
$('#wrapper').on("scroll", function() {
var $wrapper = $(this);
$('.js-chart').each( function (n) {
var $this = $(this);
if ( $this.position().top + $this.height() > 100 && $this.position().top < $wrapper.height() ) {
console.log("Test");
createChart($this);
$this.removeClass('js-chart');
}
});
if (!$(".js-chart")[0]) $wrapper.off("scroll");
});
i have 3 divs with scrollbars.
If i scroll in div 1 i want to scroll div 2 and 3 in the opposite direction.
The distance scrolled should be half the distance of div 1.
This is what i have now (small part, rest is in jsfiddle), which works for 1 div.
$("#textBox1").scroll(function () {
console.log("scroll 1");
var offset = $("#textBox1").scrollTop() - scrollPosTBox1;
var half_offset = offset/2.0;
disable1 = true;
if(disable2 == false) {
$("#textBox2").scrollTop(scrollPosTBox2 - half_offset);
}
if(disable3 == false) {
$("#textBox3").scrollTop(scrollPosTBox3 - half_offset);
}
disable1 = false;
});
However, if i try to get the same for the other 2 divs then i can't scroll anything anymore.
This is because div 1 triggers div 2 and div 2 triggers back to div 1 for example.
I tried to fix this with the disable code but it doesn't help.
Can someone help me?
http://jsfiddle.net/XmYh5/1/
No disrespect to #EmreErkan and #Simon for their effort. Here's a no-click version of this.
var $boxes = $("#textBox1,#textBox2,#textBox3"),
active;
$boxes.scrollTop(150);
// set initial scrollTop values
updateScrollPos();
// bind mouseenter:
// 1) find which panel is active
// 2) update scrollTop values
$boxes.mouseenter(function () {
active = this.id;
updateScrollPos();
});
// bind scroll for all boxes
$boxes.scroll(function (e) {
$this = $(this);
// check to see if we are dealing with the active box
// if true then set scrolltop of other boxes relative to the active box
if(this.id == active){
var $others = $boxes.not($this),
offset = $this.scrollTop()-$this.data("scroll"),
half_offset = offset / 2;
$others.each(function(){
$this = $(this);
$this.scrollTop($this.data("scroll") - half_offset);
});
}
});
// utility function:
// assign scrollTop values element's data attributes (data-scroll)
function updateScrollPos() {
$boxes.each(function(){
$this = $(this);
$this.data("scroll",$this.scrollTop());
});
}
Fiddle
You can use a variable to determine active textbox with .mousedown() and do the trick if it's active;
var activeScroll = '';
$("#textBox1").on('mousedown focus mouseenter', function () {
activeScroll = 'scroll1';
}).scroll(function () {
if (activeScroll == 'scroll1') {
console.log("scroll 1");
var offset = $("#textBox1").scrollTop() - scrollPosTBox1;
var half_offset = offset / 2.0;
$("#textBox2").scrollTop(scrollPosTBox2 - half_offset);
$("#textBox3").scrollTop(scrollPosTBox3 - half_offset);
}
});
You can check your updated jsFiddle here.
Finally got a dynamic solution for this, was more complex than I thought but I think I got it:
http://jsfiddle.net/XmYh5/14/
var initialTop = 150,
factor = 2;
$(".textBox")
.addClass('disabled')
.scrollTop(initialTop)
.on('scroll', function () {
var $this = $(this);
if(!$this.is('.disabled')) {
this.lastOffset = this.lastOffset || initialTop;
var offset = $this.scrollTop(),
step = (offset - this.lastOffset) / factor;
$this.siblings().each( function() {
var $this = $(this),
offset = $this.scrollTop() - step;
$this.scrollTop(offset);
this.lastOffset = offset;
});
this.lastOffset = offset;
}
})
.on('mouseenter', function() {
$(this).removeClass('disabled').siblings().addClass('disabled');
});
I have 3 pictures cropped by span.main{overflow:hidden}. User can pan the span with touch events and explore the hidden parts of the picture.
Code so far:
document.addEventListener('DOMContentLoaded', function() {
var box = document.querySelector('.main');
box.addEventListener("touchstart", onStart, false);
box.addEventListener("touchmove", onMove, false);
box.addEventListener("touchend", onEnd, false);
});
var startOffsetX, startOffsetY;
var moving = false;
function getPos(ev) {
return {
x: ev.touches ? ev.touches[0].clientX : ev.clientX,
y: ev.touches ? ev.touches[0].clientY : ev.clientY
};
}
function onStart(ev) {
moving = true;
var box = document.querySelector('.main');// I need something like $(this)
var pos = getPos(ev);
startOffsetX = pos.x + box.scrollLeft;
startOffsetY = pos.y + box.scrollTop;
if (ev.preventDefault)
ev.preventDefault();
else
ev.returnValue = false;
}
function onMove(ev) {
if (moving) {
var pos = getPos(ev);
var x = startOffsetX - pos.x;
var y = startOffsetY - pos.y;
var box = document.querySelector('.main'); // I need something like $(this)
box.scrollLeft = x;
box.scrollTop = y;
if (ev.preventDefault)
ev.preventDefault();
else
ev.returnValue = false;
}
}
function onEnd(ev) {
if (moving) {
moving = false;
}
}
The problem is that only the first thumbnail works as expected. I've tried:
-querySelector only returns the first element so if I add ID's and querySelector('#box1,#box2,#box3') should work. Nein. I thing I have a 'this' problem on the functions...
-Place events (as Apple suggests) inline <div class="box" onStart="ontouchstartCallback( ev);" ontouchend="onEnd( ev );"ontouchmove="onMove( ev );" > <img></div> looked like a solution yet...My guess, because of 'this' again...
You want to use the querySelectorAll method instead. It returns all matched elements in the subtree instead of only the first one (which is what querySelector does). Then loop through them using a for loop.
var elements = document.querySelectorAll('.main');
for (var i = 0, ii = elements.length; i < ii; ++i) {
var element = elements[i];
element.ontouchstart = onStart;
// ...
}
The other approach you can take (and it is probably a better one) is to use event delegation and set the event listeners on a parent element and decide which of the pictures is being manipulated by checking the target property of each event.
<div id="pictures">
<span class="main"><img /></span>
<span class="main"><img /></span>
<span class="main"><img /></span>
</div>
var parent = document.getElementById('pictures');
parent.ontouchstart = function (e) {
var box = e.target.parentNode; // parentNode because e.target is an Image
if (box.className !== 'main') return;
onStart(e, box);
};
I'm a web designer with css experience, but I'm not a JS developer.
I used jqtransform to style a search form ,
the problem is it removes all events from selectors and the search button .
here is the code before jqtransform
<input id="go-search" type="button" name="btn_search" value="search" onclick="searchLocations()" />
and after applying the script, the button doesn't do any thing
I opened the page source and here how it looks like:
<button class=" jqTransformButton" type="button" name="btn_search" id="go-search"><span><span>search</span></span></button>
Please help me !
I think it’s best to put new questions in new posts …
$(function() { $("form.jqtransform").jqTransform(); $("#city").click(populateDestrict); });
when assigning functions to an event by JavaScript, you only assign the function reference. putting parentheses behind a function identifyer will execute the function.
function myFunction(x)
{
alert(x);
return 1;
}
// correct, the onload event will trigger the function
window.onload = myFunction;
// alerts "[object Event]"
// wrong
window.onload = myFunction("hello");
// this assigns "1" to the onload property*
// * - IE may execute this, but no standard compliant browser
As far as can see only buttons are affected. The script replaces your original buttons with new ones, so everything besides the id, name, type & class attributes is removed. You would have to assign the function anew when jqtransform finished its job.
// after jqtransform
// probably $("#go-search").click(searchLocations); in jQuery, but I’m not a jQuery user … thus in plain JavaScript:
var bt = document.getElementById("go-search");
if (window.addEventListener) {
bt.addEventListener("click", searchLocations, false);
}
else {
bt.attachEvent("onclick", searchLocations);
}
I would hazard a guess at using it like
$(function() {
//find all form with class jqtransform and apply the plugin
$("form.jqtransform").jqTransform();
// fix your button
$("#go-search").click(searchLocations);
});
May be late but... Faced the same issue recently. and the solution was to use this version of the jqTransform script:
NOTE: 1) Open your jqTransform file, 2)DELETE everything, 3)COPY the code bellow 4) PASTE and 5) SAVE.
VOILA!!
/*
*
* jqTransform
* by mathieu vilaplana mvilaplana#dfc-e.com
* Designer ghyslain armand garmand#dfc-e.com
*
*
* Version 1.0 25.09.08
* Version 1.1 06.08.09
* Add event click on Checkbox and Radio
* Auto calculate the size of a select element
* Can now, disabled the elements
* Correct bug in ff if click on select (overflow=hidden)
* No need any more preloading !!
*
******************************************** */
(function($){
var defaultOptions = {preloadImg:true};
var jqTransformImgPreloaded = false;
var jqTransformPreloadHoverFocusImg = function(strImgUrl) {
//guillemets to remove for ie
strImgUrl = strImgUrl.replace(/^url\((.*)\)/,'$1').replace(/^\"(.*)\"$/,'$1');
var imgHover = new Image();
imgHover.src = strImgUrl.replace(/\.([a-zA-Z]*)$/,'-hover.$1');
var imgFocus = new Image();
imgFocus.src = strImgUrl.replace(/\.([a-zA-Z]*)$/,'-focus.$1');
};
/***************************
Labels
***************************/
var jqTransformGetLabel = function(objfield){
var selfForm = $(objfield.get(0).form);
var oLabel = objfield.next();
if(!oLabel.is('label')) {
oLabel = objfield.prev();
if(oLabel.is('label')){
var inputname = objfield.attr('id');
if(inputname){
oLabel = selfForm.find('label[for="'+inputname+'"]');
}
}
}
if(oLabel.is('label')){return oLabel.css('cursor','pointer');}
return false;
};
/* Hide all open selects */
var jqTransformHideSelect = function(oTarget){
var ulVisible = $('.jqTransformSelectWrapper ul:visible');
ulVisible.each(function(){
var oSelect = $(this).parents(".jqTransformSelectWrapper:first").find("select").get(0);
//do not hide if click on the label object associated to the select
if( !(oTarget && oSelect.oLabel && oSelect.oLabel.get(0) == oTarget.get(0)) ){$(this).hide();}
});
};
/* Check for an external click */
var jqTransformCheckExternalClick = function(event) {
if ($(event.target).parents('.jqTransformSelectWrapper').length === 0) { jqTransformHideSelect($(event.target)); }
};
/* Apply document listener */
var jqTransformAddDocumentListener = function (){
$(document).mousedown(jqTransformCheckExternalClick);
};
/* Add a new handler for the reset action */
var jqTransformReset = function(f){
var sel;
$('.jqTransformSelectWrapper select', f).each(function(){sel = (this.selectedIndex<0) ? 0 : this.selectedIndex; $('ul', $(this).parent()).each(function(){$('a:eq('+ sel +')', this).click();});});
$('a.jqTransformCheckbox, a.jqTransformRadio', f).removeClass('jqTransformChecked');
$('input:checkbox, input:radio', f).each(function(){if(this.checked){$('a', $(this).parent()).addClass('jqTransformChecked');}});
};
/***************************
Buttons
***************************/
$.fn.jqTransInputButton = function(){
return this.each(function(){
var newBtn = $('<button id="'+ this.id +'" name="'+ this.name +'" type="'+ this.type +'" class="'+ this.className +' jqTransformButton"><span><span>'+ $(this).attr('value') +'</span></span>')
.hover(function(){newBtn.addClass('jqTransformButton_hover');},function(){newBtn.removeClass('jqTransformButton_hover')})
.mousedown(function(){newBtn.addClass('jqTransformButton_click')})
.mouseup(function(){newBtn.removeClass('jqTransformButton_click')})
;
$(this).replaceWith(newBtn);
});
};
/***************************
Text Fields
***************************/
$.fn.jqTransInputText = function(){
return this.each(function(){
var $input = $(this);
if($input.hasClass('jqtranformdone') || !$input.is('input')) {return;}
$input.addClass('jqtranformdone');
var oLabel = jqTransformGetLabel($(this));
oLabel && oLabel.bind('click',function(){$input.focus();});
var inputSize=$input.width();
if($input.attr('size')){
inputSize = $input.attr('size')*10;
$input.css('width',inputSize);
}
$input.addClass("jqTransformInput").wrap('<div class="jqTransformInputWrapper"><div class="jqTransformInputInner"><div></div></div></div>');
var $wrapper = $input.parent().parent().parent();
$wrapper.css("width", inputSize+10);
$input
.focus(function(){$wrapper.addClass("jqTransformInputWrapper_focus");})
.blur(function(){$wrapper.removeClass("jqTransformInputWrapper_focus");})
.hover(function(){$wrapper.addClass("jqTransformInputWrapper_hover");},function(){$wrapper.removeClass("jqTransformInputWrapper_hover");})
;
/* If this is safari we need to add an extra class */
$.browser.safari && $wrapper.addClass('jqTransformSafari');
$.browser.safari && $input.css('width',$wrapper.width()+16);
this.wrapper = $wrapper;
});
};
/***************************
Check Boxes
***************************/
$.fn.jqTransCheckBox = function(){
return this.each(function(){
if($(this).hasClass('jqTransformHidden')) {return;}
var $input = $(this);
var inputSelf = this;
//set the click on the label
var oLabel=jqTransformGetLabel($input);
oLabel && oLabel.click(function(){aLink.trigger('click');});
var aLink = $('');
//wrap and add the link
$input.addClass('jqTransformHidden').wrap('<span class="jqTransformCheckboxWrapper"></span>').parent().prepend(aLink);
//on change, change the class of the link
$input.change(function(){
this.checked && aLink.addClass('jqTransformChecked') || aLink.removeClass('jqTransformChecked');
return true;
});
// Click Handler, trigger the click and change event on the input
aLink.click(function(){
//do nothing if the original input is disabled
if($input.attr('disabled')){return false;}
//trigger the envents on the input object
$input.trigger('click').trigger("change");
return false;
});
// set the default state
this.checked && aLink.addClass('jqTransformChecked');
});
};
/***************************
Radio Buttons
***************************/
$.fn.jqTransRadio = function(){
return this.each(function(){
if($(this).hasClass('jqTransformHidden')) {return;}
var $input = $(this);
var inputSelf = this;
oLabel = jqTransformGetLabel($input);
oLabel && oLabel.click(function(){aLink.trigger('click');});
var aLink = $('');
$input.addClass('jqTransformHidden').wrap('<span class="jqTransformRadioWrapper"></span>').parent().prepend(aLink);
$input.change(function(){
inputSelf.checked && aLink.addClass('jqTransformChecked') || aLink.removeClass('jqTransformChecked');
return true;
});
// Click Handler
aLink.click(function(){
if($input.attr('disabled')){return false;}
$input.trigger('click').trigger('change');
// uncheck all others of same name input radio elements
$('input[name="'+$input.attr('name')+'"]',inputSelf.form).not($input).each(function(){
$(this).attr('type')=='radio' && $(this).trigger('change');
});
return false;
});
// set the default state
inputSelf.checked && aLink.addClass('jqTransformChecked');
});
};
/***************************
TextArea
***************************/
$.fn.jqTransTextarea = function(){
return this.each(function(){
var textarea = $(this);
if(textarea.hasClass('jqtransformdone')) {return;}
textarea.addClass('jqtransformdone');
oLabel = jqTransformGetLabel(textarea);
oLabel && oLabel.click(function(){textarea.focus();});
var strTable = '<table cellspacing="0" cellpadding="0" border="0" class="jqTransformTextarea">';
strTable +='<tr><td id="jqTransformTextarea-tl"></td><td id="jqTransformTextarea-tm"></td><td id="jqTransformTextarea-tr"></td></tr>';
strTable +='<tr><td id="jqTransformTextarea-ml"> </td><td id="jqTransformTextarea-mm"><div></div></td><td id="jqTransformTextarea-mr"> </td></tr>';
strTable +='<tr><td id="jqTransformTextarea-bl"></td><td id="jqTransformTextarea-bm"></td><td id="jqTransformTextarea-br"></td></tr>';
strTable +='</table>';
var oTable = $(strTable)
.insertAfter(textarea)
.hover(function(){
!oTable.hasClass('jqTransformTextarea-focus') && oTable.addClass('jqTransformTextarea-hover');
},function(){
oTable.removeClass('jqTransformTextarea-hover');
})
;
textarea
.focus(function(){oTable.removeClass('jqTransformTextarea-hover').addClass('jqTransformTextarea-focus');})
.blur(function(){oTable.removeClass('jqTransformTextarea-focus');})
.appendTo($('#jqTransformTextarea-mm div',oTable))
;
this.oTable = oTable;
if($.browser.safari){
$('#jqTransformTextarea-mm',oTable)
.addClass('jqTransformSafariTextarea')
.find('div')
.css('height',textarea.height())
.css('width',textarea.width())
;
}
});
};
/***************************
Select
***************************/
$.fn.jqTransSelect = function(){
return this.each(function(index){
var $select = $(this);
if($select.hasClass('jqTransformHidden')) {return;}
if($select.attr('multiple')) {return;}
var oLabel = jqTransformGetLabel($select);
/* First thing we do is Wrap it */
var $wrapper = $select
.addClass('jqTransformHidden')
.wrap('<div class="jqTransformSelectWrapper"></div>')
.parent()
.css({zIndex: 10-index})
;
/* Now add the html for the select */
$wrapper.prepend('<div><span></span></div><ul></ul>');
var $ul = $('ul', $wrapper).css('width',$select.width()).hide();
/* Now we add the options */
$('option', this).each(function(i){
var oLi = $('<li>'+ $(this).html() +'</li>');
$ul.append(oLi);
});
/* Add click handler to the a */
$ul.find('a').click(function(){
$('a.selected', $wrapper).removeClass('selected');
$(this).addClass('selected');
/* Fire the onchange event */
//if ($select[0].selectedIndex != $(this).attr('index') && $select[0].onchange) { $select[0].selectedIndex = $(this).attr('index'); $select[0].onchange(); }
if ($select[0].selectedIndex != $(this).attr('index')) { $select[0].selectedIndex = $(this).attr('index'); $select.change(); }
//Redundent code
//$select[0].selectedIndex = $(this).attr('index');
$('span:eq(0)', $wrapper).html($(this).html());
$ul.hide();
return false;
});
/* Set the default */
$('a:eq('+ this.selectedIndex +')', $ul).click();
$('span:first', $wrapper).click(function(){$("a.jqTransformSelectOpen",$wrapper).trigger('click');});
oLabel && oLabel.click(function(){$("a.jqTransformSelectOpen",$wrapper).trigger('click');});
this.oLabel = oLabel;
/* Apply the click handler to the Open */
var oLinkOpen = $('a.jqTransformSelectOpen', $wrapper)
.click(function(){
//Check if box is already open to still allow toggle, but close all other selects
if( $ul.css('display') == 'none' ) {jqTransformHideSelect();}
if($select.attr('disabled')){return false;}
$ul.slideToggle('fast', function(){
var offSet = ($('a.selected', $ul).offset().top - $ul.offset().top);
$ul.animate({scrollTop: offSet});
});
return false;
})
;
// Set the new width
var iSelectWidth = $select.outerWidth();
var oSpan = $('span:first',$wrapper);
var newWidth = (iSelectWidth > oSpan.innerWidth())?iSelectWidth+oLinkOpen.outerWidth():$wrapper.width();
$wrapper.css('width',newWidth);
$ul.css('width',newWidth-2);
oSpan.css({width:iSelectWidth});
// Calculate the height if necessary, less elements that the default height
//show the ul to calculate the block, if ul is not displayed li height value is 0
$ul.css({display:'block',visibility:'hidden'});
var iSelectHeight = ($('li',$ul).length)*($('li:first',$ul).height());//+1 else bug ff
(iSelectHeight < $ul.height()) && $ul.css({height:iSelectHeight,'overflow':'hidden'});//hidden else bug with ff
$ul.css({display:'none',visibility:'visible'});
});
};
$.fn.jqTransform = function(options){
var opt = $.extend({},defaultOptions,options);
/* each form */
return this.each(function(){
var selfForm = $(this);
if(selfForm.hasClass('jqtransformdone')) {return;}
selfForm.addClass('jqtransformdone');
$('input:submit, input:reset, input[type="button"]', this).jqTransInputButton();
$('input:text, input:password', this).jqTransInputText();
$('input:checkbox', this).jqTransCheckBox();
$('input:radio', this).jqTransRadio();
$('textarea', this).jqTransTextarea();
if( $('select', this).jqTransSelect().length > 0 ){jqTransformAddDocumentListener();}
selfForm.bind('reset',function(){var action = function(){jqTransformReset(this);}; window.setTimeout(action, 10);});
//preloading dont needed anymore since normal, focus and hover image are the same one
/*if(opt.preloadImg && !jqTransformImgPreloaded){
jqTransformImgPreloaded = true;
var oInputText = $('input:text:first', selfForm);
if(oInputText.length > 0){
//pour ie on eleve les ""
var strWrapperImgUrl = oInputText.get(0).wrapper.css('background-image');
jqTransformPreloadHoverFocusImg(strWrapperImgUrl);
var strInnerImgUrl = $('div.jqTransformInputInner',$(oInputText.get(0).wrapper)).css('background-image');
jqTransformPreloadHoverFocusImg(strInnerImgUrl);
}
var oTextarea = $('textarea',selfForm);
if(oTextarea.length > 0){
var oTable = oTextarea.get(0).oTable;
$('td',oTable).each(function(){
var strImgBack = $(this).css('background-image');
jqTransformPreloadHoverFocusImg(strImgBack);
});
}
}*/
}); /* End Form each */
};/* End the Plugin */
})(jQuery);
You could also get the same here: http://pastebin.com/Q1pYMKZ2