Is there a YUI 2.x equivalent to jQuery's scrollTo? - javascript

I want to create an animation to scroll the page smoothly when clicking on anchor links, just like jQuery.ScrollTo plugin (http://demos.flesler.com/jquery/scrollTo/) does it.
I tried making it using YUI 2.x Animation utility, by animating the value of the property document.activeElement.scrollTop. It works on webkit only :'( - on the other browser, nothing happens - not even an error is raised.
goToAnchor = function(e, id) {
var targetToGo = Dom.get(id),
scrollToTarget = new Animation(document.activeElement,
{
scrollTop:
{
from: document.activeElement.scrollTop,
to: targetToGo.offsetTop
}
}, 1, Easing.easeOut
)
Event.preventDefault(e);
scrollToTarget.animate();
}
What I'd like to know is if there's a plugin that does this for YUI 2.x or how to do a cross browser compatible code to do so.
Thanks!

You need to keep in mind that depending on browser you might need to scroll the html or the body element.
(practially, you need to scroll both to be sure)
Also at http://developer.yahoo.com/yui/animation/#scroll i see
var element = document.getElementById('test');
var myAnim = new YAHOO.util.Scroll(element, {
scroll: {
to: [ 500, test.scrollTop ]
}
});
myAnim.animate();
Maybe that is what you are looking for (still you will have to animate both html and body)

<script>
(function() {
var scrollingBody = document.body;
if (YAHOO.env.ua.gecko){
scrollingBody = document.documentElement;
}
(new YAHOO.util.Scroll(
scrollingBody,
{
scroll:
{
to: [0, 50]
}
},
0.7,
YAHOO.util.Easing.easeOut
)).animate();
})();
</script>

Related

PhotoSwipe use image to open gallery

Im looking for a solution too open the PhotoSwipe gallery with a
img link. So there is a IMG with a gallery icon. And i want if the
user click on it that the gallery open.
Have someone an idea how i can handel that?
I found this out. But this open on load the gallery.
<script type="text/javascript">
(function(window, PhotoSwipe){
document.addEventListener('DOMContentLoaded', function(){
var
options = {
preventHide: true
},
instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
instance.show(0);
}, false);
}(window, window.Code.PhotoSwipe));
</script>
Best regargs
I just started working with photoSwipe so I am not positive this will work but it seems to me you only have to call instance.show(0) on a click event.
Assuming I have this element on the page: <a id="launch-gallery" href="#">Click to launch gallery</a> I could add this jQuery click event to launch the gallery:
$('#launch-gallery').click(function(evt){
evt.preventDefault(); // prevent regular click action
instance.show(0); // Make sure 'instance' variable is available to this function
});
If you are not using jQuery, you can do the same thing in native JavaScript (but a little more verbose).
I hope this helps.
Note that I use php (ajax) to deliver the image locations and sizes, so you'll still have to define the json data yourself.
This is how I did it with Jquery:
$('.element').off(); //in case it's a dynamically changing element
$('.element').on("click tap", function () {
var dataForPhpScript = $(this).parents('.gallery').attr("data-attr"); //data for php script
$.getJSON('urlToPHPFunction?dataID=' + dataForPhpScript, function (json) {
openPhotoSwipe(json);
});
});
And here is the photoswipe opening function:
function openPhotoSwipe(jsonData) {
var pswpElement = document.querySelectorAll('.pswp')[0];
// define options (if needed)
var options = {
// history & focus options are disabled on CodePen
history: false,
focus: false,
showAnimationDuration: 0,
hideAnimationDuration: 0
};
var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, jsonData, options);
gallery.init();
}
note that jsonData is supposed to look somewhat like this:
[
{
src: 'https://placekitten.com/600/400',
w: 600,
h: 400
},
{
src: 'https://placekitten.com/1200/900',
w: 1200,
h: 900
}
];
I realise this answer is late, but since this came on top while just googling something entirely different (but photoswipe related), I thought maybe this would be useful!

Todays Special: How is this done? Is there a jquery plugin or product to do it?

