JS Access Method from outside of script file - javascript

This one might be a silly question but I really need to fix a tiny slider issue for it's autoplay.
The problem is, are there any way of accessing already instanced object from outside of the script file itself? Note: without knowing the variable / const name of it too.
Example:
Someone from previous Dev team made a gallery of TNS / Tiny Slider like below:
var someName = tns({
container: '.carousel',
items: 3,
autoplay: true,
});
basically it just creating a tns instance from that container. In browser, it shows something like this
<div class="carousel tns-slider">
<div class="tns-item">...</div>
<div class="tns-item">...</div>
...
</div>
The problem is, the code for building that someName tns is from external url that I don't know where is it. Also, I don't know what actually the "someName" variable's name are, so it's already declared there instanced and working properly, I just need to disable the autoplay.
I've tried from documentation from https://github.com/ganlanyuan/tiny-slider
However, it always show how to destroy() or stop() or play() if I know the name of the instanced var (the "someName") while currently I don't have any access to the file nor knowing the path, I just asked to update via new JS file called updates-scripts.js. This is also demonstrated on codepen and other tutorials.
Are there any way of me to access method of it via let say jQuery('.carousel') or documentQuerySelector?
Thank you

This can be done by monkeypatching TNS. Add a setter for window.tns before the library loads. Once the library loads and assigns to the window, invoking the setter, you can assign something else to the window that intercepts the window.tns call that the external script (that you don't have any control over) uses.
Then simply access the .container property of the object passed in, and do whatever you need to do with it:
// Example code from the external script you have no control over
var slider = tns({
container: '.my-slider',
items: 3,
slideBy: 'page',
autoplay: true
});
<script>
// Insert your monkeypatching script here, before anything else
Object.defineProperty(window, 'tns', {
set(tns) {
// Delete this setter
delete window.tns;
window.tns = function(...args) {
const container = args[0]?.container;
console.log('container:', container);
return tns.apply(this, args);
};
},
configurable: true
});
</script>
<script src="https://cdn.jsdelivr.net/npm/tiny-slider#2.9.3/dist/tiny-slider.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.9.3/tiny-slider.css">
<div class="my-slider">
<div>foo</div>
<div>bar</div>
<div>baz</div>
</div>

Related

How to dynamically update google recaptcha sitekey?

I have a plain js + jQuery app with a button protected by google recaptcha, everything works as expected, but I'm failing to update the sitekey on the fly. The reason I want this is that I have a couple of environments (staging, test, production etc.) and I'd like to have a separate sitekey for specific envs (in order to separate the test stats from data from real users).
I'm able to change the attribute on my recaptcha element, but it looks like the attributes are taken by the script on initialising the whole thing, how can I refresh/reset the widget to accept the new sitekey?
I've been experimenting with reset and render methods, but to no effect so far.
<div
id="google-recaptcha"
class="g-recaptcha"
data-sitekey="this-will-be-replaced-anyways"
data-callback="onSubmit"
data-size="invisible"
></div>
if (grecaptcha) {
$('#google-recaptcha').attr({
'data-sitekey': 'my-real-sitekey'
});
}
I think you are looking for Explicitly render the reCAPTCHA widget
1.Specify your onload callback function. This function will be called by JavaScript resource(see the next step)
<script>
function onloadCallback() {
grecaptcha.render('myCaptcha1', {
'sitekey': 'sitekey value', // required
'theme': 'light', // optional
'callback': 'onloadCallback' // optional
});
}
</script>
2.Insert the JavaScript resource, setting the onload parameter to the name of your onload callback function and the render parameter to explicit.
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"></script>
3.Define the target HTML control that is supposed to be a captcha on your page.
<div id="myCaptcha1"></div>
I hope it helps you as helped me, good luck

Disable JS Popup Script On Specific Page

[!Newbie alert!] I'm using a ecommerce platform that doesn't allow me to edit the source code. I can only add new codes (html, js or css) to try to do the modifications I want. And what I want to do is to find a way to disable the script of a newsletter popup on only one specific page. The only way I thought of doing it is adding an extra JS script limiting the action of the previous script that I am not allowed to edit. Is it possible to do?
The original script for de Newsletter Popup is this:
<script type="text/javascript">
$(function() {
iniciarModalNews();
});
function iniciarModalNews() {
if (!$.cookie('showModalNews')) {
showModalNews();
};
}
function showModalNews() {
$.fancybox.open({
type: 'html',
minWidth: 270,
maxWidth: 350,
content: $('#modalNewsletter'),
beforeClose: function() {
$.cookie('showModalNews', 'hide', {
expires: 1,
path: '/'
});
}
});
}
</script>
It runs on all pages of the website and I want to exclude just one page. Is there a way to do this?
Thanks
Full Disclosure: This suggestion would not be considered a best practice but if its a one-off scenario where you don't have access to the source code it'll work.
If you only need to disable this on one page and have access to insert a block of script below the declaration of showModalNews() { ... } you can override the showModalNews() function by writing a new function with the same name. The method that calls the showModalNews method is inside an closure via IIFE (https://developer.mozilla.org/en-US/docs/Glossary/IIFE) but the method showModalNews() is NOT wrapped in a closure which would give you access to override it.
Example of the overridden method
function showModalNews() { ; }

GridStack- Setting the static grids

I am trying to make the grids static. No movement at all.
I tried:
var options = {
staticGrid: true,
};
$('.grid-stack').gridstack(options);
and also this
var options = {
setStatic: true,
};
$('.grid-stack').gridstack(options);
and this
var options = {
staticGrid: true,
};
$('.grid-stack').gridstack(options);
$('.grid-stack').data('gridstack').setStatic(true);
None of them seems to work, I used this link for documentation.
They have also mentioned a method setStatic but there are no examples of usign this method.
According to the Gridstack docs the staticGrid:true parameter is correct if you want to initialise and define the grid as STATIC at startup (your first method).
The SetStatic(true) is a function you can call on for toggling this state programatically.
If you view the source code live you will see a new CSS class has been added to the grid wrapper DIV; a class called 'grid-stack-static'. The appearance of this class confirms the parameter option staticGrid:true has been accepted and actioned.
BUT as I found myself (with v0.30 of the library), grid widgets in my initialised grid are still resizable and movable. In my opinion this suggests a bug.
You can lock down movement and resizing at a widget item level by using the item attributes data-gs-no-resize="yes" and data-gs-no-move="yes".
Seems counterproductive to have to do this if you have said 'static' already.
I have lodged an issue on Github to query this behaviour.
BTW it has been suggested to call on and use the setStatic( true ) function after grid init; as a temporary fix for this bug. Which was your third method - AND this worked for me.
Only difference between your 3rd method and mine is the function is wrapped in a document.ready function (and I am using $=jquery shortcut for convenience/compatibility on my system).
Worked:
(function ($) {
// Shortcut $=jquery
$(document).ready(function () {
// start grid
$(function () {
var options = {
staticGrid:true
};
$('.grid-stack').gridstack(options);
$('.grid-stack').data('gridstack').setStatic( true );
});
// END DOC READY
});
// SHORTCUT FIX
})( jQuery );
Just set the attribute gs-static="true"on the grid-stack's parent Grid element (on which gridstack has been initialized).
<div class="grid-stack" gs-static="true">
<div class="grid-stack-item">
<div class="grid-stack-item-content">Item 1</div>
</div>
<!-- .. and so on -->
</div

CKEditor Change Config Setting on Focus / Click

I need to be able to change the filebrowserUploadUrl of CKEditor when I change some details on the page, as the querystring I pass through is used by the custom upload process I've put in place.
I'm using the JQuery plugin. Here's my code:
$('#Content').ckeditor({
extraPlugins: 'autogrow',
autoGrow_maxHeight: 400,
removePlugins: 'resize'
});
$("#Content").ckeditorGet().on("instanceReady", function () {
this.on("focus", function () {
// Define browser Url from selected fields
this.config.filebrowserUploadUrl = filebrowserUploadUrl: '/my-path-to-upload-script/?ID1=' + $("ID1").val() + '&ID2=' + $("#ID2").val();
});
});
This works fine the first time, but if I come out of the dialogue and change the value of #ID1 and #ID2, it keeps the previous values. When I debug, the filebrowserUploadUrl is set correctly, but it doesn't affect the submission values. It seems the config values are cached.
Is there any way to change a config value on the fly?
Currently I don't see any possibility to change this URL on the fly without hacking.
Take a look at http://dev.ckeditor.com/browser/CKEditor/trunk/_source/plugins/filebrowser/plugin.js#L306
This element.filebrowser.url property is set once and as you can see few lines above it will be reused again. You can try to somehow find this element and reset this property, but not having deeper understanding of the code of this plugin I don't know how.
Second option would be to change this line #L284 to:
url = undefined;
However, I haven't check if this is the correct solution :) Good luck!
BTW. Feel free to fill an issue on http://dev.ckeditor.com.
I solved this by reloading the editor whenever a change occurred; I actually went through the source code for the browser plugin etc, but couldn't get any changes to work (and of course, I really didn't want to change anything for future upgrades).
function setFileBrowserUrl() {
// Remove editor instance
$("#Content").ckeditorGet().destroy();
// Recreate editor instance (needed to reset the file browser url)
createEditor();
}
function createEditor() {
$('#Content').ckeditor({
filebrowserUploadUrl: '/my-path-to-upload-script/?ID1=' + $("ID1").val() + '&ID2=' + $("#ID2").val(),
extraPlugins: 'autogrow',
autoGrow_maxHeight: 400,
removePlugins: 'resize'
});
}
Then I call setFileBrowserUrl every time the relevant elements on the page change. Not ideal, but it works for my purposes :)

jQuery mobile 1.1.0 slider: JS-object properties access?

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.

Categories

Resources