Mini Refactoring Javascript Code - javascript

I want to optimize my Js code, at the moment i am rewriting the same function to launch a game in a popup. The only difference between the functions (open_web_client, open_web_client_2) is the openPopup size
I would like to use the same function for both games launched in the pop up, how can i use just a function for both in order to avoid repeating all the code?
This is the code
$(document).ready(function() {
web_client();
});
var web_client = function() {
var open_web_client = function(e) {
e.preventDefault();
if (!app.userIsLoggedIn()) {
app.showLoginPopup(translate.login_required_to_play_for_real);
} else {
if (Utils.analytics_enabled()) {
Utils.analytics_track_click('Play', $(this).attr("data-game-name"));
}
new GameWindow($(this).attr('href'), 'LOBBY').openPopup('1100x800');
}
}
var open_web_client_2 = function(e){
e.preventDefault();
if(!app.userIsLoggedIn()){
app.showLoginPopup(translate.login_required_to_play_for_real);
} else {
if(Utils.analytics_enabled()){
Utils.analytics_track_click('Play', $(this).attr("data-game-name"));
}
new GameWindow($(this).attr('href'), 'LOBBY').openPopup('1024x768');
}
}
if ($("a.ea_client").size() > 0) {
$('a.ea_client').on("click", open_web_client);
$('a.oneworks_client').on("click", open_web_client_2);
}
};

The only difference between the two functions is the value that is passed to openpopup.
So create a common function and pass the dimensions to the event handler.
var open_web_client = function(e) {
e.preventDefault();
if (!app.userIsLoggedIn()) {
app.showLoginPopup(translate.login_required_to_play_for_real);
} else {
if (Utils.analytics_enabled()) {
Utils.analytics_track_click('Play', $(this).attr("data-game-name"));
}
//here the hardcoded value is replaced with e.data.dim
new GameWindow($(this).attr('href'), 'LOBBY').openPopup(e.data.dim);
}
};
then modify the handler code to pass the dimensions uniquely
$('a.ea_client').on("click",{dim:'1100x800'}, open_web_client);
$('a.oneworks_client').on("click",{dim:'1024x768'}, open_web_client);
arguments passed this way to handlers can be accessed through data property present in the event object.

The only difference between the functions (open_web_client, open_web_client_2) is the openPopup size
That is basically begging to become a parameter of your function:
function open_web_client(e, size) {
e.preventDefault();
if (!app.userIsLoggedIn()) {
app.showLoginPopup(translate.login_required_to_play_for_real);
} else {
if (Utils.analytics_enabled()) {
Utils.analytics_track_click('Play', $(this).attr("data-game-name"));
}
new GameWindow($(this).attr('href'), 'LOBBY').openPopup(size);
}
}
$('a.ea_client').on("click", function(e) {
open_web_client(e, '1100x800');
});
$('a.oneworks_client').on("click", function(e) {
open_web_client(e, '1024x768');
});
A littlebit more advanced technique is to use a closure, with a function that creates the listener:
function make_web_client_opener(size) {
return function open_web_client(e) {
e.preventDefault();
if (!app.userIsLoggedIn()) {
app.showLoginPopup(translate.login_required_to_play_for_real);
} else {
if (Utils.analytics_enabled()) {
Utils.analytics_track_click('Play', $(this).attr("data-game-name"));
}
new GameWindow($(this).attr('href'), 'LOBBY').openPopup(size);
}
};
}
$('a.ea_client').on("click", make_web_client_opener('1100x800'));
$('a.oneworks_client').on("click", make_web_client_opener('1024x768'));

Related

How to change image and text at the same time on click

