4

1. Summary

I use media queries for CSS and JavaScript code for PC and mobile devices on my site. If PC user resize page of my site, that width of active window will < 60rem, CSS for page update, but JavaScript code doesn't update → page have bugs. I don't find, what should I do to, that JavaScript will update as CSS media queries.


2. Settings

  1. CSS for pages of my site:

    @media screen and (min-width: 60rem) {
        /* My CSS for PC */
        }
    }
    
    @media screen and (max-width: 60rem) {
        /* My CSS for mobile devices */
    }
    

    Real code — https://github.com/Kristinita/KristinitaPelican/blob/master/themes/sashapelican/static/css/general/image_right.css#L35-L56.

  2. JavaScript for pages of my site:

    window.onload = function() {
        if (window.matchMedia("(min-width: 60rem)").matches) {
            // My JavaScript for PC
        } else {
            // My JavaScript for mobile devices
        }
    
    };
    

    Real code — https://github.com/Kristinita/Kristinita.github.io/blob/master/theme/js/Gemini/GeminiAndJQueryLazy.js#L8-L48

If user open page with my CSS and JavaScript on PC or mobile device without resizing active window, page work without bugs.


3. Steps to reproduce

PC user open any page (example) of my site in modern browser → user resize page (for example, use Super+Left_Arrow or Super+Right_Arrow hotkeys for Windows Aero Snap). Now window width < 60rem.


4. Expected behavior

Update CSS and JavaScript for page.


5. Actual behavior

CSS update, JavaScript doesn't update. If window width < 60rem, page open with bugs.

If window width < 60rem and user refresh browser, page open without bugs.


6. Not helped

  1. I try to use MatchMedia.js,
  2. I add event listener for media queries:

    // media query event handler
    if (matchMedia) {
      var mq = window.matchMedia("(min-width: 500px)");
      mq.addListener(WidthChange);
      WidthChange(mq);
    }
    
    // media query change
    function WidthChange(mq) {
      if (mq.matches) {
        // window width is at least 500px
      } else {
        // window width is less than 500px
      }
    
    }
    

    Full code — https://www.pastery.net/uxkvma/.

  3. I can't write code for task: if user press Super+Left_Arrow or Super+Right_Arrow, page reload. I can write code for reloading page, if user press Ctrl+Left_Arrow or Ctrl+Right_Arrow:

    $(document).keydown(function(e) {
        if (e.keyCode == 37 && e.ctrlKey || e.keyCode == 39 && e.ctrlKey){
        window.location.reload();
        }
    });
    

    But if I replace ctrlKey to metaKey, code doesn't work.

  4. Now I use window.location.reload(), if page resize by any methods:

    window.addEventListener('resize', function(event) {
      clearTimeout(resizeTimeout);
      var resizeTimeout = setTimeout(function(){
        window.location.reload();
      }, 1500);
    });
    

    But it not the best idea, because if user, for example, press Ctrl+F for find text in a page or open browser console, page will reload.


7. Do not offer

  1. Please do not offer solutions, if user must install addons, change settings or do others actions for browser. Solution must work with default settings of any modern browser.
Саша Черных
  • 2,561
  • 4
  • 25
  • 71
  • Get the resolution in server side and maintain different views for the resolution. Which means, if it is in full resolution just return "FullView" html view and if resized send "ResizedView" view. – Biby Augustine May 05 '17 at 08:41
  • A little confused here. You're saying that the scripts should be loaded by the server with respect to the screen resolution of the browser? Or are you saying that the scripts should change on the client side with respect to the screen size? – Sagar May 05 '17 at 08:44
  • @Sagar: user have any modern browser (for example, Firefox or Chrome) + use default browser settings + user resize page of my site. User don't need install addons for browser or change browser settings, but JavaScript code will change correctly for him. Thanks. – Саша Черных May 05 '17 at 08:53
  • maybe this could help? http://stackoverflow.com/questions/1818474/how-to-trigger-the-window-resize-event-in-javascript – Sagar May 05 '17 at 08:58
  • @BibyAugustine: I'm sorry, where I can read in more details, how I can to realize your algorithm? Thanks. – Саша Черных May 05 '17 at 09:00

4 Answers4

1

window.resize

pure javascript

