Jxbrowser: get image width and height from DOMElement

382 views Asked by At

How can I get the clientwidth and clientheight if I have a list of img

imgs = document.findElements(By.cssSelector("a>img"));
for(DOMElemnt img:imgs){
double height =img.getAttribute("height");//not always works ,sometime return null value
//What API can I use?
}

Or should I use jquery? but how can it combined with jxbrowser API? Thanks!

1

There are 1 answers

2
Mehran Torki On BEST ANSWER

As far as I know, there is no API for getting an element's height or width directly. I give two methods to get height and width. Use each that matches your code.

  1. If there is some attribute that separates images from each other such as id, then you can get image width and height using .executeJavaScriptAndReturnValue method:

    for(DOMElemnt img : imgs){
        JSValue res = browser.executeJavaScriptAndReturnValue(
                        "["
                      + "document.getElementById('" + img.getAttribute("id") + "').width,"
                      + "document.getElementById('" + img.getAttribute("id") + "').height,"
                      + "]");
        if (res.isArray()) {            
            JSArray attrs = res.asArray();                          
            if (attrs.get(0).isNumber()) {          
                float width = attrs.get(0).asNumber().getFloat();
                // use width variable
            }
            if (attrs.get(1).isNumber()) {              
                float height = attrs.get(1).asNumber().getFloat();
                // use height variable
            }
    
        }
    }
    
  2. If images do not have such attribute to separate them, you can call a function in javascript which returns an array of elements and every element consists of css path, width and height. By doing so, you can access images width and height directly. Also the css path can be used to access DOMElement. First of all, add this script to your html :

    <script>
    var cssPath = function(el) {
        if (!(el instanceof Element)) 
            return;
        var path = [];
        while (el.nodeType === Node.ELEMENT_NODE) {
            var selector = el.nodeName.toLowerCase();
            if (el.id) {
                selector += '#' + el.id;
                path.unshift(selector);
                break;
            } else {
                var sib = el, nth = 1;
                while (sib = sib.previousElementSibling) {
                    if (sib.nodeName.toLowerCase() == selector)
                        nth++;
                }
                if (el.previousElementSibling != null || el.nextElementSibling != null)
                    selector += ":nth-of-type("+nth+")";
            }
            path.unshift(selector);
            el = el.parentNode;
        }
        return path.join(" > ");
    };
    var getArray = function(selector) {
        var images = document.querySelectorAll(selector);
        var result = [];
        for (i = 0; i < images.length; ++i)
            result.push({'path': cssPath(images[i]), 'width' : images[i].width, 'height': images[i].height});
        return result;
    };
    </script>
    

    cssPath function takes an element and returns css path string. The code is just copied from here (asselin's answer) with a little modification(replaced if (nth != 1) with if (el.previousElementSibling != null || el.nextElementSibling != null)). function getArray takes a selector sting and iterates through querySelectorAll() result, adding every element's width, height and css path.

    Then call getArray function from java and parse the result:

    JSValue result = browser.executeJavaScriptAndReturnValue("getArray('a > img');");
    
    if (result.isArray()) {
    
        JSArray res_arr = result.asArray();
    
        for (int i = 0 ; i < res_arr.length() ; i++) {
    
            if (res_arr.get(i).isObject()) {
    
                JSObject obj = res_arr.get(i).asObject();
    
                float width = obj.getProperty("width").asNumber().getFloat();
                float height = obj.getProperty("height").asNumber().getFloat();
                String path = obj.getProperty("path").getStringValue();
    
                DOMElement elem = doc.findElement(By.cssSelector(path));
                // use anything of elem you need            
            }       
        }
    }
    
    • Make sure that frame has finished loading when you call javascript functions, here getArray. For that you can use call addLoadListener on browser and pass it a LoadAdapter. Then using onFinishLoadingFrame method of adapter.