JavaScript isn't at the quality standard required

Hallo, Envato users!

We are trying to share our first JavaScript item with CodeCanyon.

In our code we have use prototype OOP based JavaScript with abstractions and inheritance. Each class as separated IIFE. Each IIFE with constructor function and prototypes for public methods. Each IIFE in namespace.
We have write our code with variables, constants, functions, objects with suitable naming conventions and have used solid and dry principles.

We have uploaded “.js” and “.css” files in our CodeCanyon submission.

It’s easy install correctly working and useful jQuery plugin library working on:
Chrome, Mozilla, Opera, Edge, Safari, IE 8, 9, 10 and 11.
Supported mobile touch events and works correctly with any kind of devices.

Unfortunately our work was rejected for quality standard.

This is our first project for share with you and we really doesn’t know what exactly is our mistake here.

Can you help us, please.

Best regards,

ShardSky!

Can you post an example JS file? Or a small demo of your script?

Hello, tips4design!

Thank you for replay!

Here is my demo:
1. My Utils example (peaces of code which I use mostly as constants instead of writing unknown strings and numbers).
Example includes my outer namespace “dbScroller” which contains the entire application.

var dbScroller = dbScroller || {};

dbScroller.Utils = { };
dbScroller.Utils.prefix = “db_scroller_”;
dbScroller.Utils.dash = “-”;
dbScroller.Utils.outer = “outer”;
dbScroller.Utils.orientation = {
vertical: “vertical”,
horizontal: “horizontal”
};

dbScroller.Utils.parents = ‘Parents’;
dbScroller.Utils.children = ‘Children’;

dbScroller.Utils.scrollDocument = true;

2. This example shows an abstract class definition example contains inside IIFE:

dbScroller.instancesTree = dbScroller.instancesTree || {};
dbScroller.instancesTree.treeMember = dbScroller.instancesTree.treeMember || {};

// Abstraction: generic class: T - scrollers controller or model
dbScroller.instancesTree.treeMember.BaseTreeMember = (function () {
/params:
- id: any
- member: T - (T: scroller Controller or Model)
/
function BaseTreeMember (id, member) {
this.setId(id);
this.setMember(member);
}

// setId: void
// params: (id: any)
BaseTreeMember.prototype.setId = function (id) {
    this._id = id;
}
// getId: string
BaseTreeMember.prototype.getId = function () {
    return this._id;
}
// setMember: void
// params: (member: T)
BaseTreeMember.prototype.setMember = function (member) {
    this._member = member;
}
// getMember: T
BaseTreeMember.prototype.getMember = function () {
    return this._member;
}
return BaseTreeMember;

})();

3. Class inheritance example:

