I have below code for dragscroll which runs automatically when page load.
But I want to call this function manually because I'm uppending the html using DOM element.
I have tried with window.factory as well as window.reset but it is not working for me.
My Javascript module file:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports'], factory);
} else if (typeof exports !== 'undefined') {
factory(exports);
} else {
factory((root.dragscroll = {}));
}
}(this, function (exports) {
var _window = window;
var _document = document;
var mousemove = 'mousemove';
var mouseup = 'mouseup';
var mousedown = 'mousedown';
var EventListener = 'EventListener';
var addEventListener = 'add'+EventListener;
var removeEventListener = 'remove'+EventListener;
var newScrollX, newScrollY;
var dragged = [];
var reset = function(i, el) {
for (i = 0; i < dragged.length;)
{
<some code>
}
// cloning into array since HTMLCollection is updated dynamically
dragged = [].slice.call(_document.getElementsByClassName('dragscroll'));
for (i = 0; i < dragged.length;)
{
<some code>
}, 0
);
_window[addEventListener](
mouseup, cont.mu = function() {pushed = 0;}, 0
);
_window[addEventListener](
mousemove,
cont.mm = function(e) {
if (pushed) {
(scroller = el.scroller||el).scrollLeft -=
newScrollX = (- lastClientX + (lastClientX=e.clientX));
scroller.scrollTop -=
newScrollY = (- lastClientY + (lastClientY=e.clientY));
if (el == _document.body) {
(scroller = _document.documentElement).scrollLeft -= newScrollX;
scroller.scrollTop -= newScrollY;
}
}
}, 0
);
})(dragged[i++]);
}
}
if (_document.readyState == 'complete') {
reset();
} else {
_window[addEventListener]('load', reset, 0);
}
exports.reset = reset;
}));
})
I want to call above function manually.
Can you try with
window.dragscroll.reset();
this will call your reset function manually.
Let me know if it helps.
This looks like a standard JavaScript module that exports a reset() method. Depending on your environment you can load this module, e.g with CommonJS it would be
const module = require('name/path/of_your_module_file');
and then to call it when the DOM load is complete with jQuery:
$(() => {
module.reset();
});
Related
I have been searching for all available solutions
This is the best so far i could find but it doesn't work as it should be
It works for first few images then stops. Then i refresh page, works for few more images and then stops again.
So basically what i want to achieve is, give like a 100 images to a function, it starts downloading them 1 by 1
So browser caches those images and those images are not downloaded on other pages and instantly displayed
I want this images to be cached on mobile as well
Here my javascript code that i call. Actually i have more than 100 images but didn't put all here
I accept both jquery and raw javascript solutions doesn't matter
(function() {
'use strict';
var preLoader = function(images, options) {
this.options = {
pipeline: true,
auto: true,
/* onProgress: function(){}, */
/* onError: function(){}, */
onComplete: function() {}
};
options && typeof options == 'object' && this.setOptions(options);
this.addQueue(images);
this.queue.length && this.options.auto && this.processQueue();
};
preLoader.prototype.setOptions = function(options) {
// shallow copy
var o = this.options,
key;
for (key in options) options.hasOwnProperty(key) && (o[key] = options[key]);
return this;
};
preLoader.prototype.addQueue = function(images) {
// stores a local array, dereferenced from original
this.queue = images.slice();
return this;
};
preLoader.prototype.reset = function() {
// reset the arrays
this.completed = [];
this.errors = [];
return this;
};
preLoader.prototype.load = function(src, index) {
console.log("downloading image " + src);
var image = new Image(),
self = this,
o = this.options;
// set some event handlers
image.onerror = image.onabort = function() {
this.onerror = this.onabort = this.onload = null;
self.errors.push(src);
o.onError && o.onError.call(self, src);
checkProgress.call(self, src);
o.pipeline && self.loadNext(index);
};
image.onload = function() {
this.onerror = this.onabort = this.onload = null;
// store progress. this === image
self.completed.push(src); // this.src may differ
checkProgress.call(self, src, this);
o.pipeline && self.loadNext(index);
};
// actually load
image.src = src;
return this;
};
preLoader.prototype.loadNext = function(index) {
// when pipeline loading is enabled, calls next item
index++;
this.queue[index] && this.load(this.queue[index], index);
return this;
};
preLoader.prototype.processQueue = function() {
// runs through all queued items.
var i = 0,
queue = this.queue,
len = queue.length;
// process all queue items
this.reset();
if (!this.options.pipeline)
for (; i < len; ++i) this.load(queue[i], i);
else this.load(queue[0], 0);
return this;
};
function checkProgress(src, image) {
// intermediate checker for queue remaining. not exported.
// called on preLoader instance as scope
var args = [],
o = this.options;
// call onProgress
o.onProgress && src && o.onProgress.call(this, src, image, this.completed.length);
if (this.completed.length + this.errors.length === this.queue.length) {
args.push(this.completed);
this.errors.length && args.push(this.errors);
o.onComplete.apply(this, args);
}
return this;
}
if (typeof define === 'function' && define.amd) {
// we have an AMD loader.
define(function() {
return preLoader;
});
} else {
this.preLoader = preLoader;
}
}).call(this);
// Usage:
$(window).load(function() {
new preLoader([
'//static.pokemonpets.com/images/attack_animations/absorb1.png',
'//static.pokemonpets.com/images/attack_animations/bleeding1.png',
'//static.pokemonpets.com/images/attack_animations/bug_attack1.png',
'//static.pokemonpets.com/images/attack_animations/bug_attack2.png',
'//static.pokemonpets.com/images/attack_animations/bug_boost1.png',
'//static.pokemonpets.com/images/attack_animations/burned1.png',
'//static.pokemonpets.com/images/attack_animations/change_weather_cloud.png',
'//static.pokemonpets.com/images/attack_animations/confused1.png',
'//static.pokemonpets.com/images/attack_animations/copy_all_enemy_moves.png',
'//static.pokemonpets.com/images/attack_animations/copy_last_move_enemy.png',
'//static.pokemonpets.com/images/attack_animations/cringed1.png',
'//static.pokemonpets.com/images/attack_animations/critical1.png',
'//static.pokemonpets.com/images/attack_animations/cure_all_status_problems.png',
'//static.pokemonpets.com/images/attack_animations/dark_attack1.png',
'//static.pokemonpets.com/images/attack_animations/dark_attack2.png',
'//static.pokemonpets.com/images/attack_animations/dark_attack3.png',
'//static.pokemonpets.com/images/attack_animations/dark_boost1.png',
'//static.pokemonpets.com/images/attack_animations/double_effect.png',
'//static.pokemonpets.com/images/attack_animations/dragon_attack1.png',
'//static.pokemonpets.com/images/attack_animations/dragon_attack2.png',
'//static.pokemonpets.com/images/attack_animations/dragon_attack3.png',
'//static.pokemonpets.com/images/attack_animations/dragon_attack4.png'
]);
});
Something like this?
I do not have time to make it pretty.
const pref = "https://static.pokemonpets.com/images/attack_animations/";
const defa = "https://imgplaceholder.com/20x20/000/fff/fa-image";
const images=['absorb1','bleeding1','bug_attack1','bug_attack2','bug_boost1','burned1','change_weather_cloud','confused1','copy_all_enemy_moves','copy_last_move_enemy','cringed1','critical1','cure_all_status_problems','dark_attack1','dark_attack2','dark_attack3','dark_boost1','double_effect','dragon_attack1','dragon_attack2','dragon_attack3','dragon_attack4'];
let cnt = 0;
function loadIt() {
if (cnt >= images.length) return;
$("#imagecontainer > img").eq(cnt).attr("src",pref+images[cnt]+".png"); // preload next
cnt++;
}
const $cont = $("#container");
const $icont = $("#imagecontainer");
// setting up test images
$.each(images,function(_,im) {
$cont.append('<img src="'+defa+'" id="'+im+'"/>'); // actual images
$icont.append('<img src="'+defa+'" data-id="'+im+'"/>'); // preload images
});
$("#imagecontainer > img").on("load",function() {
if (this.src.indexOf("imgplaceholder") ==-1) { // not for the default image
$("#"+$(this).attr("data-id")).attr("src",this.src); // copy preloaded
loadIt(); // run for next entry
}
})
loadIt(); // run
#imagecontainer img { height:20px }
#container img { height:100px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container"></div>
<hr/>
<div id="imagecontainer"></div>
My Code works for 1 canvas. But I need this implementation to work for 2 of canvas.
So I tried
var SIGNATURE_2 = new CLIPBOARD_CLASS("signatureCanvas2", true);
The problem is that this always pastes the image in the first canvas, I just need to press Ctrl+V.
How do I paste ONLY when the canvas is focused or hovered?
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy paste Image to Canvas
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var SIGNATURE = new CLIPBOARD_CLASS("signatureCanvas", true);
var SIGNATURE_2 = new CLIPBOARD_CLASS("signatureCanvas2", true);
/**
* image pasting into canvas
*
* #param {string} canvas_id - canvas id
* #param {boolean} autoresize - if canvas will be resized
*/
function CLIPBOARD_CLASS(canvas_id, autoresize) {
var _self = this;
var canvas = document.getElementById(canvas_id);
var ctx = document.getElementById(canvas_id).getContext("2d");
var ctrl_pressed = false;
var command_pressed = false;
var paste_event_support;
var pasteCatcher;
//handlers
document.addEventListener('keydown', function (e) {
_self.on_keyboard_action(e);
}, false); //firefox fix
document.addEventListener('keyup', function (e) {
_self.on_keyboardup_action(e);
}, false); //firefox fix
document.addEventListener('paste', function (e) {
_self.paste_auto(e);
}, false); //official paste handler
//constructor - we ignore security checks here
this.init = function () {
pasteCatcher = document.createElement("div");
pasteCatcher.setAttribute("id", "paste_ff");
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;width:10px;margin-left:-20px;';
document.body.appendChild(pasteCatcher);
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (paste_event_support === true || ctrl_pressed == false || mutation.type != 'childList'){
//we already got data in paste_auto()
return true;
}
//if paste handle failed - capture pasted object manually
if(mutation.addedNodes.length == 1) {
if (mutation.addedNodes[0].src != undefined) {
//image
_self.paste_createImage(mutation.addedNodes[0].src);
}
//register cleanup after some time.
setTimeout(function () {
pasteCatcher.innerHTML = '';
}, 20);
}
});
});
var target = document.getElementById('paste_ff');
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
}();
//default paste action
this.paste_auto = function (e) {
paste_event_support = false;
if(pasteCatcher != undefined){
pasteCatcher.innerHTML = '';
}
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
paste_event_support = true;
//access data directly
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
//image
var blob = items[i].getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
this.paste_createImage(source);
}
}
e.preventDefault();
}
else {
//wait for DOMSubtreeModified event
}
}
};
//on keyboard press
this.on_keyboard_action = function (event) {
var k = event.keyCode;
//ctrl
if (k == 17 || event.metaKey || event.ctrlKey) {
if (ctrl_pressed == false)
ctrl_pressed = true;
}
//v
if (k == 86) {
if (document.activeElement != undefined && document.activeElement.type == 'text') {
//let user paste into some input
return false;
}
if (ctrl_pressed == true && pasteCatcher != undefined){
pasteCatcher.focus();
}
}
};
//on kaybord release
this.on_keyboardup_action = function (event) {
//ctrl
if (event.ctrlKey == false && ctrl_pressed == true) {
ctrl_pressed = false;
}
//command
else if(event.metaKey == false && command_pressed == true){
command_pressed = false;
ctrl_pressed = false;
}
};
//draw pasted image to canvas
this.paste_createImage = function (source) {
var pastedImage = new Image();
pastedImage.onload = function () {
if(autoresize == true){
//resize
canvas.width = pastedImage.width;
canvas.height = pastedImage.height;
}
else{
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(pastedImage, 0, 0);
};
pastedImage.src = source;
};
}
.signatureCanvas {
border:1px solid #027C8C;
width: 100%;
max-height:200px;
}
<canvas id="signatureCanvas" class="signatureCanvas"></canvas>
<canvas id="signatureCanvas2" class="signatureCanvas"></canvas>
PS: Please just open snipping tool on windows and copy paste an image to test
Detect if mouse is over canvas, and store it in a variable.
var over_canvas=false;
document.getElementById("signatureCanvas").addEventListener("mouseover", function (i) {
over_canvas=true;
});
document.getElementById("signatureCanvas").addEventListener("mouseout", function (i) {
over_canvas=false;
});
When pasting, check if mouse is over canvas by changing your paste function to:
document.addEventListener('paste', function (e) {
if (over_canvas){
_self.paste_auto(e);
}
}, false);
I have this code in Javascript:
var menuPosition = $('.scroll-nav').offset().top;
var menuPos = 110;
if (menuPosition = menuPos) {
$('.scroll-nav').addClass('stick-menu');
$('.fake-nav').removeClass('stick-menu');
}
My idea is when the position of the menuPostion be in 110px stick the .scroll-nav... but when I load the page the code is executed automaticaly.
Any idea?
EDIT
Solution to my question:
var distance = $('.scroll-nav').offset().top + 200, //+200 BECAUSE JQUERY OFFSET DONT GET MARGINS AND PADDINGS (+200 is an estimative of my total)
$window = $(window);
$window.scroll(function() {
if ( $window.scrollTop() >= distance ) {
$('.scroll-nav').addClass('is-sticky');
$('.fake-nav').removeClass('is-sticky');
}
if ( $window.scrollTop() <= distance ) {
$('.scroll-nav').removeClass('is-sticky');
$('.fake-nav').addClass('is-sticky');
}
});
Wrap this into a function and add event listener on scroll which would fire it when scrolled.
So you want to add a class if the menuPos is exactly 110? You can use:
$(document).ready(callback)
And instead of callback you can write anonymous function that will be executed when the page is loaded. You can attach a function on this item in particular.
You can write and a custom eventListener that will catch a position change on an item:
jQuery.fn.onPositionChanged = function (trigger, millis) {
if (millis == null) millis = 100;
var o = $(this[0]); // our jquery object
if (o.length < 1) return o;
var lastPos = null;
var lastOff = null;
setInterval(function () {
if (o == null || o.length < 1) return o; // abort if element is non existend eny more
if (lastPos == null) lastPos = o.position();
if (lastOff == null) lastOff = o.offset();
var newPos = o.position();
var newOff = o.offset();
if (lastPos.top != newPos.top || lastPos.left != newPos.left) {
$(this).trigger('onPositionChanged', { lastPos: lastPos, newPos: newPos });
if (typeof (trigger) == "function") trigger(lastPos, newPos);
lastPos = o.position();
}
if (lastOff.top != newOff.top || lastOff.left != newOff.left) {
$(this).trigger('onOffsetChanged', { lastOff: lastOff, newOff: newOff});
if (typeof (trigger) == "function") trigger(lastOff, newOff);
lastOff= o.offset();
}
}, millis);
return o;
};
you can trigger this event like this:
$(document).ready(function() {
$('.scroll-nav').onPositionChanged(someFunctionForExample());
}
*the condition in the if statement should be with '=='
P.s. I hope I understood your problem right. If I did not. Share some more thoughts on this so we can help
This problem is with 1.0
I have the following html in a polymer element
<iron-selector attr-for-selected="step-number" selected="{{stepNumber}}">
<section step-number="1">
<page-1 id="page1"></page-1>
</section>
<section step-number="2">
<page-2 id="page2"></page-2>
</section>
<section step-number="3">
<page-3 id="page3"></page-3>
</section>`
page 1 fires an event - event1, page-2 fires event2. Here's my javascript for the polymer element
function () {
Polymer({
is: 'name',
ready: function() {
this.stepNumber = 1;
var firstStep = this.$.page1;
var secondStep = this.$.page2;
var thirdStep = this.$.page3;
var that = this;
firstStep.addEventListener('event1', function(e) {
that.stepNumber = 2; // WORKING
});
secondStep.addEventListener('event2', function(e) {
that.stepNumber = 3; // NOT WORKING
});
}
});
Here's the interesting part:
Both events get fired, the value for stepNumber gets updated inside event1 handler but not inside event2 handler. I also debugged this and inside the event2 handler the value of stepNumber DOES get updated (page-3 element gets the tag "iron-selected") but it doesn't persist. After a bunch of polymer code executes the value is back to 2.
Looks like a bug in polymer?
Some info from the debugger -
polymer code that's executing after the event method is basically the code that executes the event handler, followed by a "gesture recognition" code (which i guess is the on-click), where the tag iron-selector is added to page-2 section
var recognizers = Gestures.recognizers;
for (var i = 0, r; i < recognizers.length; i++)
{
r = recognizers[i];
if (gs[r.name] && !handled[r.name]) {
handled[r.name] = true; // in here for r.name = "tap"
r[type](ev); // type = click. ev = MouseEvent. ev.target = iron-selector
}
}
Digging deeper -
this creates an event handler
_createEventHandler: function(node, eventName, methodName) {
var host = this;
return function(e) {
if (host[methodName]) {
hostmethodName;
} else {
host._warn(host._logf("_createEventHandler", "listener method " + methodName + " not defined"));
}
};
host is iron-selector. methodName is _activateHandler where _itemActivate is called for section of page-2
_activateHandler: function(e) {
// TODO: remove this when https://github.com/Polymer/polymer/issues/1639 is fixed so we
// can just remove the old event listener.
if (e.type !== this.activateEvent) {
return;
}
var t = e.target;
var items = this.items;
while (t && t != this) {
var i = items.indexOf(t);
if (i >= 0) {
var value = this._indexToValue(i);
this._itemActivate(value, t);
return;
}
t = t.parentNode;
}
},
_itemActivate: function(value, item) {
if (!this.fire('iron-activate',
{selected: value, item: item}, {cancelable: true}).defaultPrevented) {
this.select(value);
}
_itemActivate is where the value of stepNumber changes to 2
Clear the activateEvent property (activate-event attribute) of the iron-selector, like this:
<iron-selector attr-for-selected="step-number" selected="{{stepNumber}}" activate-event="">
Try this:
Polymer({
is: 'name',
ready: function() {
this.stepNumber = 1;
var firstStep = this.$.page1;
var secondStep = this.$.page2;
var thirdStep = this.$.page3;
var that = this;
firstStep.addEventListener('event1', function(e) {
that.async(function(){
that.stepNumber = 2;
},0);
});
secondStep.addEventListener('event2', function(e) {
that.async(function(){
that.stepNumber = 3;
},0);
});
}
});
Ok! I'm working on a wordpress site, and everything this javascript add on is supposed to do, it does...But, when I inspect element via safari develop, I notice that it's loading all of my headers scripts,meta,styles etc. into the body as well as the head. I can't figure out why. Here's what the script looks like:
function ft(params) {
var ol= document.addEventListener?"DOMContentLoaded":"load"; //on load event
var navB = params.navB || "reverse slide"; //backbrowser button effect, default empty
var but = params.but || false; //Allow transitions on input type button
var cBa = params.cBa || function() {};
function aDL(url, t, o) { //Ajax Div Load
if (window.XMLHttpRequest) {
r = new XMLHttpRequest();
} else if (window.ActiveXObject) {
r = new ActiveXObject("Microsoft.XMLHTTP");
}
if (r != undefined) {
r.onreadystatechange = function() {Ol(r, t, o);};
r.open("GET", url, true);
r.send("");
}
}
function Ol(r, t, o) { //On load div
if (r.readyState == 4) {
if (r.status == 200 || r.status == 0) {
t.innerHTML = r.responseText;
o();
} else {
t.innerHTML="Error:\n"+ r.status + "\n" +r.statusText;
}
}
}
function DE() //Div Effect
{
var dochtml = document.body.innerHTML;
document.body.innerHTML = "";
var d1 = document.createElement("div");
d1.id = "d1";
d1.style.zIndex = 2;
d1.style.position = "absolute";
d1.style.width = "100%";
d1.style.height = "100%";
d1.style.left = "0px";
d1.style.top = "0px";
document.body.appendChild(d1);
d1.innerHTML = dochtml;
var d2 = document.createElement("div");
d2.id = "d2";
d2.style.zIndex = 1;
d2.style.position = "absolute";
d2.style.width = "100%";
d2.style.height = "100%";
d2.style.left = "0px";
d2.style.top = "0px";
document.body.appendChild(d2);
return {d1: d1, d2: d2 };
}
function timeOuts(e, d1,d2)
{
setTimeout(function() { d1.className = e + " out"; }, 1);
setTimeout(function() { d2.className = e + " in"; }, 1);
setTimeout(function() {
document.body.innerHTML = d2.innerHTML;
cBa();
}, 706);
}
function slideTo(href, effect, pushstate)
{
var d = DE();
var d1 = d.d1;
var d2 = d.d2;
aDL(href, d2,
function() {
if (pushstate && window.history.pushState) window.history.pushState("", "", href);
timeOuts(effect,d1,d2);
}
);
}
function dC(e){ //Detect click event
var o;
var o=e.srcElement || e.target;
var tn = o.tagName.toLowerCase();
if (!but || tn!="input" || o.getAttribute("type")!="button") //if it is not a button
{
//try to find an anchor parent
while (tn!=="a" && tn!=="body")
{
o = o.parentNode;
tn = o.tagName.toLowerCase();
}
if (tn==="body") return;
}
var t = o.getAttribute("data-ftrans");
if (t)
{
e.preventDefault();
var hr = o.getAttribute("href") || o.getAttribute("data-href");
if (hr) slideTo(hr, t, true);
}
}
function aE(ev, el, f) { //Add event
if (el.addEventListener) // W3C DOM
el.addEventListener(ev,f,false);
else if (el.attachEvent) { // IE DOM
var r = el.attachEvent("on"+ev, f);
return r;
}
}
aE("click", window, dC);
aE(ol, document, //On load
function(ev)
{
aE("popstate", window, function(e) { //function to reload when back button is clicked
slideTo(location.pathname, navB, false);
});
}
);
}
here is the link to the site: http://www.fasw.ws/faswwp/non-jquery-page-transitions-lightweight/
I assume that thats not supposed to happen. So im trying to figure out how to keep it clean, and keep the head files loaded in the head, and only load the page content. I cannot figure this one out, some help from the pros is needed :)
FASW comes with two functions that serves as "hooks" both before and after initializing the component. you can do it like this:
(function inittrans()
{
initComponents();
var params = { /*put your options here*/ };
new ft(params);
})();
function onTransitionFinished()
{
initComponents();
}
function initComponents() {
// here is where you put your "other" javascript codes
}
Notice how your javascript codes are executed after loading your initial page and once again after the transition happened. Anyway, this is how I got the work around on it 'coz javascript codes just won't work as they are loaded by FASW via Ajax on-the-fly.