Jquery js获取与数据关联的dom对象

Jquery js获取与数据关联的dom对象,jquery,dom,knockout.js,Jquery,Dom,Knockout.js,我正在使用knockout.js构建动态列表,并试图找出如何获得与可观察数组中的对象关联的DOM对象。具体地说,我想获取一行的jQuery 例如: <ul data-bind="foreach: Item"> <li data-bind="events: {click: getDomObject}, text: 'text: ' + text"> </li> </ul> 在getDomObject函数中,我希望能够获得特

我正在使用knockout.js构建动态列表,并试图找出如何获得与可观察数组中的对象关联的DOM对象。具体地说,我想获取一行的jQuery

例如:

<ul data-bind="foreach: Item">
    <li data-bind="events: {click: getDomObject}, text: 'text: ' + text">
    </li>
</ul>
getDomObject
函数中,我希望能够获得特定的
  • DOM对象,这样我就可以对它进行一些jQuery操作

    我曾考虑过向Item ViewModel添加一个
    id
    成员,然后将该id添加为行项目的html id,然后根据该id进行选择,但我觉得应该有一种更简单的方法


    引用knockout.js生成的动态HTML的正确方法是什么?

    事件处理程序,如click get passed two arguments。就是

  • 此事件所属的项-类似于使用foreach绑定呈现的可观察数组的条目(“本例中的项”)

  • 还有一个事件对象,它为您提供有关实际事件的更多信息。此对象包含已单击的DOM元素(键“target”):

  • 请注意:不要混合使用敲除和原生jQueryDOM操作——如果您可以通过巧妙的敲除绑定获得相同的结果,我建议您使用它

    下面是一个简单的演示:

    var项=函数(颜色){
    this.color=字符串(颜色);
    this.setTextColor=函数(项、事件){
    $(event.target).css('背景',颜色);
    };
    };
    ko.applyBindings(新函数(){
    this.Items=ko.array([
    新项目(“红色”),
    新项目(“蓝色”),
    新项目(“绿色”)
    ]);
    }());
    
    li{
    填充:2x10px;
    }
    
    
    如果$(event.target)解决方案与项目的DOM元素位于目标位置的已发生事件相关,则该解决方案是好的。但有时您没有目标项目,因为没有事件(例如,您希望将列表滚动到用户未做手势的项目)

    在这种情况下,可以为项的DOM元素id属性指定一个包含项id的唯一值:

    <li data-bind="attr: {id: 'item_' + id}">
    

    添加第三个选项,也适用于没有事件可处理的情况(如果有事件,则接受的答案是最佳/优化的)

    创建自定义绑定,例如:

    ko.bindingHandlers.scrollTo = {
        update: function(element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            if (value) {
                var scrollParent = $(element).closest("div");
                var newTop = $(element).position().top + scrollParent.scrollTop();
                scrollParent.scrollTop(newTop);
            }
        }
    };
    
    用法如下:

    <li data-bind="scrollTo: $parent.scrollTo() && $parent.scrollTo().id == id">
    
  • 在上面的例子中,$parent是我的视图模型。我有一个包含唯一ID的可观察对象。每当我设置scrollTo()对象时,列表就会滚动到该项


    请注意,我的代码假定LI的父DIV具有滚动条(溢出:auto/scroll)。您可以根据自己的需要进行调整,可能在父级上使用一个类并将其用于jQuery选择器,或者为了使其非常灵活,您可以通过数据绑定选项传入选择器。。。对我来说,这就足够了,因为我总是在可滚动的部分使用div。

    我也遇到了类似的问题。我提出了一个类似于Backbone.js使用el和$el引用的解决方案

    在ViewModel中:

    在html中(例如列表元素):

    例如,您可以使用$el,如:

    希望这有帮助

    我的解决方案(对“值”绑定有效)


    现在有了绑定到jquery和DOM元素的yourobservable.el和yourobservable.el。

    非常感谢!这太棒了!感谢您对jQuery操作的介绍。我在特定的行上使用autocomplete,所以我不认为我可以通过ko来实现。伟大的解决方案为autocomplete学徒使用自定义绑定:P使用ko 3个月后,我学到了一件事:对jquery/jquery ui的东西使用自定义绑定。我使用knockout已经很长时间了,但不知道事件参数-brilliant!谢谢,这个答案更完整,因为正是yuvalr80所说的原因。这个答案正是我所需要的,但对于最初的问题,接受的答案更好。谢谢你也发布了这个答案,这正是我所需要的。我并不热衷于跨越MVVM的界限,但我只是需要一种高效的方式来滚动一个项目以查看,而且我也不想为列表中的每个对象都添加一个额外的可观察对象。它可以工作,但需要传递ID,然后通过该ID获取DOM。它打破了一些规则。任何非身份证的解决方案都将不胜感激。我同意Andrew Steitz的观点——这应该是公认的答案。这是一个更全面的解决方案。注意不要在KO绑定发生之前运行jQuery表达式,否则将不会设置DOM元素ID-我按照答案添加了一个
    afterBind()
    方法。我做了类似的事情,效果非常好!谢谢你的帖子,我希望我能多次投票,因为我已经多次需要这个,我多次看到你的答案!
    ko.bindingHandlers.scrollTo = {
        update: function(element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            if (value) {
                var scrollParent = $(element).closest("div");
                var newTop = $(element).position().top + scrollParent.scrollTop();
                scrollParent.scrollTop(newTop);
            }
        }
    };
    
    <li data-bind="scrollTo: $parent.scrollTo() && $parent.scrollTo().id == id">
    
    var myViewModel = function(){
      var self = this;
    
      //html element
      self.el = ko.observable();
    
      //jquery wrapped version
      self.$el = ko.observable();
    }
    
    <!-- left side is the name of the handler, right side is name of the observable -->
    <li class="myclass" data-bind="el: el, $el: $el"></li>
    
    ko.bindingHandlers.el = {
      init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        //assign value to observable (we specified in html)
        value(element);
      }
    };
    
    ko.bindingHandlers.$el = {
      init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        var value = valueAccessor();
        //here we first create a jQuery object by using $(myelem)
        //before updating observable value
        value($(element).first());
      }
    };
    
    var myViewModel = function(){
      var self = this;
    
      //plain DOM element reference
      self.el = ko.observable();
    
      //jquery object reference
      self.$el = ko.observable();
    
      self.myFunction = function() {
        console.log(self.$el().html());
        self.$el().addClass("myCssClass");
      }
    }
    
     ko.bindingHandlers.value.preprocess = function(val, name, cb) {
        /* every time I set a data-bind="value: xxxx" with an 
         * observable xxxx add also a data-bind="domElement: xxxx" */
        cb('domElement', val );
        return val;
    }
    
    ko.bindingHandlers.domElement = {
        /* For each data-bind="domElement: xxxx" add an extension "element" */
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
          valueAccessor().extend({element: element });
        }
      };
    
    ko.extenders.element = function (target, element) {
        /* element extension add el and $el to observable xxxx */
        target.el = element;
        target.$el = $(element);
    }