I'm trying to change my text and image on click (mobile only) but it's not working. Only the image can be changed with the function I wrote. Could anyone help me with that, please?
Here is the live code: https://codepen.io/oleanderek/pen/OdNzME
document.querySelectorAll(".nav__label").forEach((el) => {
el.addEventListener('click', changeArrow);
el.addEventListener('click', changeText);
});
function changeArrow() {
var arrow = this.getElementsByClassName('arrow')[0];
if (arrow.classList.contains("down-arrow")) {
arrow.classList.remove("down-arrow");
arrow.classList.add("up-arrow");
} else if (arrow.classList.contains("up-arrow")) {
arrow.classList.remove("up-arrow");
arrow.classList.add("down-arrow");
}
}
function changeText() {
var changeText = this.getElementsByClassName('showText')[0];
if (changeText.classList.contains("showText")) {
arrow.classList.remove("showText");
arrow.classList.add("hideText");
} else if (changeText.classList.contains("hideText")) {
arrow.classList.remove("hideText");
arrow.classList.add("showText");
}
}
If you delete the class to change, the variable you define remains undefined. Therefore, you must define a class that you will not change. I added newClass This works fine.
HTML
<p class="newClass showText">.</p>
Javascript
document.querySelectorAll(".nav__label").forEach((el) => {
el.addEventListener('click', changeArrow);
el.addEventListener('click', changeText);
});
function changeArrow() {
var arrow = this.getElementsByClassName('arrow')[0];
if (arrow.classList.contains("down-arrow")) {
arrow.classList.remove("down-arrow");
arrow.classList.add("up-arrow");
} else if (arrow.classList.contains("up-arrow")) {
arrow.classList.remove("up-arrow");
arrow.classList.add("down-arrow");
}
}
function changeText() {
var changeText = document.querySelector(".newClass");
if (changeText.classList.contains("showText")) {
changeText.classList.remove("showText");
changeText.classList.add("hideText");
} else if (changeText.classList.contains("hideText")) {
changeText.classList.remove("hideText");
changeText.classList.add("showText");
}
}

custom when statement not firing functions

I am trying to make a when statement but it is not working as planned. Basically its a function to call another function when try. First before I explain further here is the syntax
when(function() {
//code here
});
Now basically... Think this way.. We have a progressbar.. We also have a custom event such as...
var pBarEvent = document.createEvent('Event');
pBarEvent.initEvent('pbardone', true, true);
document.addEventListener('pbardone', function() {
//code here
});
//if progress bar reaches 100 dispatchEvent
if (document.querySelector(".progress-bar").style.width === 100 + "%")
{
document.dispatchEvent(pBarEvent);
}
Now that piece of code is an example. If the document loads and its for instance at 50% it wont trigger until you add another event such as keydown or click. I dont want to do that I want to do.... "when" progress bar width equals 100% trigger it. Thats basically what needs to happen. So here is the code for the when statement so far (keep in mind its not the best looking one. As I dont normally do this but I wanted to keep this dynamic and who knows someone who later wants to do this can look at this question)
when function
function when(func)
{
var nowActive = false;
if (!typeof func === 'undefined')
{
func = new Function();
}
if (func)
{
nowActive = true;
clearInterval(whenStatementTimer);
}
else
{
nowActive = false;
var whenStatementTimer = setInterval(function() {
switch(func)
{
case true:
{
nowActive = true;
when();
break;
}
case false:
{
nowActive = false;
when();
break;
}
}
}, 1000);
}
if (nowActive === true)
{
func();
}
}
Now this does not work when I go to try something like....
when(function() {
SmartLeadJS.SmartLeadEvents.customEvents.progressBarFull(function() {
alert("100%");
SmartLeadJS.SmartLeadAds.LeadView.ChromeExtension.General.DynamicStyles.$.style("body", "background", "black");
});
});
It does not trigger. I need help possibly getting this when statement to work. What am I doing wrong? What can I do to fix it? No errors get thrown but it never fires.
edit based on answer
Function tried
function when(currentValue)
{
try
{
var o = {};
o.currentValue = currentValue;
o.do = function(func)
{
if (!typeof func === 'undefined')
{
func = new Function();
}
if (this.currentValue)
{
func();
}
else
{
setTimeout(this.do(func), 100);
}
};
return o;
}
catch(e)
{
console.log(e);
}
}
used as
when(true).do(function() {
SmartLeadJS.SmartLeadEvents.customEvents.progressBarFull(function() {
alert("This divs going through changes!!");
SmartLeadJS.SmartLeadAds.LeadView.ChromeExtension.General.DynamicStyles.$.style(".div", "background", "black");
});
});
This does not work. It never fires. But if I use a onclick listener as such it fires
document.addEventListener("click", function() {
SmartLeadJS.SmartLeadEvents.customEvents.progressBarFull(function() {
alert("This divs going through changes!!");
SmartLeadJS.SmartLeadAds.LeadView.ChromeExtension.General.DynamicStyles.$.style(".div", "background", "black");
});
}, false);
function when(statement){
o={};
o.statement=statement;
o.do=function(func){
awhen(this.statement,func);
};
return o;
}
function awhen(statement,func){
if(eval(statement)){
func();
}else{
window.setTimeout(function(){awhen(statement,func);},100);
}
}
Use:
when("true").do(function(){});
It works now :) . Its important to put the condition in ""!

