hey guys i am very new to js and jquery in genenral and i was just going throught the plugin code of a gallery plugin , i can across the function called _loadevents , that had the following content , see below :
this.$navPrev.on('click.gallery', function (event) {
});
this.$navNext.on('click.gallery', function (event) {
});
this.$wrapper.on('webkitTransitionEnd.gallery transitionend.gallery OTransitionEnd.gallery', function (event) {
});
now $navPrev , $navNext , and $wrapper are obviously some HTML element , now my question is about another method i came across in the same plugin , look below :
destroy: function () {
// console.log('inside destroy');
this.$navPrev.off('.gallery');
this.$navNext.off('.gallery');
this.$wrapper.off('.gallery');
}
now i see that if this function is called all the event handlers will be taken off. now , can somebody tell me what is the necessacity of such a function , does it improve a plugins efficiency ? how or when does such a function get used and is it a common practice to write e destroy function for events in plugins ?
Thank you.
Alex-z .
Destroy functions in plugins enable a developer to reset or remove a plugin from an element, restoring the element to before the plugin was initialised. This is useful if, for example, you have a gallery plugin that works and looks fantastic on desktop, but you don't want it on mobile. You can listen to resize event on window and if the window size is smaller than e.g. 710px then destroy the plugin. This will remove all the added events, undo any DOM manipulation, and restore the html elements back to how they were before the plugin was first initialised (turn-wise, if the window size is larger than 710px then initialise the plugin).
They are generally considered good practice.
Related
I have created a slider/carousel like the one below on left - Desktop view.
I would like it to be switching to Pager based slider on mobile screens - like the one on the right side.
I have used this script for desktop slider -
https://www.jqueryscript.net/rotator/Simplest-3D-Image-Carousel-Plugin-For-jQuery-Carousel-js.html
Any help will be great, Thanks!
You will have to use 2 plugins for this. As far as I can tell there is no "pager" option for the plugin you are using. And then, using JavaScript you should destroy current plugin and initialize new one. Which could also be a problem since I don't see any sort of destroy method for your plugin. So ok, it would look something like this.
function init3DSlider() {
$('.your-container').carousel({
your: 'options'
})
}
function initPagerSlider() {
$('.your-container').somePagerPlugin({
// ...your options
})
}
// Function for checking which slider should turn on.
function turnOnSliderDependingOnResolution () {
if(window.matchMedia('(min-width: 768px)').matches) {
init3DSlider()
// ...somehow destroy pager slider
} else {
initPagerSlider()
// ...somehow destroy 3d slider
}
}
// Run turnOnSliderDependingOnResolution function on window resize.
window.addEventListener('resize', turnOnSliderDependingOnResolution)
Since this 3d slider doesn't have destroy method, try using this: http://ub4.underblob.com/remove-jquery-plugin-instance/
Or you can use a more simple solution, and that is to duplicate your slider, initialize both sliders (3D and pager). And then using CSS media queries you would hide one or the other.
Not exactly optimal but it will work.
I'm using jQuery with the bxSlider plugin, here is the link to it just incase: http://bxslider.com/
I'm trying to reload the slider and my custom pager after I've removed certain slides from it.
Here is what I have tried:
$(function() {
var slider = $('#slider').bxSlider({
pagerCustom: '#bx-pager'
});
$('.list').on('click', '.delete', function() {
image = $(this).closest('li').find('[type="hidden"]');
// image.attr('id') contains a string: image-0, image-1, image-2, etc.
$('#slider, #bx-pager').find('.' + image.attr('id')).remove();
slider.reloadSlider({
pagerCustom: '#bx-pager'
}); // I have also tried: slider.reloadSlider();
});
});
It works partially. What happens is the slider gets reloaded just fine but it removes the pager completely when it runs the reload.
Thank you very much for any help.
As long as I see, this is a bug in bxSlider, in fact, when you call the reloadSlider method, internally are called the methods destroySlider and init.
In the destroySlider method the pagerEl element is destroyed, this is right if you are not using a custom one, because it is recreated programmatically in the init method, but if you are using a custom one it can't be recreated programmatically.
I ended up modifying the destroySlider method to check if a custom pager is used, in this case it must not be deleted.
Here is the before (line 1294):
if(slider.pagerEl) slider.pagerEl.remove();
And after:
if (slider.settings.pagerCustom === '') {
if(slider.pagerEl) slider.pagerEl.remove();
}
I'll post the bug on GitHub as soon as I have the time.
I have been writting HTML and CSS for a while but am new to the javascript domain. I am using the below code to control the attributes of a jQuery slider. The code works fine, but what I need to do is change some of the elements within it as the browser screen resizes (or loaded on mobile device) to enable the functionality to work correctly on smaller screens.
$(document).ready(
function() {
$(".container").wtListRotator({
screen_width:534,
screen_height:300,
item_width:210,
item_height:75,
item_display:4,
list_align:"left",
scroll_type:"mouse_move",
auto_start:true,
delay:5000,
transition:"v.slide",
transition_speed:800,
easing:"",
auto_center:true,
display_playbutton:false,
display_number:false,
display_timer: false,
display_arrow:true,
display_thumbs:true,
display_scrollbar:true,
mouseover_select:false,
pause_mouseover: true,
cpanel_mouseover:false,
text_mouseover:false,
text_effect:"fade",
text_sync:true,
cpanel_align:"TR",
timer_align:"bottom",
move_one:false,
auto_adjust:true,
shuffle:false,
play_once:false,
mousewheel_scroll:true,
block_size:75,
vert_size:50,
horz_size:50,
block_delay:35,
vstripe_delay:90,
hstripe_delay:180
});
}
);
I have already implemented media queries on the elements in the CSS so they resize and also across the rest of my site, however I am struggling to change the attributes below when the screen size/re-size event occurs and define this in the above javascript.
screen_width:534,
screen_height:300,
item_width:210,
item_height:75,
item_display:4,
Thanks
Rich
two things that might help you:
1) you can always get the current usable width/height of the browser window using window.innerWidth and window.innerHeight.
2) you can "register" a function to be called whenever the size of the window changes. Examples:
window.addEventListener("resize",nameOfFunction);
window.onresize = function() { //do stuff };
I'm happy to help if you have further questions...
EDIT: This could be seen as a pure javascript objects question. The code can be found here:
jquery.mobile-1.1.0.js
I need to access properties of a jQuery mobile JS-object but is not sure how that is possible. In the jquery.mobile-1.1.0.js and mobile.slider is the following (see extend on line 5967):
$.widget( "mobile.slider", $.mobile.widget, {
...
_create: function() {
...
$.extend( this, {
slider: slider,
handle: handle,
valuebg: valuebg,
dragging: false,
beforeStart: null,
userModified: false,
mouseMoved: false
});
Primarily the property I would like to read is the "dragging".
I know i can execute the methods using:
$("#slider").slider("refresh")
Is there a similair way to access the properties?
Thanks
How to react to user dragging the slider, without having to bind mouse-/tap-events, but instead using the JQM functionallity already in place.
To access the "dragging" variable of the JQM slider object I made an extension to the object as follows:
$(document).bind("mobileinit", function(){
$.mobile.slider.prototype.getDragging = function(){
return this.dragging;
};
});
With that in place, I can choose to react to changes only done by the user:
$("#slider").live('change',function(){
if($("#slider").slider("getDragging"))){
console.log('User is dragging slider to new value');
}
else {
console.log('Program changed value. (or user typed in visible textbox)') ;
}
});
With the slider textbox hidden, this give me the benefit of:
Using the "change"-event to react to user dragging without being triggered when my program change the slider value.
When my program is going to change the slider value, it can first check that the user is NOT currently dragging the slider.
I'm using ExtJS 3.2.1 and I need a component almost identical to the bundled HtmlEditor, with one exception: it must start editing the HTML source code directly. The reason I don't use a normal TextArea is that the user should be able to preview the result of his actions before submitting.
I've tried calling toggleSourceEdit(), as per ExtJS documentation, with no success. Debugging, I see that the editor object has the sourceEditMode property set to true, and the Source Edit button seems as if it was "pressed", but clicking on it does not render the typed HTML, and clicking it again goes to the Source Mode.
I've tried calling toggleSourceEdit() after the container show() method, on the container afterLayout listener and on the editor afterRender listener. I've tried also calling it on another button that I added to the container. The result is the same on every try.
The only other option I see is updating ExtJS to 3.3.0, but I haven't seem anything related on the changelogs. Either way, it's going to be my next step. EDIT: The app had another problems when updating, we'll make a bigger effort to update later. As of right now, we are using the HtmlEditor in its original setting.
Thanks!
ran into the same problem (using 3.3.0 by the way)
stumbled upon a fix by dumb luck. i have no idea why this works, but second time is the charm. call it twice in a row to achieve the desired effect..
HTMLEditor.toggleSourceEdit(true);
HTMLEditor.toggleSourceEdit(true);
hope that helps!
Rather calling toggleSourceEdit(), try to setup the configuration while you create HtmlEditor Object
Using toggleSourceEdit() caused some problems for me. One was that this seemed to put the editor somewhere in limbo between source edit and WYSIWYG mode unless I used a timeout of 250ms or so. It also puts the focus in that editor, and I don't want to start the form's focus in the editor, especially since it's below the fold and the browser scrolls to the focused html editor when it opens.
The only thing that worked for me was to extend Ext.form.HtmlEditor and then overwrite toggleSourceEdit, removing the focus command. Then adding a listener for toggling to the source editor when the component is initialized. This is for Ext 4.1 and up. For older versions, replace me.updateLayout() with me.doComponentLayout().
var Namespace = {
SourceEditor: Ext.define('Namespace.SourceEditor', {
extend: 'Ext.form.HtmlEditor',
alias: 'widget.sourceeditor',
initComponent: function() {
this.callParent(arguments);
},
toggleSourceEdit: function (sourceEditMode) {
var me = this,
iframe = me.iframeEl,
textarea = me.textareaEl,
hiddenCls = Ext.baseCSSPrefix + 'hidden',
btn = me.getToolbar().getComponent('sourceedit');
if (!Ext.isBoolean(sourceEditMode)) {
sourceEditMode = !me.sourceEditMode;
}
me.sourceEditMode = sourceEditMode;
if (btn.pressed !== sourceEditMode) {
btn.toggle(sourceEditMode);
}
if (sourceEditMode) {
me.disableItems(true);
me.syncValue();
iframe.addCls(hiddenCls);
textarea.removeCls(hiddenCls);
textarea.dom.removeAttribute('tabindex');
//textarea.focus();
me.inputEl = textarea;
} else {
if (me.initialized) {
me.disableItems(me.readOnly);
}
me.pushValue();
iframe.removeCls(hiddenCls);
textarea.addCls(hiddenCls);
textarea.dom.setAttribute('tabindex', -1);
me.deferFocus();
me.inputEl = iframe;
}
me.fireEvent('editmodechange', me, sourceEditMode);
me.updateLayout();
}
})
}
Then to use it:
Ext.create('Namespace.SourceEditor', {
/*regular options*/
listeners: {
initialize: function(thisEditor) {
thisEditor.toggleSourceEdit();
}
}
});
htmlEditor.toggleSourceEdit(true);
one time should be enough if you do this listening to the afterrender event of the editor.