-1

Is it possible to load scripts through wp_enqueue_script based on a browser's width?

Thanks

  • The question is pointless. Do you have any problem with media queries ? – Sumit Jun 11 '16 at 10:14
  • anything is possible but are you really sure you want to? if you elaborate on what you are trying to achieve a better solution is probably available. – majick Jun 11 '16 at 10:55
  • 3
    XY problem alert! If you explain why you want to do this, we'll probably find a much better solution for you. – TheDeadMedic Jun 11 '16 at 11:40
  • short answer is yes – majick Jun 11 '16 at 14:04
  • Can't you set set a cookie on the client for largest screen dimensions and read from that on the server? Wouldn't help you on the first request but second+ for clients that support cookies. – jgraup Jun 12 '16 at 0:07
1

Kinda just answering this to counter the "not-possible" answers...

Yes it is probably not the best thing to do, since we are still unsure what the OP is trying to achieve, but that does not make it not possible... complex and impractical perhaps, but still entirely possible.

First enqueue the script as you normally would... here setting the minimum and/or maximum screen widths to load for as well:

add_action('wp_enqueue_scripts','enqueue_screen_size_script');
function enqueue_screen_size_script() {
    global $screensizescripturl, $screenminwidth, $screenmaxwidth;

    // set one or the other or both of these
    $screenminwidth = '319'; $screenmaxwidth = '769'; 

    $screensizescripturl = get_stylesheet_directory_uri().'/screen-size.js';

    wp_enqueue_script('screen-size',$screensizescripturl,array('jquery'));
}

Then you can filter the enqueue using the script_loader_tag filter, and add some magical javascript to conditionally load the script inside itself:

add_filter('script_loader_tag','enqueue_for_screen_size', 10, 2);
function enqueue_for_screen_size($tag, $handle) {
    global $screensizescripturl, $screenminwidth, $screenmaxwidth;

    if ($handle == 'screen-size') {

        // this would get the src url dynamically, but using global instead
        // $scripturl = substr($tag,(strpos($tag,'src="')+5),strlen($tag));
        // $scripturl = substr($scripturl,0,strpos($tag,'"'));

        $conditionaltag = "if (window.jQuery) {x = jQuery(window).width();}
        else {x = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;} ";

        if ( ($screenminwidth) && ($screenmaxwidth) ) {
            $conditionaltag .= "if ( (x > ".$screenminwidth.") && (x < ".$screenmaxwidth.") ) {";
        }
        elseif ($screenminwidth) {$conditionaltag .= "if (x > ".$screenminwidth.") {";}
        elseif ($screenmaxwidth) {$conditionaltag .= "if (x < ".$screenmaxwidth.") {";}

        $conditionaltag .= " document.write(unescape('%3Cscript id=\"screen-size-script\" src=\"".$scripturl."\"%3E%3C\/script%3E')); }</script>";

        $tag = str_replace('src="'.$scripturl.'"','',$tag);
        $tag = str_replace('</script>',$conditionaltag, $tag);
    }

    return $tag;
}

So then, the point of responsiveness being responsive, you would probably need a window resize function to dynamically load the script if it fits your chosen specifications after resize... with a debounce thrown in for good measure.

add_action('wp_footer','screen_resizer_check');
    function screen_resizer_check() {
        global $screensizescripturl, $screenminwidth, $screenmaxwidth;

        // note: debounce window resize function from here:
        // http://stackoverflow.com/questions/2854407/javascript-jquery-window-resize-how-to-fire-after-the-resize-is-completed

        echo "<script>jQuery(document).ready(function($) {

            function loadscreensizescript() {
                x = jQuery(window).width();
                ";

                if ( ($screenminwidth) && ($screenmaxwidth) ) {
                    echo "if ( (x > ".$screenminwidth.") && (x < ".$screenmaxwidth.") ) {";
                }
                elseif ($screenminwidth) {echo "if (x > ".$screenminwidth.") {";}
                elseif ($screenmaxwidth) {echo "if (x < ".$screenmaxwidth.") {";}

                echo "
                    newscript = document.createElement('script');
                    newscript.setAttribute('id','screen-size-script');
                    newscript.src = '".$screensizescripturl."';
                    document.getElementsByTagName('head')[0].appendChild(newscript);
                }
            }

            /* could just script load here instead of using wp_enqueue script */
            /* loadscreensizescript(); */

            var resizeDebounce = (function () {
                var timers = {};
                return function (callback, ms, uniqueId) {
                    if (!uniqueId) {uniqueId = "nonuniqueid";}
                    if (timers[uniqueId]) {clearTimeout (timers[uniqueId]);}
                    timers[uniqueId] = setTimeout(callback, ms);
                };
            })();


            jQuery(window).resize(function () {
                if (document.getElementById('screen-size-script')) {return;}
                resizeDebounce(function(){ 
                    loadscreensizescript();
                }, 1000, "screensizescript");
            }); 
        });
    }