(function() {

window.addEventListener("resize", myFunction);

function myFunction() {
    var w = window.outerWidth;
    var h = window.outerHeight;
    var txt = "Window size: width=" + w + ", height=" + h;
    var img = document.querySelector("img");
    var p   = document.querySelector("p[id=size]");    
    
    p.style.float = "right"; // DOM CSS    
    p.innerHTML   = txt; // DOM HTML
    
    if (w > 500) { 
      img.setAttribute("src", "https://www.enfa.co.id/sites/indonesia/files/inline-images/article/si-kecil-belajar-apa-dari-permainan-cilukba_0.jpg");  
      
      // My JavaScript for PC
      anotherFunction("lightgrey");
 
    } else { 
      img.setAttribute("src", "https://pbs.twimg.com/profile_images/574971671183912961/RJ8uis5w.jpeg");
      
      // My JavaScript for mobile devices      
      anotherFunction("yellow");
 
    }    
}

function anotherFunction(color) {
    var p   = document.querySelector("p[id=size]");

    p.style.backgroundColor = color; // DOM CSS    
}

})(); //self executing function
<body> 
  <p id="size">Please click "Full page"</p>
  <p>Please resize the browser</p>
  
  <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSqLQwPshtQVlcV5b9V26btY1zPlX-Egb3Tlnj9T2LNc3jNNPffhQ" />
</body>

event_onresize
innerWidth
css_selectors

antelove
  • 3,216
  • 26
  • 20
  • Thanks for the answer. Unfortunately, I don't understand, what can I do for real example from my question. See [**my javascript**](https://github.com/Kristinita/Kristinita.github.io/blob/master/theme/js/Gemini/TestResize.js), [**demo**](http://kristinita.ru/Sublime-Text/OnresizeTest). Thanks. – Саша Черных Dec 06 '17 at 14:48
0

did you tried to use jquery? (there are similar methods in pure js).

something like

if($(window).width() >= '60rem') {

     //do one js code

}else{

     //do another js code

}
Gabbax0r
  • 1,696
  • 3
  • 18
  • 31
  • Thanks for answer. Unfortunately, this spoils the page layout for me. If I replace [**this line**](https://github.com/Kristinita/Kristinita.github.io/blob/master/theme/js/Gemini/GeminiAndJQueryLazy.js#L9) of script as you tell, page nice displayed, if mobile device width, but I have a bugs, if PC width. [**Page**](http://kristinita.ru/Sublime-Text/ValeriyaSpeller) screenshot [**before**](http://i.imgur.com/NNUMLzG.png) — screenshot [**after**](http://i.imgur.com/1iAmqsx.png). Thanks. – Саша Черных May 05 '17 at 09:10
0

I guess your window.onload holds some kind of initialization for your functions.

How about you do something like this:

var deregisterScripts = function() {
   // remove scripts.
}
var initScripts = function() {
    deregisterScripts();
    if (window.matchMedia("(min-width: 60rem)").matches) {
        initJavaScriptDesktop();
    } else {
        initJavaScriptMobile();
    }

};
window.onload = initScripts;
window.onresize = initScripts;

Inside your init functions you can deregister the unnecessary stuff from the currently unused view.

Everytime you resize the window all scripts will get reinitialized and they should switch according to your media query.

Morfium
  • 241
  • 4
  • 7
  • Thanks for the answer. If I get you right, I need to write additional code for remove scripts? Thanks. – Саша Черных May 05 '17 at 09:27
  • That depends. I don't know what exactly you do within your onload. If your functions and variables all have the same name you could simply overwrite them I guess. If you attach them to dom elements you might have to unattach and reattach those. It really depends on what (and how) you do in there. – Morfium May 05 '17 at 10:38
  • [**My script**](https://github.com/Kristinita/Kristinita.github.io/blob/master/theme/js/Gemini/GeminiAndJQueryLazy.js#L8-L44), I use [**custom scrollbar**](https://github.com/noeldelgado/gemini-scrollbar). If in web-page PC window width, scrollbar apply for `body` tag; if mobile device width, scrollbar apply for `main` tag. **//** I'm sorry, where I can read, how I can write code, that remove scripts? Thanks. – Саша Черных May 05 '17 at 11:00
  • Hm I don't know those plugins, but I'd try storing you pcscrollbar and mobilescrollbar somewhere where you can reach it on resize (maybe the window) and then use pcscrollbar.destroy() in your mobile view and vice versa. I just looked into their documentation, that should do the trick. – Morfium May 05 '17 at 11:10
0

Do you familiar with MVC (Model-View-Controller) architecture?

In that architecture controller decides which view needs to be shown to the user. You can create multiple views with different HTML, CSS and javascript codes. For an example I do have "Full" and "Resized" views. When a user calling a URL like

http://...../Home/Index

Then Index action will be performed in the HomeController (this controller working in server side). In this Index action method we will check the resolution. For example

if(resolution==300)
then return Full
else
return resized
Biby Augustine
  • 425
  • 1
  • 3
  • 16