I am just a beginner in jquery. I have used the tooltip script from this site. http://www.twinhelix.com/dhtml/supernote/demo/#demo4 .They used the following function to close the tooltip on clicking the close button.
<script type="text/javascript">
// SuperNote setup: Declare a new SuperNote object and pass the name used to
// identify notes in the document, and a config variable hash if you want to
// override any default settings.
var supernote = new SuperNote('supernote', {});
// Available config options are:
//allowNesting: true/false // Whether to allow triggers within triggers.
//cssProp: 'visibility' // CSS property used to show/hide notes and values.
//cssVis: 'inherit'
//cssHid: 'hidden'
//IESelectBoxFix: true/false // Enables the IFRAME select-box-covering fix.
//showDelay: 0 // Millisecond delays.
//hideDelay: 500
//animInSpeed: 0.1 // Animation speeds, from 0.0 to 1.0; 1.0 disables.
//animOutSpeed: 0.1
// You can pass several to your "new SuperNote()" command like so:
//{ name: value, name2: value2, name3: value3 }
// All the script from this point on is optional!
// Optional animation setup: passed element and 0.0-1.0 animation progress.
// You can have as many custom animations in a note object as you want.
function animFade(ref, counter)
{
//counter = Math.min(counter, 0.9); // Uncomment to make notes translucent.
var f = ref.filters, done = (counter == 1);
if (f)
{
if (!done && ref.style.filter.indexOf("alpha") == -1)
ref.style.filter += ' alpha(opacity=' + (counter * 100) + ')';
else if (f.length && f.alpha) with (f.alpha)
{
if (done) enabled = false;
else { opacity = (counter * 100); enabled=true }
}
}
else ref.style.opacity = ref.style.MozOpacity = counter*0.999;
};
supernote.animations[supernote.animations.length] = animFade;
// Optional custom note "close" button handler extension used in this example.
// This picks up click on CLASS="note-close" elements within CLASS="snb-pinned"
// notes, and closes the note when they are clicked.
// It can be deleted if you're not using it.
addEvent(document, 'click', function(evt)
{
var elm = evt.target || evt.srcElement, closeBtn, note;
while (elm)
{
if ((/note-close/).test(elm.className)) closeBtn = elm;
if ((/snb-pinned/).test(elm.className)) { note = elm; break }
elm = elm.parentNode;
}
if (closeBtn && note)
{
var noteData = note.id.match(/([a-z_\-0-9]+)-note-([a-z_\-0-9]+)/i);
for (var i = 0; i < SuperNote.instances.length; i++)
if (SuperNote.instances[i].myName == noteData[1])
{
setTimeout('SuperNote.instances[' + i + '].setVis("' + noteData[2] +
'", false, true)', 100);
cancelEvent(evt);
}
}
});
// Extending the script: you can capture mouse events on note show and hide.
// To get a reference to a note, use 'this.notes[noteID]' within a function.
// It has properties like 'ref' (the note element), 'trigRef' (its trigger),
// 'click' (whether its shows on click or not), 'visible' and 'animating'.
addEvent(supernote, 'show', function(noteID)
{
// Do cool stuff here!
});
addEvent(supernote, 'hide', function(noteID)
{
// Do cool stuff here!
});
// If you want draggable notes, feel free to download the "DragResize" script
// from my website http://www.twinhelix.com -- it's a nice addition :).
</script>
I have tried to edit this function for closing the tooltip on clicking the esckey too. But i couldn't. How can i modify the function?
Related
I'm using the Microsoft Translation Widget, which I'd like to use to automatically translate a webpage without user interaction.
The problem is, I can't get rid of the widget that keeps popping up or hide it on document.ready because the CSS and JS get loaded from Microsoft's own script in the widget!
Does anyone know a way around this? I've looked everywhere and cannot find a solutuion for this.
Whoa, after some time playing around with that, I've finally achieved what you want.
It's kindda ugly, because of some needed workarounds, but it works, take a look at the fiddle.
The steps were:
Firstly, we must override the default addEventListener behavior:
var addEvent = EventTarget.prototype.addEventListener;
var events = [];
EventTarget.prototype.addEventListener = function(type, listener) {
addEvent.apply(this, [].slice.call(arguments));
events.push({
element: this,
type: type,
listener: listener
});
}
Then, we create a helper function removeEvents. It removes all the event listeners of an element.
var removeEvents = function(el, type) {
var elEvents = events.filter(function(ev) {
return ev.element === el && (type ? ev.type === type : true);
});
for (var i = 0; i < elEvents.length; i++) {
el.removeEventListener(elEvents[i].type, elEvents[i].listener);
}
}
When creating the script tag, in the way Microsoft says:
var s = d.createElement('script');
s.type = 'text/javascript';
s.charset = 'UTF-8';
s.src = ((location && location.href && location.href.indexOf('https') == 0) ? 'https://ssl.microsofttranslator.com' : 'http://www.microsofttranslator.com') + '/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=True&ui=true&settings=Manual&from=';
var p = d.getElementsByTagName('head')[0] || d.dElement;
p.insertBefore(s, p.firstChild);
We must add a load event listener to that script, and the code below is fully commented:
s.addEventListener('load', function() {
// when someone changes the translation, the plugin calls the method TranslateArray
// then, we save the original method in a variable, and we override it
var translate = Microsoft.Translator.TranslateArray;
Microsoft.Translator.TranslateArray = function() {
// we call the original method
translate.apply(this, [].slice.call(arguments));
// since the translation is not immediately available
// and we don't have control when it will be
// I've created a helper function to wait for it
waitForTranslation(function() {
// as soon as it is available
// we get all the elements with an attribute lang
[].forEach.call(d.querySelectorAll('[lang]'), function(item, i) {
// and we remove all the mouseover event listeners of them
removeEvents(item, 'mouseover');
});
});
}
// this is the helper function which waits for the translation
function waitForTranslation(cb) {
// since we don't have control over the translation callback
// the workaround was to see if the Translating label is visible
// we keep calling the function, until it's hidden again
// and then we call our callback
var visible = d.getElementById('FloaterProgressBar').style.visibility;
if (visible === 'visible') {
setTimeout(function() {
waitForTranslation(cb);
}, 0);
return;
}
cb();
}
});
Update 1
After re-reading your question, it seems you want to hide all the widgets at all.
So, you must add the following code as soon as the translation is got:
waitForTranslation(function() {
document.getElementById('MicrosoftTranslatorWidget').style.display = 'none';
document.getElementById('WidgetLauncher').style.display = 'none';
document.getElementById('LauncherTranslatePhrase').style.display = 'none';
document.getElementById('TranslateSpan').style.display = 'none';
document.getElementById('LauncherLogo').style.display = 'none';
document.getElementById('WidgetFloaterPanels').style.display = 'none';
// rest of the code
});
I've created another fiddle for you, showing that new behavior.
Update 2
You can prevent the widget showing at all by adding the following CSS code:
#MicrosoftTranslatorWidget, #WidgetLauncher, #LauncherTranslatePhrase, #TranslateSpan, #LauncherLogo, #WidgetFloaterPanels {
opacity: 0!important;
}
And you can even prevent the before-translated text being showed, by hiding the document.body by default, and then showing it when the page is fully translated:
(function(w, d) {
document.body.style.display = 'none';
/* (...) */
s.addEventListener('load', function() {
var translate = Microsoft.Translator.TranslateArray;
Microsoft.Translator.TranslateArray = function() {
translate.apply(this, [].slice.call(arguments));
waitForTranslation(function() {
/* (...) */
document.body.style.display = 'block';
});
}
});
});
Take a look at the final fiddle I've created.
For me, this was the solution:
on your < style > section add this class
.LTRStyle { display: none !important }
Also, if you are invoking the translation widget this way:
Microsoft.Translator.Widget.Translate('en', lang, null, null, TranslationDone, null, 3000);
then add this to your callback (in this example is TranslationDone) function:
function TranslationDone() {
Microsoft.Translator.Widget.domTranslator.showHighlight = false;
Microsoft.Translator.Widget.domTranslator.showTooltips = false;
document.getElementById('WidgetFloaterPanels').style.display = 'none';
};
I'm using Skrollr-menu to animate down a page on a button press using the following
HTML
<div class="trigger-scroll left">></div>
... the page i want to reveal, using scrolling ...
<section id="End" class="scroll-here">
<div class="hsContainer bottom"></div>
</section>
JavaScript
var s = skrollr.init();
skrollr.menu.init(s, {
animate: true,
//How long the animation should take in ms.
duration: function(currentTop, targetTop) {
//By default, the duration is hardcoded at 500ms.
return 18000;
//But you could calculate a value based on the current scroll position (`currentTop`) and the target scroll position (`targetTop`).
//return Math.abs(currentTop - targetTop) * 10;
},
//This event is triggered right before we jump/animate to a new hash.
change: function(newHash, newTopPosition) {
//Do stuff
},
//Add hash link (e.g. `#foo`) to URL or not.
updateUrl: false //defaults to `true`.
});
What happens when I click the button is that it works, that is not the problem.
The problem is that it seems to change speed as skrollr-menu animates the page. It starts off quite quickly, which means that the first few elements on the page (about the first 2000px) flash past without being readable. Then the speed evens out and is fine right until the last 3000px (approximately) where skrollr-menu is very slow. What I want is for the click of the button to resemble holding the down arrow on the keyboard or the scroll sidebar, which by default it seems skrollr-menu does not do.
I've tried using math equations to change the speed but the issue persists no matter what i try, and there doesn't seem to be any "simple" way to change the acceleration speed, and I suspect the problem is somewhere within the Skrollr.menu.js file, but I can't see where.
Is there any way which I can make the scrolling an even speed, rather than fast at the start and slow at the end?
Note: I'm not very experienced in JavaScript or jQuery, so it's probably something simple I've overlooked.
skrollr menu on github
https://github.com/Prinzhorn/skrollr-menu
Skrollr.menu.js
/*!
* Plugin for skrollr.
* This plugin makes hashlinks scroll nicely to their target position.
*
* Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr
*
* Free to use under terms of MIT license
*/
(function(document, window) {
'use strict';
var DEFAULT_DURATION = 500;
var DEFAULT_EASING = 'sqrt';
var DEFAULT_SCALE = 1;
var MENU_TOP_ATTR = 'data-menu-top';
var MENU_OFFSET_ATTR = 'data-menu-offset';
var MENU_DURATION_ATTR = 'data-menu-duration';
var MENU_IGNORE_ATTR = 'data-menu-ignore';
var skrollr = window.skrollr;
var history = window.history;
var supportsHistory = !!history.pushState;
/*
Since we are using event bubbling, the element that has been clicked
might not acutally be the link but a child.
*/
var findParentLink = function(element) {
//We reached the top, no link found.
if(element === document) {
return false;
}
//Yay, it's a link!
if(element.tagName.toUpperCase() === 'A') {
return element;
}
//Maybe the parent is a link.
return findParentLink(element.parentNode);
};
/*
Handle the click event on the document.
*/
var handleClick = function(e) {
//Only handle left click.
if(e.which !== 1 && e.button !== 0) {
return;
}
var link = findParentLink(e.target);
//The click did not happen inside a link.
if(!link) {
return;
}
if(handleLink(link)) {
e.preventDefault();
}
};
/*
Handles the click on a link. May be called without an actual click event.
When the fake flag is set, the link won't change the url and the position won't be animated.
*/
var handleLink = function(link, fake) {
var hash;
//When complexLinks is enabled, we also accept links which do not just contain a simple hash.
if(_complexLinks) {
//The link points to something completely different.
if(link.hostname !== window.location.hostname) {
return false;
}
//The link does not link to the same page/path.
if(link.pathname !== document.location.pathname) {
return false;
}
hash = link.hash;
} else {
//Don't use the href property (link.href) because it contains the absolute url.
hash = link.getAttribute('href');
}
//Not a hash link.
if(!/^#/.test(hash)) {
return false;
}
//The link has the ignore attribute.
if(!fake && link.getAttribute(MENU_IGNORE_ATTR) !== null) {
return false;
}
//Now get the targetTop to scroll to.
var targetTop;
var menuTop;
//If there's a handleLink function, it overrides the actual anchor offset.
if(_handleLink) {
menuTop = _handleLink(link);
}
//If there's a data-menu-top attribute and no handleLink function, it overrides the actual anchor offset.
else {
menuTop = link.getAttribute(MENU_TOP_ATTR);
}
if(menuTop !== null) {
//Is it a percentage offset?
if(/p$/.test(menuTop)) {
targetTop = (menuTop.slice(0, -1) / 100) * document.documentElement.clientHeight;
} else {
targetTop = +menuTop * _scale;
}
} else {
var scrollTarget = document.getElementById(hash.substr(1));
//Ignore the click if no target is found.
if(!scrollTarget) {
return false;
}
targetTop = _skrollrInstance.relativeToAbsolute(scrollTarget, 'top', 'top');
var menuOffset = scrollTarget.getAttribute(MENU_OFFSET_ATTR);
if(menuOffset !== null) {
targetTop += +menuOffset;
}
}
if(supportsHistory && _updateUrl && !fake) {
history.pushState({top: targetTop}, '', hash);
}
var menuDuration = parseInt(link.getAttribute(MENU_DURATION_ATTR), 10);
var animationDuration = _duration(_skrollrInstance.getScrollTop(), targetTop);
if(!isNaN(menuDuration)) {
animationDuration = menuDuration;
}
//Trigger the change if event if there's a listener.
if(_change) {
_change(hash, targetTop);
}
//Now finally scroll there.
if(_animate && !fake) {
_skrollrInstance.animateTo(targetTop, {
duration: animationDuration,
easing: _easing
});
} else {
defer(function() {
_skrollrInstance.setScrollTop(targetTop);
});
}
return true;
};
var jumpStraightToHash = function() {
if(window.location.hash && document.querySelector) {
var link = document.querySelector('a[href="' + window.location.hash + '"]');
if(!link) {
// No link found on page, so we create one and then activate it
link = document.createElement('a');
link.href = window.location.hash;
}
handleLink(link, true);
}
};
var defer = function(fn) {
window.setTimeout(fn, 1);
};
/*
Global menu function accessible through window.skrollr.menu.init.
*/
skrollr.menu = {};
skrollr.menu.init = function(skrollrInstance, options) {
_skrollrInstance = skrollrInstance;
options = options || {};
_easing = options.easing || DEFAULT_EASING;
_animate = options.animate !== false;
_duration = options.duration || DEFAULT_DURATION;
_handleLink = options.handleLink;
_scale = options.scale || DEFAULT_SCALE;
_complexLinks = options.complexLinks === true;
_change = options.change;
_updateUrl = options.updateUrl !== false;
if(typeof _duration === 'number') {
_duration = (function(duration) {
return function() {
return duration;
};
}(_duration));
}
//Use event bubbling and attach a single listener to the document.
skrollr.addEvent(document, 'click', handleClick);
if(supportsHistory) {
skrollr.addEvent(window, 'popstate', function(e) {
var state = e.state || {};
var top = state.top || 0;
defer(function() {
_skrollrInstance.setScrollTop(top);
});
}, false);
}
jumpStraightToHash();
};
//Expose the handleLink function to be able to programmatically trigger clicks.
skrollr.menu.click = function(link) {
//We're not assigning it directly to `click` because of the second ("private") parameter.
handleLink(link);
};
//Private reference to the initialized skrollr.
var _skrollrInstance;
var _easing;
var _duration;
var _animate;
var _handleLink;
var _scale;
var _complexLinks;
var _change;
var _updateUrl;
//In case the page was opened with a hash, prevent jumping to it.
//http://stackoverflow.com/questions/3659072/jquery-disable-anchor-jump-when-loading-a-page
defer(function() {
if(window.location.hash) {
window.scrollTo(0, 0);
}
});
}(document, window));
The problem was the easing function found here
//Now finally scroll there.
if(_animate && !fake) {
_skrollrInstance.animateTo(targetTop, {
duration: animationDuration,
easing: _easing
});
} else {
defer(function() {
_skrollrInstance.setScrollTop(targetTop);
});
}
return true;
It seems that, even though Skrollr states that easing's default is linear (no easing), the default is ACTUALLY set to sqrt (or at least it was in my case). The problem can be solved by forcing easing to linear in skrollr.menu.init, or chaning the skrollr.menu.js file to remove easing from the function. The first of these two solutions is cleaner, and won't cause issues later.
skrollr.menu.init(s, {
duration: function(currentTop, targetTop) {return 20000;},
easing: 'linear'
});
I wrote a slideshow plugin, but for some reason maybe because I've been working on it all day, I can't figure out exactly how to get it to go back to state one, once it's reached the very last state when it's on auto mode.
I'm thinking it's an architectual issue at this point, because basically I'm attaching the amount to scroll left to (negatively) for each panel (a panel contains 4 images which is what is currently shown to the user). The first tab should get: 0, the second 680, the third, 1360, etc. This is just done by calculating the width of the 4 images plus the padding.
I have it on a setTimeout(function(){}) currently to automatically move it which works pretty well (unless you also click tabs, but that's another issue). I just want to make it so when it's at the last state (numTabs - 1), to animate and move its state back to the first one.
Code:
(function($) {
var methods = {
init: function(options) {
var settings = $.extend({
'speed': '1000',
'interval': '1000',
'auto': 'on'
}, options);
return this.each(function() {
var $wrapper = $(this);
var $sliderContainer = $wrapper.find('.js-slider-container');
$sliderContainer.hide().fadeIn();
var $tabs = $wrapper.find('.js-slider-tabs li a');
var numTabs = $tabs.size();
var innerWidth = $wrapper.find('.js-slider-container').width();
var $elements = $wrapper.find('.js-slider-container a');
var $firstElement = $elements.first();
var containerHeight = $firstElement.height();
$sliderContainer.height(containerHeight);
// Loop through each list element in `.js-slider-tabs` and add the
// distance to move for each "panel". A panel in this example is 4 images
$tabs.each(function(i) {
// Set amount to scroll for each tab
if (i === 1) {
$(this).attr('data-to-move', innerWidth + 20); // 20 is the padding between elements
} else {
$(this).attr('data-to-move', innerWidth * (i) + (i * 20));
}
});
// If they hovered on the panel, add paused to the data attribute
$('.js-slider-container').hover(function() {
$sliderContainer.attr('data-paused', true);
}, function() {
$sliderContainer.attr('data-paused', false);
});
// Start the auto slide
if (settings.auto === 'on') {
methods.auto($tabs, settings, $sliderContainer);
}
$tabs.click(function() {
var $tab = $(this);
var $panelNum = $(this).attr('data-slider-panel');
var $amountToMove = $(this).attr('data-to-move');
// Remove the active class of the `li` if it contains it
$tabs.each(function() {
var $tab = $(this);
if ($tab.parent().hasClass('active')) {
$tab.parent().removeClass('active');
}
});
// Add active state to current tab
$tab.parent().addClass('active');
// Animate to panel position
methods.animate($amountToMove, settings);
return false;
});
});
},
auto: function($tabs, settings, $sliderContainer) {
$tabs.each(function(i) {
var $amountToMove = $(this).attr('data-to-move');
setTimeout(function() {
methods.animate($amountToMove, settings, i, $sliderContainer);
}, i * settings.interval);
});
},
animate: function($amountToMove, settings, i, $sliderContainer) {
// Animate
$('.js-slider-tabs li').eq(i - 1).removeClass('active');
$('.js-slider-tabs li').eq(i).addClass('active');
$('#js-to-move').animate({
'left': -$amountToMove
}, settings.speed, 'linear', function() {});
}
};
$.fn.slider = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
return false;
}
};
})(jQuery);
$(window).ready(function() {
$('.js-slider').slider({
'speed': '10000',
'interval': '10000',
'auto': 'on'
});
});
The auto and animate methods are where the magic happens. The parameters speed is how fast it's animated and interval is how often, currently set at 10 seconds.
Can anyone help me figure out how to get this to "infinitely loop", if you will?
Here is a JSFiddle
It would probably be better to let go of the .each() and setTimeout() combo and use just setInterval() instead. Using .each() naturally limits your loop to the length of your collection, so it's better to use a looping mechanism that's not, and that you can break at any point you choose.
Besides, you can readily identify the current visible element by just checking for .active, from what I can see.
You'd probably need something like this:
setInterval(function () {
// do this check here.
// it saves you a function call and having to pass in $sliderContainer
if ($sliderContainer.attr('data-paused') === 'true') { return; }
// you really need to just pass in the settings object.
// the current element you can identify (as mentioned),
// and $amountToMove is derivable from that.
methods.animate(settings);
}, i * settings.interval);
// ...
// cache your slider tabs outside of the function
// and just form a closure on that to speed up your manips
var slidertabs = $('.js-slider-tabs');
animate : function (settings) {
// identify the current tab
var current = slidertabs.find('li.active'),
// and then do some magic to determine the next element in the loop
next = current.next().length >= 0 ?
current.next() :
slidertabs.find('li:eq(0)')
;
current.removeClass('active');
next.addClass('active');
// do your stuff
};
The code is not optimized, but I hope you see where I'm getting at here.
I've added a custom button to TinyMCE which brings up a bespoke link-picker. When the user selects some text and clicks the button the dialog appears and when they've picked the url I'm using execCommand('insertHTML', false, "<a href... etc">) on the selection.
This works fine - now, when the link has already been created, and the user wants to edit it, they click the link button again (when the cursor is inside the linked text as normal), but then here is the situation - I don't know how to access the already created link and it's attributes to then load up and populate the dialogue again!
Have search TinyMCE site, Stack, Google in general. Hoping for (and also slightly dreading) a simple answer - but if not, a complex one will be fine!!
If anybody knows the answer or can point me to it, I'd be extremely grateful. Thanks in advance,
Rob
EDIT - bits of my code to explain need
In the TinyMCE init:
setup: function (ed) {
ed.addButton("link", {
title: "Link",
onclick: function (evt) {
Intranet.TextEditor._loadUrlDialog(jQueryTextAreaObject, evt);
}
});
}
The function which is called above:
_loadUrlDialog: function (jQueryTextAreaObject, clickEvent) {
var mce = $(jQueryTextAreaObject).tinymce();
var isSelected = mce.selection.getContent().length != 0 ? true : false;
if (isSelected) {
Intranet.UrlDialog.Fn.LoadDialog("", true, "", function (url, target, title) {
var theTarget = target == false ? "_self" : "_blank";
var link = "" + mce.selection.getContent() + "";
mce.execCommand('insertHTML', false, link); // creates new link
});
}
else {
/// THIS IS THE MISSING BIT!
};
}
You have two ways of achieving this:
When pushing the button you check for the selection parent node. If the node is a link then you can get the link information from the html a-element. To populate your dialogue you will know what to do.
The other option is to add a contextmenu on rightclick, which will provide the necessary functionalities.
Here is the plugin code for this (keep in mind that you will have to add "customcontextmenu" to the plugin-setting of your tinymce).
/**
* editor_plugin_src.js
*
* Plugin for contextmenus.
*/
(function() {
var Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM;
tinymce.PluginManager.requireLangPack('customcontextmenu');
/**
* This plugin a context menu to TinyMCE editor instances.
*
* #class tinymce.plugins.customcontextmenu
*/
tinymce.create('tinymce.plugins.customcontextmenu', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* #method init
* #param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* #param {string} url Absolute URL to where the plugin is located.
*/
init : function(ed) {
var t = this, lastRng;
t.editor = ed;
// Registiere commands
ed.addCommand('edit_inline_element', function() {
//edit_inline_element(ed, ed.right_clicked_node); //ed.right_clicked_node is the actually clicked node
//call or do whatever you need here
});
// delete link
ed.addCommand('delete_inline_element', function() {
$(ed.right_clicked_node).replaceWith($(ed.right_clicked_node).html());
});
// assign the right clicked node (it is the evt.target)
ed.onClick.add(function(ed, evt) {
if (evt.button == 2) ed.right_clicked_node = evt.target;
});
/**
* This event gets fired when the context menu is shown.
*
* #event onContextMenu
* #param {tinymce.plugins.ContextMenu} sender Plugin instance sending the event.
* #param {tinymce.ui.DropMenu} menu Drop down menu to fill with more items if needed.
*/
t.onContextMenu = new tinymce.util.Dispatcher(this);
ed.onContextMenu.add(function(ed, e) {
if (!e.ctrlKey) {
// Restore the last selection since it was removed
if (lastRng)
ed.selection.setRng(lastRng);
var menu = t._getMenu(ed);
if ((typeof menu).toLowerCase() == 'object')
{
menu.showMenu(e.clientX, e.clientY);
Event.add(ed.getDoc(), 'click', function(e) {
hide(ed, e);
});
Event.cancel(e);
}
// sonst Standardmenu anzeigen
}
});
ed.onRemove.add(function() {
if (t._menu)
t._menu.removeAll();
});
function hide(ed, e) {
lastRng = null;
// Since the contextmenu event moves
// the selection we need to store it away
if (e && e.button == 2) {
lastRng = ed.selection.getRng();
return;
}
if (t._menu) {
t._menu.removeAll();
t._menu.destroy();
Event.remove(ed.getDoc(), 'click', hide);
}
};
ed.onMouseDown.add(hide);
ed.onKeyDown.add(hide);
},
_getMenu: function(ed){
var t = this, m = t._menu, se = ed.selection, col = se.isCollapsed(), el = se.getNode() || ed.getBody(), am, p1, p2;
if (m) {
m.removeAll();
m.destroy();
}
p1 = DOM.getPos(ed.getContentAreaContainer());
p2 = DOM.getPos(ed.getContainer());
m = ed.controlManager.createDropMenu('contextmenu', {
offset_x : p1.x + ed.getParam('contextmenu_offset_x', 0),
offset_y : p1.y + ed.getParam('contextmenu_offset_y', 0),
constrain : 1
});
t._menu = m;
if ((typeof ed.right_clicked_node) !== "undefined" && ed.right_clicked_node.nodeName.toLowerCase() == 'a' )
{
m.add({
title: $(ed.right_clicked_node).attr('title'),
});
m.addSeparator();
m.add({
title: 'Edit link',
icon: 'edit_inline_element',
cmd: 'edit_link'
});
m.add({
title: 'Delete link',
icon: 'delete_inline_element',
cmd: 'delete_link'
});
t.onContextMenu.dispatch(t, m, el, col);
return m;
}
else {
// kein Menu anzeigen
return 0;
}
}
});
// Register plugin
tinymce.PluginManager.add('customcontextmenu', tinymce.plugins.customcontextmenu);
})();
I'm currently using the anythingSlider plugin, it works totally fine except when there is only one <li>.
The <li>s are generated from the database so sometimes there's only one.
However, the anythingSlider plugin still tries to slide through the <li>s, it works by sliding back to the first slide. Although this doesn't look great.
Does anybody know of a way of stopping it sliding if there's only one <li>?
-- EDIT --
Hi!
Can anybody else help with this? I've tried the solution by Greg and I've also tried:
if (banners<1) {
.anythingSlider({
startStopped: true,
buildNavigation: false
});
}
'banners' is my variable that I'm calling.
And this disables the anythingSlider function altogether.
Help please?!
-- EDIT 2 --
The original code is in the page of the html
<script type="text/javascript">
var banners=[];
banners[0]="http://image.ebuyer.com/customer/promos/UK/AcerAspire5536.jpg";
//banners[1]="http://image.ebuyer.com/customer/promos/2150/banner.jpg";
//banners[2]="http://image.ebuyer.com/customer/promos/UK/257653_FerrariOne_tb20091026.jpg";
//banners[3]="http://image.ebuyer.com/customer/promos/UK/247038_compaq_images/247038_compaq_incentive_banner20090814.jpg"; //added 03/09/2009
//banners[4]="http://image.ebuyer.com/customer/promos/UK/247858-samsung-tv-comp-tb20090817.jpg"; //added 19/08/2009
var bannerLink=[];
bannerLink[0]="http://www.ebuyer.com/product/173536";
//bannerLink[1]="/special/2150";
//bannerLink[2]="/product/172295";
//bannerLink[3]="/compaq-cash-incentive";
//bannerLink[4]="/special/2101";
var bannerAlt=[];
bannerAlt[0]="Acer Aspire 5536";
//bannerAlt[1]="The X5 range for Asus";
//bannerAlt[2]="Acer Ferrari One Laptop";
//bannerAlt[3]="Buy these three products together and claim £75 cashback";
//bannerAlt[4]="Win a Samsung 46in LCV TV";
</script>
It's then being actioned by this file: http://image.ebuyer.com/customer/promos/js/topbanners.js
// function to import css and javascript from external locations
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
// importing css and javascript
loadjscssfile("http://static.ebuyer.com/css/slider.css", "css") ////dynamically load and add this .css file
// setting the variables
var banner = document.getElementById('tehBanner');
var link = document.getElementById('tehLink');
// this function creates the tracking tags
function tracking (x) {
if (x.indexOf("?")>=0){x+='&tb='+(i+1);}else{x+='?tb='+(i+1);}
return x
}
// telling the javascript to display all available variables
for (var i in banners) {
banner.alt = bannerAlt[i];
link.href = tracking(bannerLink[i]);
banner.src = banners[i];
document.write('' + '<img src="' + banners[i] + '" id="slide-image" alt="' + bannerAlt[i] + '" />');
}
// remove the original banner
$ ('a#tehLink').parent().remove();
// hide banners to begin with
$('a.slide-link').hide();
/*
anythingSlider v1.1
By Chris Coyier: http://css-tricks.com
with major improvements by Doug Neiner: http://pixelgraphics.us/
based on work by Remy Sharp: http://jqueryfordesigners.com/
To use the navigationFormatter function, you must have a function that
accepts two paramaters, and returns a string of HTML text.
index = integer index (1 based);
panel = jQuery wrapped LI item this tab references
#return = Must return a string of HTML/Text
navigationFormatter: function(index, panel){
return index + " Panel"; // This would have each tab with the text 'X Panel' where X = index
}
*/
(function($){
$.anythingSlider = function(el, options){
// To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;
// Access to jQuery and DOM versions of element
base.$el = $(el);
base.el = el;
// Set up a few defaults
base.currentPage = 1;
base.timer = null;
base.playing = false;
// Add a reverse reference to the DOM object
base.$el.data("AnythingSlider", base);
base.init = function(){
base.options = $.extend({},$.anythingSlider.defaults, options);
// Cache existing DOM elements for later
base.$wrapper = base.$el.find('> div').css('overflow', 'hidden');
base.$slider = base.$wrapper.find('> ul');
base.$items = base.$slider.find('> li');
base.$single = base.$items.filter(':first');
// Build the navigation if needed
if(base.options.buildNavigation) base.buildNavigation();
// Get the details
base.singleWidth = base.$single.outerWidth();
base.pages = base.$items.length;
// Top and tail the list with 'visible' number of items, top has the last section, and tail has the first
// This supports the "infinite" scrolling
base.$items.filter(':first').before(base.$items.filter(':last').clone().addClass('cloned'));
base.$items.filter(':last' ).after(base.$items.filter(':first').clone().addClass('cloned'));
// We just added two items, time to re-cache the list
base.$items = base.$slider.find('> li'); // reselect
// Setup our forward/backward navigation
base.buildNextBackButtons();
// If autoPlay functionality is included, then initialize the settings
if(base.options.autoPlay) {
base.playing = !base.options.startStopped; // Sets the playing variable to false if startStopped is true
base.buildAutoPlay();
};
// If pauseOnHover then add hover effects
if(base.options.pauseOnHover) {
base.$el.hover(function(){
base.clearTimer();
}, function(){
base.startStop(base.playing);
});
}
// If a hash can not be used to trigger the plugin, then go to page 1
if((base.options.hashTags == true && !base.gotoHash()) || base.options.hashTags == false){
base.setCurrentPage(1);
};
};
base.gotoPage = function(page, autoplay){
// When autoplay isn't passed, we stop the timer
if(autoplay !== true) autoplay = false;
if(!autoplay) base.startStop(false);
if(typeof(page) == "undefined" || page == null) {
page = 1;
base.setCurrentPage(1);
};
// Just check for bounds
if(page > base.pages + 1) page = base.pages;
if(page < 0 ) page = 1;
var dir = page < base.currentPage ? -1 : 1,
n = Math.abs(base.currentPage - page),
left = base.singleWidth * dir * n;
base.$wrapper.filter(':not(:animated)').animate({
scrollLeft : '+=' + left
}, base.options.animationTime, base.options.easing, function () {
if (page == 0) {
base.$wrapper.scrollLeft(base.singleWidth * base.pages);
page = base.pages;
} else if (page > base.pages) {
base.$wrapper.scrollLeft(base.singleWidth);
// reset back to start position
page = 1;
};
base.setCurrentPage(page);
});
};
base.setCurrentPage = function(page, move){
// Set visual
if(base.options.buildNavigation){
base.$nav.find('.cur').removeClass('cur');
$(base.$navLinks[page - 1]).addClass('cur');
};
// Only change left if move does not equal false
if(move !== false) base.$wrapper.scrollLeft(base.singleWidth * page);
// Update local variable
base.currentPage = page;
};
base.goForward = function(autoplay){
if(autoplay !== true) autoplay = false;
base.gotoPage(base.currentPage + 1, autoplay);
};
base.goBack = function(){
base.gotoPage(base.currentPage - 1);
};
// This method tries to find a hash that matches panel-X
// If found, it tries to find a matching item
// If that is found as well, then that item starts visible
base.gotoHash = function(){
if(/^#?panel-\d+$/.test(window.location.hash)){
var index = parseInt(window.location.hash.substr(7));
var $item = base.$items.filter(':eq(' + index + ')');
if($item.length != 0){
base.setCurrentPage(index);
return true;
};
};
return false; // A item wasn't found;
};
// Creates the numbered navigation links
base.buildNavigation = function(){
base.$nav = $("<div id='thumbNav'></div>").appendTo(base.$el);
base.$items.each(function(i,el){
var index = i + 1;
var $a = $("<a href='#'></a>");
// If a formatter function is present, use it
if( typeof(base.options.navigationFormatter) == "function"){
$a.html(base.options.navigationFormatter(index, $(this)));
} else {
$a.text(index);
}
$a.click(function(e){
base.gotoPage(index);
if (base.options.hashTags)
base.setHash('panel-' + index);
e.preventDefault();
});
base.$nav.append($a);
});
base.$navLinks = base.$nav.find('> a');
};
// Creates the Forward/Backward buttons
base.buildNextBackButtons = function(){
var $forward = $('<a class="arrow forward">></a>'),
$back = $('<a class="arrow back"><</a>');
// Bind to the forward and back buttons
$back.click(function(e){
base.goBack();
e.preventDefault();
});
$forward.click(function(e){
base.goForward();
e.preventDefault();
});
// Append elements to page
base.$wrapper.after($back).after($forward);
};
// Creates the Start/Stop button
base.buildAutoPlay = function(){
base.$startStop = $("<a href='#' id='start-stop'></a>").html(base.playing ? base.options.stopText : base.options.startText);
base.$el.append(base.$startStop);
base.$startStop.click(function(e){
base.startStop(!base.playing);
e.preventDefault();
});
// Use the same setting, but trigger the start;
base.startStop(base.playing);
};
// Handles stopping and playing the slideshow
// Pass startStop(false) to stop and startStop(true) to play
base.startStop = function(playing){
if(playing !== true) playing = false; // Default if not supplied is false
// Update variable
base.playing = playing;
// Toggle playing and text
base.$startStop.toggleClass("playing", playing).html( playing ? base.options.stopText : base.options.startText );
if(playing){
base.clearTimer(); // Just in case this was triggered twice in a row
base.timer = window.setInterval(function(){
base.goForward(true);
}, base.options.delay);
} else {
base.clearTimer();
};
};
base.clearTimer = function(){
// Clear the timer only if it is set
if(base.timer) window.clearInterval(base.timer);
};
// Taken from AJAXY jquery.history Plugin
base.setHash = function ( hash ) {
// Write hash
if ( typeof window.location.hash !== 'undefined' ) {
if ( window.location.hash !== hash ) {
window.location.hash = hash;
};
} else if ( location.hash !== hash ) {
location.hash = hash;
};
// Done
return hash;
};
// <-- End AJAXY code
// Trigger the initialization
base.init();
};
$.anythingSlider.defaults = {
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: true, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 3000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: true, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
};
$.fn.anythingSlider = function(options){
if(typeof(options) == "object"){
return this.each(function(i){
(new $.anythingSlider(this, options));
// This plugin supports multiple instances, but only one can support hash-tag support
// This disables hash-tags on all items but the first one
options.hashTags = false;
});
} else if (typeof(options) == "number") {
return this.each(function(i){
var anySlide = $(this).data('AnythingSlider');
if(anySlide){
anySlide.gotoPage(options);
}
});
}
};
})(jQuery);
// this function wraps the elements in the neccessary tags to work with anything Slider
$ (document).ready(function() {
$('a.slide-link')
.wrap('<li class="slide-list-item"></li>');
$('li.slide-list-item')
.wrapAll('<ul id="slide-list"></ul>');
$('ul#slide-list')
.wrapAll('<div class="wrapper"></div>');
$('div.wrapper')
.wrapAll('<div class="anythingSlider internalSlider"></div>');
$('.anythingSlider')
.anythingSlider({
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: true, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 7000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: false, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
});
$('a.slide-link').show();
});
It's a bit of a hash job but works fine as long as there's more than one <li>
Try this:
// this function wraps the elements in the neccessary tags to work with anything Slider
$ (document).ready(function() {
$('a.slide-link')
.wrap('<li class="slide-list-item"></li>');
$('li.slide-list-item')
.wrapAll('<ul id="slide-list"></ul>');
$('ul#slide-list')
.wrapAll('<div class="wrapper"></div>');
$('div.wrapper')
.wrapAll('<div class="anythingSlider internalSlider"></div>');
if(banners.length > 1){
autoplayval= true;
} else {
autoplayval= false;
}
$('.anythingSlider')
.anythingSlider({
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: autoplayval, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 7000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: false, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
});
$('a.slide-link').show();
});
Changing this
$('.anythingSlider').anythingSlider({...});
to this
$('.anythingSlider:has(li:nth-child(2)').anythingSlider({...});
should do it
This assumes you don't have nested lists.
I had this problem and could only resolve this with a new version of the plugin: v1.5.3
URL: https://github.com/ProLoser/AnythingSlider/downloads
Once you've got the latest version, only change one line:
base.setCurrentPage(startPanel, false); // added to trigger events for FX code
When I have only one <li> the anythingControls element's style is display=none.
This will only activate the slider if more than 1 <LI> elements are present:
jQuery("#sliderDiv:has(>li:eq(1))").anythingSlider({...})
it assumes your HTML structure is like this:
<div id="sliderDiv">
<li>Offer 1</li>
<li>Offer 2</li>
</div>
You'll need something like
if($([ULELEMENT]).children('li').length > 1){
//Your code
}
Something along those lines. If you post your code, I can give it a try.