dbScroller.instancesTree.treeMember.ParentChildrenMember = (function () {
var parentObject = dbScroller.instancesTree.treeMember.BaseTreeMember,
currentObject = ParentChildrenMember;

dbScroller.Utils.extendObject(currentObject, parentObject);
// ParentChildrenMember - generic class: T - scrollers controller or model
function ParentChildrenMember (id, member) {
    // params: (id: any, member: T)
    parentObject.call(this, id, member);
    // _children: HashMap<any>
    this._children = {};
    // _parents: HashMap<any>
    this._parents = {};
}

4. Example of controllers constructor and its init function:

function ScrollerController (options) {
var initialValue = 0;
parentObject.call(this, initialValue);
this._appContainer = options.container;
this._orientation = options.orientation;
this._inputEvents = options.events;
this._step = options.step || dbScroller.Utils.defaults.step;
this.customClass = options.customClass || null;
if (options[“width”] != “undefined”) this._appContainer[0].style.width = appSize(options[“width”]);
if (options[“height”] != “undefined”) this._appContainer[0].style.height = appSize(options[“height”]);
init.bind(this)();
}

var init = function () {
    // create model
    var modelOptions = {};
    modelOptions.guid = dbScroller.Utils.guid();
    modelOptions.orientation = this._orientation;
    this.model = new dbScroller.slide.models.ScrollerModel(modelOptions);
    this._side = this.model.options.orientationOptions.orientation;
    this._otherSide = this.model.options.otherOrientationOptions.orientation;
    // if element is display: "inline" ("span" for example) we are setting display: "block"
    if (this._appContainer.css("display") != "block" &&
        this._appContainer.css("display") != "inline-block") {
        this._appContainer[0].setAttribute("data-" + dbScroller.Utils.styleBefore,
            JSON.stringify({display: this._appContainer.css("display")}));
        this._appContainer.css("display", "block");
    }
    createScroller.bind(this)();
    this.redraw();
}

5. Example of output point where plugin is created;

(function ($) {
var initialValue = 0,
appNamespace = dbScroller.slide.controllers,
orientation = dbScroller.Utils.orientation,
event = dbScroller.Utils.eventType;

dbScroller.scrollersTree = dbScroller.scrollersTree || {};
dbScroller.scrollersTree = dbScroller.instancesTree.FamilyTree.getInstance();
var vc, hc, vcOptions = {}, hcOptions = {};
var methods = {
    init: function (options) {
        // Instance vertical scroller
        vcOptions = options;
        vcOptions["orientation"] = orientation.vertical;
        vcOptions["container"] = this;
        vcOptions["events"] = options["events"];
        vc = new appNamespace.ScrollerController(vcOptions);
        if (dbScroller.scrollersTree.memberExists(vc.model.options.guid)) {
            var vm = dbScroller.scrollersTree.getMember(vc.model.options.guid);
            vm.setMember(vc);
        }
        // Instance horizontal scroller
        hcOptions = options;
        hcOptions["orientation"] = orientation.horizontal;
        hcOptions["container"] = this;
        hcOptions["events"] = options["events"];
        hc = new appNamespace.ScrollerController(hcOptions);
        if (dbScroller.scrollersTree.memberExists(hc.model.options.guid)) {
            var hm = dbScroller.scrollersTree.getMember(hc.model.options.guid);
            hm.setMember(hc);
        }
    }
}
$.fn.dbScroller = function (options) {
    if (typeof options != "string") {
        options = $.extend({
            events: [event.SCROLL, event.TOUCH, event.DRAG_HANDLE, event.RAIL_CLICK, event.KEYBOARD]
            // defaults
        }, options);
    }
    var getGuidByAttr = function (attr) {
        return this.data(attr);
    }
    var vAttr = dbScroller.Utils.appIdAttr(orientation.vertical),
        hAttr = dbScroller.Utils.appIdAttr(orientation.horizontal),
        vGuid = getGuidByAttr.bind(this)(vAttr),
        hGuid = getGuidByAttr.bind(this)(hAttr);
    if (dbScroller.scrollersTree.memberExists(vGuid)) {
        vc = dbScroller.scrollersTree.getMember(vGuid).getMember();
    }
    else {
        vc = null;
    }
    if (dbScroller.scrollersTree.memberExists(hGuid)) {
        hc = dbScroller.scrollersTree.getMember(hGuid).getMember();
    }
    else {
        hc = null;
    }
    if ((vc || hc) && ((vc ? vc[options] : true) && (hc ? hc[options] : true))) {
        // If user is decided to change something (for example: value) for only one of the scrollers
        var inputOrientation = null;
        if (arguments[1]) {
            if (arguments[1].orientation) {
                var inputOrientation = arguments[1].orientation;
            }
        }
        if (vc && (!inputOrientation || inputOrientation == dbScroller.Utils.orientation.vertical)) {
            vc[options].apply(vc, Array.prototype.slice.call(arguments, 1));
        }
        if (hc && (!inputOrientation || inputOrientation == dbScroller.Utils.orientation.horizontal)) {
            hc[options].apply(hc, Array.prototype.slice.call(arguments, 1));
        }
    }
    else if (typeof options === 'object' || !options) {
        methods.init.apply(this, [options]);
    }
    else {
        throw new Error('Invalid input ' + options + '!');
    }
    return this;
}

})(jQuery);

Everything else inside the code is much likely of the examples below. Although if something else should exists here I will provide it.

Thanks again!

Best Regards,

ShardSky!

While some parts of the code are good, there are a few things you could improve:

  1. Naming variables, you have variable names like “vc” or “hc” that could be improved.
  2. Comments. Do you use any particular commenting style? I find really confusing how you comment your function declarations as you only name the parameter types and don’t actually explain what the functions do.
  3. Confusing auxilliary variables. See the code below why do you copy a reference from options into vcOptions and then do vcOptions["events"] = options["events"] . This code actually is options.events = options.events, which does nothing. (also, try using the dot notation like vcOptions.events).

In my opinion you use too much abstraction for too little functionality, stuff like this instancesTree.treeMember.BaseTreeMember looks overly complicated if your actual script is not hundreds of JS files.

Also, this line:
if ((vc || hc) && ((vc ? vc[options] : true) && (hc ? hc[options] : true)))

As I don’t know what your script is about, I have no idea what this line is doing. Shorter is not always better.

Also, try using === when possible instead of ==.

And, my final advice, use a JS code linter if you are not using one.

1 Like

Thank you for the good advices, tips4design!

Actually yes… my real code is hundreds of JS files :smiley: and for my submission I arrange everything in one big file. I love to program in small separated peaces but if the rules here are different I will consider a refactoring. Will take a look about abstractions, statements, comments and variables name by your opinion.

Best Regards,

ShardSky!

I think you have to submit both the initial source code (all files, non minified) and the production JS file (the bundled file containing everything).

1 Like

Ok. I will do like this for my next submission.