I saw this technique at the bottom of a web page where the TAB stays in place at the bottom of the page and can be opened and closed to display more info. I assume it can be rotated to display a different special for different days. Can you point me to anything like it or explain the technique ? thanks. Here is a sample: http://www.tmdhosting.com/ look at the bottom of the page .
position: fixed is how you manage to keep something at the bottom or top of the page, regardless of scrolling.
This is easily discoverable using firebug's (http://getfirebug.com/) inspect element feature
You can check out my version of this at uxspoke.com
I wrote a jQuery plugin to do it, and calling it is straightforward:
$('#about').pulloutPanel({open:true}).
click(function() { $(this).trigger('toggle'); }) });
I basically instrument the panel to support "open", "close" events, and the implement the appropriate animations around them. The only "hard" part is getting the height right. It also supports "toggle" so you can add a generic click handler to it to open or close it. Finally, it uses opened/closed classes to keep track of its current state. That's it!
The code's pretty coupled to the technologies on the page (Csster) and the design it is in, so I'm not sure it will work for you. You can either use Csster, or just put the CSS rules into your stylesheet and remove them from the code. The important Css attributes are the positioning and bottom.
Here it is:
$.fn.pulloutPanel = function(options) {
var settings = $.extend({}, {
attachTo: 'bottom',
css: {
left: 0,
minHeight: 390,
border: '1px 1px 1px 0 solid #666',
has: [roundedCorners('tr', 10),boxShadow([0,0], 10, phaseToColor('requirements').saturate(-30).darken(50))],
cursor: 'pointer'
}, options);
return $(this).each(function() {
var $this = $(this);
$this.addClass('pullout_panel');
$this.bind('open', function(event) {
$this.animate({bottom: 0}, 'slow', 'easeOutBounce', function() {
$this.removeClass('closed').addClass('opened');
$this.trigger('opened');
});
});
$this.bind('close', function(event) {
var height = $this.innerHeight();
$this.animate({bottom: -height + 50}, 'slow', 'easeOutBounce', function() {
$this.addClass('closed').removeClass('opened');
$this.trigger('closed');
});
});
$this.bind('toggle', function(event) {
$this.trigger($this.hasClass('opened') ? 'close' : 'open');
});
once(function() {
Csster.style({
'.pullout_panel': {
position: 'fixed',
bottom: 0,
has: [settings.css]
}
});
});
$this.trigger(settings.open ? 'open' : 'close');
});
};

Shade entire page, unshade selected elements on hover

I'm trying to make a page inspection tool, where:
The whole page is shaded
Hovered elements are unshaded.
Unlike a lightbox type app (which is similar), the hovered items should remain in place and (ideally) not be duplicated.
Originally, looking at the image lightbox implementations, I thought of appending an overlay to the document, then raising the z-index of elements upon hover. However this technique does not work in this case, as the overlay blocks additional mouse hovers:
$(function() {
window.alert('started');
$('<div id="overlay" />').hide().appendTo('body').fadeIn('slow');
$("p").hover(
function () {
$(this).css( {"z-index":5} );
},
function () {
$(this).css( {"z-index":0} );
}
);
Alternatively, JQueryTools has an 'expose' and 'mask' tool, which I have tried with the code below:
$(function() {
$("a").click(function() {
alert("Hello world!");
});
// Mask whole page
$(document).mask("#222");
// Mask and expose on however / unhover
$("p").hover(
function () {
$(this).expose();
},
function () {
$(this).mask();
}
);
});
Hovering does not work unless I disable the initial page masking. Any thoughts of how best to achieve this, with plain JQuery, JQuery tools expose, or some other technique? Thankyou!
What you can do is make a copy of the element and insert it back into the DOM outside of your overlay (with a higher z-index). You'll need to calculate its position to do so, but that's not too difficult.
Here is a working example.
In writing this I re-learned the fact that something with zero opacity cannot trigger an event. Therefore you can't use .fade(), you have to specifically set the opacity to a non-zero but very small number.
$(document).ready(function() { init() })
function init() {
$('.overlay').show()
$('.available').each(function() {
var newDiv = $('<div>').appendTo('body');
var myPos = $(this).position()
newDiv.addClass('available')
newDiv.addClass('peek')
newDiv.addClass('demoBorder')
newDiv.css('top',myPos.top+'px')
newDiv.css('left',myPos.left+'px')
newDiv.css('height',$(this).height()+'px')
newDiv.css('width',$(this).width()+'px')
newDiv.hover(function()
{newDiv.addClass('full');newDiv.stop();newDiv.fadeTo('fast',.9)},function()
{newDiv.removeClass('full');newDiv.fadeTo('fast',.1)})
})
}
Sorry for the prototype syntax, but this might give you a good idea.
function overlay() {
var div = document.createElement('div');
div.setStyle({
position: "absolute",
left: "0px",
right: "0px",
top: "0px",
bottom: "0px",
backgroundColor: "#000000",
opacity: "0.2",
zIndex: "20"
})
div.setAttribute('id','over');
$('body').insert(div);
}
$(document).observe('mousemove', function(e) {
var left = e.clientX,
top = e.clientY,
ele = document.elementFromPoint(left,top);
//from here you can create that empty div and insert this element in there
})
overlay();

Possible to make jqGrid stretch to 100%?

Is it possible to make it so that a jqGrid will have a width set to 100%? I understand that column widths must be an absolute pixel size, but I've yet to find anything for setting the width of the actual grid to a relative size. For instance, I want to set the width to 100%. Instead of 100% it seems to use an odd size of 450px. There is more horizontal room on the page, but with the columns width and such, it will make the container(of only the grid) horizontally scroll. Is there some way around this?
autowidth: true from 3.5 onwards
It works for me:
width: null,
shrinkToFit: false,
I'm using this to set the width of the grid to the width of the parent container.
function resizeGrid() {
var $grid = $("#list"),
newWidth = $grid.closest(".ui-jqgrid").parent().width();
$grid.jqGrid("setGridWidth", newWidth, true);
}
I ended up using the jqGrids.fluid extension to do this and it worked great.
UPDATE: That link seems to be dead, but the archived article can be viewed here.
You can try to fix the width of jqGrid with respect of a function which I described here Correctly calling setGridWidth on a jqGrid inside a jQueryUI Dialog
wonderful function for this i found here (stackoverflow) cannot remember the post. I have the height portion commented out keep that in mind (was not working for me) but the width is perfect. throw this anywhere in your php file.
$resize = <<<RESIZE
jQuery(window).resize(function(){
gridId = "grid";
gridParentWidth = $('#gbox_' + gridId).parent().width();
$('#' + gridId).jqGrid('setGridWidth',gridParentWidth);
// $('#' + gridId).jqGrid('setGridHeight', //Math.min(500,parseInt(jQuery(".ui-jqgrid-btable").css('height'))));
})
RESIZE;
Try to set width to "null". It works for me.
$(grid).jqGrid({
width: null,
});
It looks like this is not supported. According to the docs for setGridWidth:
Sets a new width to the grid dynamically. The parameters are:
new_width is the new width in pixels...
The docs for the width option also do not mention being able to set width as a percentage.
That being said, you can use the autowidth feature or a similar technique to give the grid the correct initial width. Then follow the methods discussed in resize-jqgrid-when-browser-is-resized to ensure the grid is properly resized when the browser window is resized, which will simulate the effect of having 100% width.
loadComplete : function () {
$("#gridId").jqGrid('setGridWidth', $(window).width(), true);
},
Simpler
$("#gridId").setGridWidth($(window).width() );
Try this,
Replace width: 1100 to autowidth: true,
You can't give width in percent, while if you want according to screen resolution then set as follows:
var w = screen.width
and then use this variable in width option of jqgrid.
Hope it will useful.
I have done this and working like charm.
$(document).ready(function () {
$("#jQGridDemo").setGridWidth(window.innerWidth - offset);
});
I have put offset of 50
I've noticed that only the combination of all 3 answers given, i.e. JohnJohn's answer,
Bhargav's answer and
Molson's answer helped me to achive a real automatic resize.
So I have created some code that takes advantage of all, see the snippet below. I've also improved it so you can either pass a single grid object or an array of grids to be resized.
If you try it out ensure that you
click on Run code snippet, and
then click on the "Full page" link button in the upper right corner.
Resize the window and watch how the grids changes their size and re-align automatically:
// see: https://free-jqgrid.github.io/getting-started/
// CDN used: https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid
$(function() {
// pass one single grid, or an array of grids
function resizeGrid(jqGridObj) {
var $gridArray = Array.isArray(jqGridObj) ? jqGridObj : [jqGridObj];
for(let i=0; i<$gridArray.length; i++) {
var $grid=$gridArray[i],
newWidth = $grid.closest(".ui-jqgrid").parent().width();
$grid.jqGrid("setGridWidth", newWidth, true);
}
};
// template for the 2 grids
function createGrid(gridName, gridData) {
var gridObj=$("#"+gridName); gridObj.jqGrid({
autowidth: true, height: 45,
colNames: ['First name', 'Last name', 'Updated?'],
colModel: [{name: "firstName"}, {name: "lastName"}, {name: "updated"}],
data: gridData,
loadComplete: function() {
// resize on load
resizeGrid(gridObj);
}
});
return gridObj;
}
// instantiate Grid1
var data1 = [
{ id: 10, firstName: "Jane", lastName: "Doe", updated: "no"},
{ id: 20, firstName: "Justin", lastName: "Time", updated: "no" }
];
var gridObj1=createGrid("grid1", data1);
// instantiate Grid2
var data2 = [
{ id: 10, firstName: "Jane", lastName: "Smith", updated: "no"},
{ id: 20, firstName: "Obi-Wan", lastName: "Kenobi", updated: "no" }
];
var gridObj2=createGrid("grid2", data2);
function debounce(fn, delay) {
delay || (delay = 200);
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 200);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
// change size with window for both grids
jQuery(window).resize(throttle(function(){
resizeGrid([gridObj1, gridObj2]);
}));
});
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Resizing jqGrid example</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.15.2/css/ui.jqgrid.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.15.2/jquery.jqgrid.min.js"></script>
<table id="grid1"></table>
<br/>
<table id="grid2"></table>
Note: While this example is simple, if you have more complex jqGrids you will need throttling or debouncing (the 2 functions throttle and debounce are taken from there), otherwise the resize event could be really slow. Follow the link to read more about it. I prefer throttling in this case because it looks smoother, but I have included both functions so you can use them if needed in your code.
In my real code I needed throttling, otherwise resizing was getting far too slow. The code snippet already includes a throttled handler with a default threshold of 200ms. You can experiment with it, for example if you replace throttle by debounce in the code snippet, i.e.
jQuery(window).resize(debounce(function(){
resizeGrid([gridObj1, gridObj2]);
}));

jQuery animate() to position issue

I'm just working on my personal website, giving it a bit of a revamp.
I've implemented a sort of 'accordion' menu feature, where if a menu button is clicked, the "non-clicked" buttons disappear, and then the clicked button is moved to the top of the list, where then a panel animates down in which I will be putting text content.
In Firefox this works perfectly, however in IE and Chrome the button jumps to the top of the page and then animates to position, instead of animating from where it started from.
Anyone any ideas how to fix this?
Offending code:
function Accordion(e)
{
var o =
{
init: function()
{
o.button = e;
o.addClickHandler();
},
addClickHandler: function()
{
o.button.click(function(){
o.button.removeClass('unselected');
o.button.addClass('selected');
o.fader();
});
},
fader: function()
{
$j('.unselected').animate({opacity:0}, 1000);
var wait = setInterval(function() {
if(!$j('.unselected').is(":animated") ) {
clearInterval(wait);
o.shifter();
}
}, 100);
},
shifter: function()
{
o.button.css({'position':'absolute'});
o.button.animate({top:91}, 500, o.createInfoBox);
},
createInfoBox: function()
{
var buttonParent = o.button.parent();
buttonParent.append("<div class='infoBox'></div>");
$j('.infoBox').animate({height:390});
}
}
o.init();
return o;
}
}
The issue lies within the shifter function, where I'm setting the position to absolute and then animating so the desired effect can be achieved. I understand why it's doing this (presume it's just resetting itself to top:0 and then animating to top:91) but does anyone have a quick solution? It's late and it's doing my head in.
Much appreciated,
Dave
HAve you tried using the current position of the element when you switch it to absolute... for example:
function() {
var currentp = $(this).offset();
o.button.css({'position':'absolute', top: currentp.top});
o.button.animate({top:91}, 500, o.createInfoBox);
}
Note there are two different offset functions and im not sure which one you want use here so you might want to review the docs on that.
Also you could always just re-theme the jQuery-ui accordian and save yourself the trouble ;-)

Categories