How do I capture if the enter key has been pressed?

I'm trying to capture if the enter key has been pressed and execute a search. This is the viewmodel for the search page.
(function ()
{
a.viewModels.userSearch = function (view, params) {
$view = $(view);
var self = a.viewModel({
users: a.collection({
url: '/admin/Account/SearchUsers',
query: {
SearchText: null
}
}).fetch(),
setPageIndex: setPageIndex,
search: search
});
$view.keypress(function (e) {
if (e.keyCode == 13) {
self.search(e);
}
});
function search(e) {
self.users.query.rowCount = 0;
self.users.query.pageIndex = 1;
self.users.fetch();
}
function setPageIndex(e) {
e.preventDefault();
self.users.query.set('pageIndex', $(e.currentTarget).data('page-index'));
self.users.fetch();
}
return self;
}
Now, this works. The problem is that it works only after pressing the 'Enter' key 2 times. Seems like I'm missing something related to the scope but js ain't my cup of tea.
If it is of any help, here goes my view model function:
function viewModel(viewModelConfig) {
var self = kendo.observable($.extend({
busy: 0,
resultMessage: null,
clearResultMessage: clearResultMessage
}, viewModelConfig));
self.bind('change', onChange);
function onChange(change) {
var errorProp, errorMsg, infoProp, infoMsg;
if (change.field.endsWith('.busy')) {
if (self.get(change.field))
self.set('busy', self.busy + 1);
else if (self.busy > 0)
self.set('busy', self.busy - 1);
}
else if (change.field.endsWith('.resultMessage')) {
var data = self.get(change.field);
self.set('resultMessage', data);
}
}
function clearResultMessage(e)
{
if (e) e.preventDefault();
self.set('resultMessage', null);
return false;
}
return self;
}
I have a similar setup on my site, and using MVVM, just add the custom enter binding within the data-bind attribute of the element to link to the function within the view-model you wish to execute.
The code to add the custom binder is as such:
kendo.data.binders.widget.enter = kendo.data.Binder.extend({
init: function(element, bindings, options) {
kendo.data.Binder.fn.init.call(this, element, bindings, options);
var binding = this.bindings.enter;
$(element.element).keyup(function(e) {
if( e.which === 13 )
bindings.get();
});
},
refresh: $.noop
});

Jquery function is starting on click but I need to stop it

I always wonder that onclick functions start to a javascript or jQuery, but How does it stop? Finally, I faced with a function in my learning progress. May you help me to find a solution?
I want to stop this function on another onclick:
function live_preview() {
var icon = document.getElementById('LivePreIcon');
if (icon.classList.contains('fa-eye-slash')) {
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
$('#result').keyup(function () {
$('#dialog').html($(this).val());
});
return;
}
if (icon.classList.contains('fa-eye')) {
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
// Stop the jquery function here
return;
}
}
var play=0;
function live_preview() {
var icon = document.getElementById('LivePreIcon');
var play;
if(!play){
if (icon.classList.contains('fa-eye-slash')) {
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
$('#result').keyup(function () {
$('#dialog').html($(this).val());
play = 1;
});
return;
}
}
else{
if (icon.classList.contains('fa-eye')) {
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
play=0;
return false;
// Stop the jquery function here
}
}
}

Self invoking function that can be called as well

The following code works, but I'd like to use the self-invoking function syntax when declaring it instead of calling it explicitly on the last line:
var ShowMe = function() {
if ($('input:checkbox:checked').length) {
$('#Save').fadeIn('slow');
} else {
$('#Save').hide();
}
};
$('input:checkbox').on('click',ShowMe);
ShowMe();
You can't declare the var inside of an expression, but you can put its definition in one:
var ShowMe; (ShowMe = function() {
if ($('input:checkbox:checked').length) {
$('#Save').fadeIn('slow');
} else {
$('#Save').hide();
}
})();
$('input:checkbox').on('click',ShowMe);
Try this instead:
var ShowMe = function() {
if ($(this).length) { // `this` is the input that was clicked
$('#Save').fadeIn('slow');
} else {
$('#Save').hide();
}
};
$('input:checkbox').on('click', ShowMe).trigger('click');
Update based on comments below:
$('#Save').hide();
$('input:checkbox').on('click', function() {
if(this.checked) { //check if this is checked
$('#Save').show('slow');
}
else if(!($('input[type="checkbox"]:checked').length)) {
//check to see if anything else was checked
$('#Save').hide();
}
});

Categories