5
\$\begingroup\$

I need to refactor this code, targeted to Google Chrome (current+) to make it manageable going forward.

Here is a working JSBin of the idea.

The messiness comes from determining the accurate number of lines of text, and the real heights of elements. I know I am passing this information around too much, without enough structure, and recalculating too many things. I also know it is messy, especially inside scal_el and run_scan.

function scan_el(el_fin_callback,el,mask,sub_mask,real_height,real_width,push,lines,line) {
        line = line || 0;
        if(line >= lines) {
                el_fin_callback();
                return; // scan finished
        }
        var current_line = real_height*line;    
        var line_os = $(el).offset();
        line_os.top += current_line;
        if(lines > 1) {
                $(mask)[0].style.height = real_height+'px';
        }
        $(sub_mask).css( { 
                'height' : $(el).height()-real_height-current_line } );
        $(mask).offset(line_os);
        line_os.top += real_height;
        var length = Math.ceil($(el).text().length*real_width)+push;
        if(lines > 1) {
                length = $(el).width();
        }
        $(sub_mask).offset(line_os);
        function next_line() { // callback after scan complete
                scan_el(el_fin_callback,el,mask,sub_mask,real_height,real_width,push,lines,line+1);
        }
        run_line_scan(length,mask,next_line);
}
\$\endgroup\$
2
  • \$\begingroup\$ I think you'd be better off figuring out how to parse the HTML-layout into a big fat pre-blob of text, and running the scan on that, character-by-character. Each character is a single span, I suppose, with visibility changed as required. This would give you dynamic and flexible layout, with an easier method of performing the display. "Easier" assuming you can translate to the big fat text-blob in the first place. \$\endgroup\$ Mar 11, 2013 at 15:20
  • \$\begingroup\$ In the link above, the display seems wonky in FF19 (it doesn't work at all in IE9). However, when I switch to the edit mode @ jsbin.com/unazig/1/edit THEN it seems to display okay, in an abbreviated right-bar. \$\endgroup\$ Mar 11, 2013 at 15:27

1 Answer 1

5
\$\begingroup\$

There are only two things I can think of.

Sometimes it's best to pass objects when there are more than 4 parameters for a method call.

Instead of this

function scan_el(el_fin_callback, el, mask, sub_mask, real_height, real_width, push, lines, line) {

Try this.

function scan_el(el_fin_callback, els, metrics, lines, line) {

els and metrics would look something like this.

els = {
    el : jQuery,
    mask : jQuery,
    submask : jQuery
};
metrics = {
    real_width : Number,
    real_height : Number,
    push : Number
}

Try to make functions no longer than 8-12 lines.

You could extract the real_* variables into a function and return a object instead of a list of variables.

function getRealMetrics(el){
      // doesn't work completely
    var real = {};
    real.box = window.getComputedStyle(el);
    real.width = parseFloat(real.box.width);
    real.height = parseFloat(real.box.height);
    real.el = el.getBoundingClientRect();
    real.el_style = window.getComputedStyle(el);
    real.el_padding = parseFloat(real.el_style.padding);
    real.el_padding_left = parseFloat(real.el_style.paddingLeft);
    real.el_margin_left = parseFloat(real.el_style.marginLeft);
    real.el_align = real.el_style.textAlign;

    if (!isNaN(real.el_padding)) {
        real.el_height -= real.el_padding * 2.0;
    }
    var lines = Math.ceil(real.el_height / real.height);
    if (lines > 1) {
        length = real.el.width;
    }
    real.el_push = real.el_margin_left + real.el_padding_left + (real.el.width - length) / 2.0;
    if (real.el_align !== 'center') {
        real.el_push = real.el_margin_left + real.el_padding;
    }
    return result;
}
\$\endgroup\$

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.