简体   繁体   中英

How do I use JavaScript to add SVG Data Attributes to Objects without being Janky?

I am learning to use vanilla JavaScript to add SVG Data Attributes to HTML Objects to suit device widths. I am looking for a way to load and switch SVGs for different layouts between mobile and desktop.

I built a test using the JavaScript setAttribute() property to add data attributes to object elements and inject external SVG files according to the client browser window width.

I cobbled together JavaScript code from various resources. It works but the result is janky. The JavaScript includes a window.onresize function that causes the SVG to jitter and reload/repaint. Is there any way to improve this code to reduce FLOUT?

Here is code:

    <script>
    if (window.matchMedia("(max-width: 760px)").matches) {
      /* the view port is at less than 760 pixels wide */
        document.getElementsByTagName("object")
[0].setAttribute("data", "assets/images/svg/SVG_dynamic-
test_02.svg"); 
    }
        else {
      /* the view port is more than 760 pixels wide */
        document.getElementsByTagName("object")
[0].setAttribute("data", "assets/images/svg/SVG_dynamic-
test_01.svg"); 
        };

    window.onresize=function(){
        if (window.matchMedia("(max-width: 760px)").matches) {
      /* the view port is at less than 600 pixels wide */
        document.getElementsByTagName("object")
[0].setAttribute("data", "assets/images/svg/SVG_dynamic-
test_02.svg"); 
    }
        else {
      /* the view port is more than 760 pixels wide */
        document.getElementsByTagName("object")
[0].setAttribute("data", "assets/images/svg/SVG_dynamic-
test_01.svg"); 
    }
    };
    </script>

Here are links to live prototypes:

http://craigwebbart.com/prototypes/SVG_attribute-test.html https://codepen.io/cwebba1/pen/GyLVEm

Extract the logic in your setAttribute call into its own function, then in your event handler, wrap the call to setAttribute in a setTimeout call (you can pass in 0 for the length):

function setSvgAttribute(svgName) {
    document.getElementsByTagName("object")[0].setAttribute("data", svgName);
}
...
if (window.matchMedia("(max-width: 760px)").matches) {
  /* the view port is at less than 760 pixels wide */
    setTimeout(function() { 
        setSvgAttribute("assets/images/svg/SVG_dynamic-test_02.svg");}, 0);
}...

By calling setTimeout , you are temporarily yielding execution back to the browser, which will use that opportunity to repaint and update DOM elements' positions and such. Your SVG's are flickering because you're forcing an additional layout pass by the browser by mutating the DOM.

I took Josh's mentoring and added throttle to his suggestion. The final code looks like this:

<script>
  var delay = 150, // delay between calls, was 250
    throttled = false; // are we currently throttled?

  function setSvgAttribute(svgName) {
    document.getElementsByTagName("object")[0].setAttribute("data", svgName);
}
if (!throttled) {

  if (window.matchMedia("(max-width: 760px)").matches) {
    /* the view port is at less than 760 pixels wide */
      setTimeout(function() { 
          setSvgAttribute("assets/images/svg/SVG_dynamic-test_02.svg");}, 0);
    }
  else {
  /* the view port is more than 760 pixels wide */
    setTimeout(function() { 
        setSvgAttribute("assets/images/svg/SVG_dynamic-test_01.svg");}, 0);
  }
    throttled = true;
};

if (!throttled) {
  window.onresize=function(){
    if (window.matchMedia("(max-width: 760px)").matches) {
    /* the view port is at less than 600 pixels wide */
      setTimeout(function() { 
          setSvgAttribute("assets/images/svg/SVG_dynamic-test_02.svg");}, 0);
    }
    else {
    /* the view port is more than 760 pixels wide */
      setTimeout(function() { 
          setSvgAttribute("assets/images/svg/SVG_dynamic-test_01.svg");}, 0);
    }
  }
};
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM