-2

I have a ReactJS project and I've been advised not to use jQuery for various reasons, so I'm attempting to convert the following jQuery to JavaScript -- it smoothly changes background color while scrolling the page:

$( window ).ready(function() {

    var wHeight = $(window).height();

    $('.slide')
        .height(wHeight)
        .scrollie({
            scrollOffset : -50,
            scrollingInView : function(elem) {

                var bgColor = elem.data('background');

                $('body').css('background-color', bgColor);

            }
        });

    });

CSS:

* { box-sizing: border-box }

body {
    font-family: 'Coming Soon', cursive;
    transition: background 1s ease;
    background: #3498db;
}

p {
    color: #ecf0f1;
    font-size: 2em;
    text-align: center;     
}

a {
    text-decoration: none;
}

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/2542/jquery.scrollie.min_1.js"></script>

<div class="main-wrapper">

    <div class="slide slide-one" data-background="#3498db">
        <p>Title</p>
        <center>Go To <a href="#green" style="color:green">Green</a>.</center>  
    </div>

    <div class="slide slide-two" data-background="#27ae60">
        <a name="green">
            <p>Green area</p>
            <center>Go To <a href="#red" style="color:red">Red</a>.</center>
        </a>
    </div>

    <div class="slide slide-three" data-background="#e74c3c">
        <a name="red">
            <p>Red area</p>
            <center>Page over. Hope that was helpful :)</center>
        </a>
    </div>

But how can I do the conversion to JavaScript to fit the ReactJS project?

Thank you in advance and will be sure to accept/upvote answer

ElChiniNet
  • 2,778
  • 2
  • 19
  • 27
Jo Ko
  • 7,225
  • 15
  • 62
  • 120
  • 2
    Nobody here is going to convert a whole plugin for you. This isn't a free code writing or conversion service – charlietfl Feb 10 '17 at 18:18
  • 2
    @charlietfl I am not asking to have it converted. I'm simply asking for guidance... – Jo Ko Feb 10 '17 at 18:32
  • 1
    Make a js fiddle and try to do it yourself, post where you get stuck and people will be more inclined to help. – Zach L Feb 10 '17 at 18:32
  • @charlietfl Jeez. What in the world – Jo Ko Feb 10 '17 at 18:35
  • I don't think you realize that what you are asking is not trivial and is far too broad a scope for a question here – charlietfl Feb 10 '17 at 18:41
  • @charlietfl Do you not realize that I just asked for guidance? Don't understand what's bothering you so much to a point where you'd rather waste your time being so toxic rather than actually contributing to the community. – Jo Ko Feb 10 '17 at 18:55
  • Sure I do...but "guidance" for ripping apart and converting a whole plugin is not trivial. What sort of answer do you really expect for that? – charlietfl Feb 10 '17 at 18:56
  • @charlietfl I expect guidance. You are making it seem like I have thousands of code. Really though. – Jo Ko Feb 10 '17 at 19:04
  • To simply answer your question on *how to*: Just split your code into atomic steps of code, have a look what each step is doing and translate it into its vanillaJS counterpart. Then look at your code as a whole and reassamble the JS function to reproduce the expected outcome. When you just seek guidance then the css and html part is just superfluous in this question. – empiric Feb 10 '17 at 19:11
  • You are only showing the initialization of the plugin...sure...that's simple. But the plugin code from this file needs converting https://s3-us-west-2.amazonaws.com/s.cdpn.io/2542/jquery.scrollie.min_1.js Not trivial – charlietfl Feb 10 '17 at 19:13
  • And for @charlietfl's point: You are using `.scrollie()` which is no standard jQuery function but a plugin. You probalby need to figure out on how to mimic the animation in vanillaJS or search for a non-jQuery plugin which does the same thing – empiric Feb 10 '17 at 19:14
  • @empiric Is there a better way to approach for changes in background color when scrolling for ReactJS? – Jo Ko Feb 10 '17 at 19:19
  • @JoKo [here](http://stackoverflow.com/a/16845203/4202224) would be an vanillaJS example handling that, but other than that I don't if there is anything reactJS specific. – empiric Feb 10 '17 at 19:22
  • @empiric Doesn't have to be necessarily reactJS specific, but rather just javscript and not jQuery as jQuery goes against reactJS methodology with DOM. I actually came across that but it goes through every shade color on every scroll and not quiet achieving https://codepen.io/Funsella/pen/dpRPYZ which is what I'm looking for. – Jo Ko Feb 10 '17 at 19:32
  • @empiric Just checking in to see if you've my last comment. Please let me know. Thank you in advance! – Jo Ko Feb 13 '17 at 23:14

3 Answers3

3

Changing from JQuery to JavaScript is always possible. Because JQuery builds on JavaScript. Most of the time ( like in your case ) it's not even that much work.

I've not changed your CSS or HTML. So this is just some new JavaScript. However you should put this script at the end of your website.

(function() { // create an own scope and run when everything is loaded

  // collect all the slides in this array and apply the correct height
  var slides = document.getElementsByClassName('slide')
  for (slide of slides) slide.style.height = window.innerHeight + 'px'

  // use the native scroll event
  document.addEventListener("scroll", function() {
    // how much have we scrolled already
    var currentOffset = document.documentElement.scrollTop || document.body.scrollTop

    // now check for all slides if they are in view (only one will be)
    for (slide of slides) {
       // 200 is how much before the top the color should change
       var top = slide.getBoundingClientRect().top + currentOffset - 200
       var bottom = top + slide.offsetHeight

      // check if the current slide is in view
      if (currentOffset >= top && currentOffset <= bottom) {
        // set the new color, the smooth transition comes from the CSS tag
        // CSS: transition: background 1s ease;
        document.body.style.background = slide.dataset.background
        break
      }
    }

  })

}())

Additionally you might want to listen on resize event, because as of now when you resize the window will look a bit off ( this replaces the 5 line of the code above)

  function setSize() {
    for (slide of slides) slide.style.height = window.innerHeight + 'px'
  }
  window.addEventListener("resize", setSize)
  setSize()

Solution

(function() {
  
  var slides = document.getElementsByClassName('slide')
  function setSize() {
    for (slide of slides) slide.style.height = window.innerHeight + 'px'
  }
  window.addEventListener("resize", setSize)
  setSize()

  document.addEventListener("scroll", function() {
    var currentOffset = document.documentElement.scrollTop || document.body.scrollTop
    
    for (slide of slides) {
       // 100 is how much before the top the color should change
       var top = slide.getBoundingClientRect().top + currentOffset - 100
    var bottom = top + slide.offsetHeight

      if (currentOffset >= top && currentOffset <= bottom) {
        document.body.style.background = slide.dataset.background
        break
      }
    }
    
  })
  
}())
body {
    font-family: 'Coming Soon', cursive;
    transition: background 1s ease;
    background: #3498db;
}

p {
    color: #ecf0f1;
    font-size: 2em;
    text-align: center;     
}

a { text-decoration: none;
}
<div class="main-wrapper">

    <div class="slide slide-one" data-background="#3498db">
        <p>Title</p>
        <center>Go To <a href="#green" style="color:green">Green</a>.</center>  
    </div>

    <div class="slide slide-two" data-background="#27ae60">
        <a name="green">
            <p>Green area</p>
            <center>Go To <a href="#red" style="color:red">Red</a>.</center>
        </a>
    </div>

    <div class="slide slide-three" data-background="#e74c3c">
        <a name="red">
            <p>Red area</p>
            <center>Page over. Hope that was helpful :)</center>
        </a>
    </div>
arc
  • 4,553
  • 5
  • 34
  • 43
1

The plugin you are referring to links an example from their README that includes a link to a newer version that makes use of this other plugin that does not use jQuery and in fact does what you want it to do, I think. It is called in-view and it looks very good to me (both the functionality and the code).

Its usage is very similar to what you are doing currently. From the newer example linked above:

var $target = $('.wrapper');
inView('.section').on('enter', function(el){
  var color = $(el).attr('data-background-color');
  $target.css('background-color', color );
});

I do realize that I am in a way not answering the question, because this is not a jQuery-to-vanilla-JS guide, but I do think that it helps to know that somebody already did it for you.

Just a student
  • 10,560
  • 2
  • 41
  • 69
0

Should give you some idea.

var wHeight = window.innerHeight;

To select elements in javascript: on browser open inspect element, console tab and type:

document.get

and it gives you hint what to get

To get style of element:

 var elem1 = document.getElementById("elemId");
 var style = window.getComputedStyle(elem1, null);

To set Property:

 document.body.style.setProperty(height`, wHeight  +"px");

Below is some modifications that you can make, As people commented I am not trying to teach you how to's but want to give you some start:

 // $( window ).ready(function() { //remove this

var wHeight = $(window).height(); // USe this instead: var wHeight = window.innerHeight;

$('.slide') //instead of selecting with jquery "$('.slide')"  select with:  Javascript var x = document.getElementsByClassName("example") ;
  .height(wHeight) // Here you are chaining methods, read this article https://schier.co/blog/2013/11/14/method-chaining-in-javascript.html
  .scrollie({
    scrollOffset : -50,
    scrollingInView : function(elem) {

      var bgColor = elem.data('background'); //var bgColor = window.getComputedStyle(elem, null);

      $('body').css('background-color', bgColor); //document.body.style.background = bgColor;

    }
  });

 // }); //remove this

For .... in

var t = document.getElementsByClassName('slide')
console.log(typeof t) //object

for (var prop in t) {
 console.log('t.' + prop, '=', t[prop]);
 // output is index.html:33 t.0 = <div class=​"slide slide-one" data-      background=​"#3498db">​…​</div>​
 // output is index.html:33 t.1 = <div class=​"slide slide-two" data- background=​"#27ae60">​…​</div>​
 // output is index.html:33 t.2 = <div class=​"slide slide-three" data-background=​"#e74c3c">​…​</div>​<a name=​"red">​…​</a>​</div>​
// output is index.html:33 t.length = 3
// output is index.html:33 t.item = function item() { [native code] }
// output is index.html:33 t.namedItem = function namedItem() { [native code] }

}

Janatbek Orozaly
  • 445
  • 3
  • 17
  • Before I accept the answer and upvote, do you mind showing how it pertains to the code I provided? – Jo Ko Feb 10 '17 at 19:56
  • Really appreciate your comments! Helping me to understand and learn. In the case of `scrollie({ scrollOffset : -50, scrollingInView : function(elem)`, how should I handle it? – Jo Ko Feb 10 '17 at 21:40
  • Really great read! So my question is, how am I supposed to redefine `'.slide'` so that it returns an object as suggested? – Jo Ko Feb 10 '17 at 22:14
  • edited an answer, and you need to read more plain Javascript before working with React. – Janatbek Orozaly Feb 10 '17 at 22:45
  • See how the object is returned! Thank you. How about as for `scrollie({ scrollOffset : -50, scrollingInView : function(elem)`? Still not sure how it is supposed to be handled. – Jo Ko Feb 10 '17 at 22:52
  • I can't stay whole day with this code. try to make it work. so you'll know it in future . good luck – Janatbek Orozaly Feb 10 '17 at 22:55
  • Here is explained well : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in – Janatbek Orozaly Feb 10 '17 at 22:56
  • Before I accept the answer and upvote, I'm just trying to understand how to implement `scrollie`, because it isn't a function offered for all objects or is it? – Jo Ko Feb 10 '17 at 22:59
  • I don't know what scrollie is. jQuery has scroll() function. – Janatbek Orozaly Feb 10 '17 at 23:29
  • Why did you copy someone else code and trying to hack it. just do it from schretch. I found codepen for that. https://codepen.io/Funsella/pen/yLfAG – Janatbek Orozaly Feb 10 '17 at 23:30
  • And this is Javascript way: http://jsbin.com/elolud/2/edit?html,js,output – Janatbek Orozaly Feb 10 '17 at 23:36
  • I'm aware of that Javascript way, but it doesn't function the way I want it to. It goes through every shade color on every scroll and not quiet achieving codepen.io/Funsella/pen/dpRPYZ which is what I'm looking for. That codepen only changes color once it hits a breakpoint it has that fading in and out effect with the color – Jo Ko Feb 10 '17 at 23:42
  • Did but seeing if there's a simpler way of implementing it – Jo Ko Feb 11 '17 at 00:14