• A customer of mine on Page Builder Sandwich reported a conflict between Smart Slider 3 and my plugin.

    I did some debugging and found something weird. If SS3 is turned on, JS for loops get an extra element – a function – but only when looping through them.

    If I execute this JS script on the console:

    var arr = ['a', 'b', 'c'];
    for ( var i in arr ) {
    console.log(arr[i]);
    }

    Here’s what happens with all plugins turned off & using Twenty Sixteen:

    a
    b
    c

    This is the expected result. But if I turn on SS3, I get this:

    a
    b
    c
    function () {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
    what = a[--L];
    while ((ax = this.indexOf(what)) !== -1) {

    This is affecting all arrays that are looped through and causes errors in other JS in the page if other plugins are turned on also.

    https://www.ads-software.com/plugins/smart-slider-3/

Viewing 5 replies - 1 through 5 (of 5 total)
  • Plugin Author Nextendweb

    (@nextendweb)

    Hi,

    I will check that and where does it come from! Also, if you allow me some comment on your JS array loop ?? I had also this issue in the past with other plugins, but it turned out, I was the one who do not use the proper code. If you looping an array that would be:

    var arr = ['a', 'b', 'c'];
    for(var i = 0; i < arr.length; i++){
       console.log(arr[i]);
    }

    for in statement made for looping object properties.

    var obj = {a: 1, b: 10, c: 30};
    for (var key in obj) {
       console.log(key, obj[key]);
    }

    To be honest, this is not the best way for objects, because it should check if the key is really a property or not as the object can have functions etc…

    function myObj(){
       this.a = 1;
       this.b = 10;
       this.c = 30;
    }
    
    myObj.prototype.myMethod = function(){
       console.log(this.a);
    }
    var obj = new myObj();
    for (var key in obj) {
       console.log(key, obj[key]);
    }

    This will print other the code of myMethod as it do not check if it is a real property or not. So the proper way:

    var obj = new myObj();
    for (var key in obj) {
       if (obj.hasOwnProperty(key)) {
          console.log(key, obj[key]);
       }
    }

    So it is important to always use hasOwnProperty if the object is not 100% plain object as it will help you to avoid issues.

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

    https://stackoverflow.com/questions/242841/javascript-for-in-vs-for

    Thread Starter Benjamin Intal

    (@bfintal)

    Hi, I’m in the process of cleaning this up. After I posted I came across this: https://adripofjavascript.com/blog/drips/the-problem-with-for-in-and-javascript-arrays.html – a good read too.

    Thanks for the tip. However, I think this also needs to be addressed in SS3. This would mean that any other plugin that iterates over arrays would most likely have problems with SS3 right away. I doubt everyone would be willing to rewrite all their loops to make them safe like what I’m doing now.

    Plugin Author Nextendweb

    (@nextendweb)

    I will do that for Smart Slider 3 it will be ready and tested on the update for Monday. I just wanted to make a clear explanation why it is bad the for in loop for arrays.

    We have extended the prototype of Array in JS with a method and that caused this:

    if (!Array.prototype.remove) {
        Array.prototype.remove = function () {
            var what, a = arguments, L = a.length, ax;
            while (L && this.length) {
                what = a[--L];
                while ((ax = this.indexOf(what)) !== -1) {
                    this.splice(ax, 1);
                }
            }
            return this;
        };
    }

    Another story. Some years ago the indexOf method added to the specification of the JS array. It is a great method to find something in the array with a native call. But old browsers do not support this method and programmers had to define this method when it is not supported. (There are a lot of JS library which uses it that way) It looks like this:

    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function (obj, fromIndex) {
            if (fromIndex == null) {
                fromIndex = 0;
            } else if (fromIndex < 0) {
                fromIndex = Math.max(0, this.length + fromIndex);
            }
            for (var i = fromIndex, j = this.length; i < j; i++) {
                if (this[i] === obj)
                    return i;
            }
            return -1;
        };
    }

    The point is, if you (under you, I mean other developers) still use the wrong loop for iteration, then the issue still persist as in old browsers there will be this codes by other plugins and frameworks and your iterations will fail on these too. But you might not see the issue just the user who are using the old browser.

    Thread Starter Benjamin Intal

    (@bfintal)

    I totally agree. I also did that for indexOf before. Good thing that’s gone now unless you’re still supporting IE 8 – I hope you’re not ??

    Thanks for pushing an update. I’ll be pushing an update too soon regarding loops. I’m marking this as resolved now.

    Plugin Author Nextendweb

    (@nextendweb)

    Yes, I’m working on it ??

    Also I would be the happiest people on Earth if old browsers gone, but in real, I have to leave the indexOf extension inside as other parts of our code prepared for old browser too ??

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘Javascript array loops get extra elements with plugin turned on’ is closed to new replies.