Although, it is arguably a better just to load the script using jQuery(document).ready in the first place as noted above and not bothering with wp_enqueue_script, but I guess that wouldn't fully answer the question. :-)

Note: untested as a whole from otherwise working snippets I have lying around...

  • Might be easier and more readable just to skip wp_enqueue_script() and dump the code in wp_head. – fuxia Jun 11 '16 at 12:42
  • as i said that wouldn't answer the specific question tho... personally I'd skip it and just do the footer load as given, as better for this kind of thing anyway to wait for the document ready to fire to get a more reliable browser width... so it may as well be after everything and be non-blocking too. – majick Jun 11 '16 at 12:51
  • 2
    seriously? the point of not loading anything is that it will not work well under specific condition, lets say when screen width is below 500 pixel. Now after you loaded the big screen JS how exactly are you going to unload it when the width is below 500? It is just impossible in JS, so this is not even a theoretical but pointless solution, it just an invitation for hard to debug bugs – Mark Kaplun Jun 11 '16 at 12:58
  • but "unloading" the script is another question... and there is no indication whether than is needed or not... if it was, you would simply use an internal check in the script to not fire the functions if the screen is smaller than 500px... if going to this much trouble in the first place, that is really not a big deal. – majick Jun 11 '16 at 13:11
  • Totally pointless. Anything that requires and relies on client side processes are totally unreliable, you will definitely dish wrong content unintendently to most users. I totally agree with @MarkKaplun here – Pieter Goosen Jun 12 '16 at 6:40
3

No it isn't. Server can not know browser width. Not sure it is even a smart idea since the width of the browser can change at any point.

  • it's a crazy workaround to combine with client-side checking but it is possible... – majick Jun 11 '16 at 12:49
  • 1
    @majick yes, it might be possible, but it is totally unreliable. No matter what, you will dish up wrong content to most users. Any client side process is just totally unreliable and should not be used to control server side prosesses. – Pieter Goosen Jun 12 '16 at 6:43
  • @PieterGoosen that's cool, I'm more than willing to hear of cases where it would be unreliable, as it gives a better idea of how to use client-side processes more effectively by failing them gracefully. for example the 500px example use case Mark already mentioned. – majick Jun 12 '16 at 6:52
0

As @Mark Kaplan correctly points out, the right answer to this clear question is No.

What you can do, and maybe asking on Stackoverflow will get a better answer, is run scripts in response to certain browser sizes and also detect when the window is resized if that is also important to you. This isn't without its problems, but these are JS issues, not WP issues, so I won't go into that here.

You could put a script loader into the mix if it's important to you that a script is only downloaded for certain window or screen sizes.

If you're worried about performance then these things are a balancing act and you may find other types of optimisations are more helpful.

  • yes but you can add extra javascript to the enqueue or modify it through the script_loader_tag filter... making it a question of how is it possible to do this in WP... – majick Jun 11 '16 at 12:47
  • Aren't we both just saying "use JS for the conditional load?" We should enqueue that script properly, but otherwise this starts to feel like a semantic argument. – Andy Macaulay-Brook Jun 11 '16 at 12:52
  • yes we are... it is possible to use enqueue "properly" as shown, but for the complexity is not worth it... anyway, just felt I had to add "yes but" in response to the "right answer is no"... :-) – majick Jun 11 '16 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.