代码之家  ›  专栏  ›  技术社区  ›  Chris

Chrome的offset()为选项返回null值

  •  8
  • Chris  · 技术社区  · 13 年前

    我无法计算选择中某个选项的偏移位置:

    <select multiple="true">
        <option>asdf</option>
        <option id="bar">qwer</option>
    </select>
    
    $("#bar").offset()
    

    Chrome返回(测试过1.7.2、1.9等jQuery版本):

    {top: 0, left: 0} 
    

    FF返回:

    {top: 26, left: 9}
    

    我需要像FF退货这样的职位。Chrome有变通办法吗?

    http://jsfiddle.net/YrRLx/

    2 回复  |  直到 13 年前
        1
  •  2
  •   haejeong87    13 年前

    啊。。。我能想到的一个解决方案是用ul对象替换select,并附加事件处理程序将select同步到ul。对li元素调用.offset()在FF和Chrome上都能正常工作。

    因此,如果您单击li元素,它将更新其背景色并更新隐藏选择的选定值。这样,当提交表单时,就会发送正确的值。

    http://jsfiddle.net/hqYqh/

    HTML格式:

    <select id="mySelect" multiple="true">
        <option>2011</option>
        <option>2012</option>
        <option>2013</option>
        <option>2014</option>
        <option>2015</option>
        <option>2016</option>
        <option>2017</option>
        <option>2018</option>
        <option>2019</option>
    </select>
    

    CSS格式:

    ul.select {
        display: inline-block;
        border: 1px solid black;
        list-style: none;
        margin: 0;
        padding: 2px;
        height: 80px;
        overflow: auto;
        width: 50px;
    }
    
    ul.select li {
        background-color: none;
        cursor: pointer;
    }
    
    ul.select li.selected {
        background-color: skyblue;
    }
    

    JS:

    var $select = $('#mySelect');
    var $ul = $('<ul class="select">').on('click', 'li', function() {
        $(this).parent().find('li').removeClass('selected');
        $(this).addClass('selected');
        $select.val($(this).text()).change();
    });
    
    $select.find('option').each(function() {
        var $li = $('<li>').text($(this).text());
        $ul.append($li);
    });
    
    $select.hide().after($ul);
    
    $select.change(function() {
        alert('Offset of ' + $(this).val() + ' is ' + JSON.stringify($('li.selected').offset()));
    });
    

    已编辑

    因此,我尝试了另一种方法,遵循Huanism的建议,使用select元素的offset()和scrollTop()。

    唯一不可用的是选项元素的高度。所以我试着用字体大小来估计,但并不完美,我不得不在Chrome上添加神奇的数字3来获得确切的偏移量。如果你能计算出选项元素的高度,你就不必处理上面所有的ul/li业务。

    它在这里:

    http://jsfiddle.net/hqYqh/2/

    optionOffset = function($option) {
        var i = $option.index();
        var h = Number($option.css('font-size').replace(/px/, '')) + 3; // Cannot get the height of the option element :(
        var $select = $option.parent();
        var offset = $select.offset();
        offset.top += i*h - $select.scrollTop();
        return offset;
    }
    
        2
  •  0
  •   Huangism    13 年前

    我想说chrome返回0,因为该选项不可见,因此无法计算顶部。这可能在safari中也会发生,因为它都是webkit浏览器。 我唯一能想到的是,你得到选择的偏移顶部,然后做一些计算,得到选项的大致顶部。例如,如果一个选项的高度约为10px,则您需要知道在您想要的选项之前有多少个选项,并计算出需要在选择顶部添加多少像素。