0

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

Thanks

5
  • The question is pointless. Do you have any problem with media queries ? Commented Jun 11, 2016 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. Commented Jun 11, 2016 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. Commented Jun 11, 2016 at 11:40
  • short answer is yes Commented Jun 11, 2016 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. Commented Jun 12, 2016 at 0:07

3 Answers 3

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...

8
  • Might be easier and more readable just to skip wp_enqueue_script() and dump the code in wp_head. Commented Jun 11, 2016 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. Commented Jun 11, 2016 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 Commented Jun 11, 2016 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. Commented Jun 11, 2016 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 Commented Jun 12, 2016 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.

3
  • it's a crazy workaround to combine with client-side checking but it is possible... Commented Jun 11, 2016 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. Commented Jun 12, 2016 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. Commented Jun 12, 2016 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.

3
  • 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... Commented Jun 11, 2016 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. Commented Jun 11, 2016 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"... :-) Commented Jun 11, 2016 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.