javscript querySelector版本的Jquery

时间:2019-05-31 19:15:11

标签: javascript jquery

我正试图摆脱JQuery。

我有一个名为“ clientProfiles”的div

<div class="paperlist" data-role='listview' data-inset='true' data-split-icon='delete' id='clientProfiles'></div>

我的应用程序将像这样用按钮填充'div'。

function getClientHtml(device) {

                var html = "";
                html += '<div data-name="' + device.Name + '" data-id="' + device.Id + '"data-app="' + device.AppName + '" style="border-radius: 2px; border: 1px solid rgba(0,0,0,0.158)" class="clientProfile listItem">';
                html += '<img style="float-left; width:3%;" src="' + deviceNameImage(device.Name) + '"/>';
                html += '<div class="listItemBody">';
                html += '<h3 class="listItemBodyText">' + device.Name + ' - ' + device.AppName + '</h3>';
                html += '</div>';
                html += '<i class="md-icon btnDeleteProfile" data-index="0">close</i>';
                html += '</div>';
                html += '<br />';
                return html;
            };

用户添加按钮后的html如下所示:

<div class="paperlist" data-role="listview" data-inset="true" data-split-icon="delete" id="clientProfiles">
<div data-name="Xbox One" data-id="mcX7xXZksA1fJooKY2SRS5soNbFgM4lQurFx3bxr2s" data-app="Theater" style="border-radius: 2px; border: 1px solid rgba(0,0,0,0.158)" class="clientProfile listItem">
<img style="float-left; width:3%;" src="../images/devices/xboxone.png"><div class="listItemBody"><h3 class="listItemBodyText">XBLAHBLAHNAME</h3>
</div>
<i class="md-icon btnDeleteProfile" data-index="0">close</i>
</div>
<br>
</div>

这些动态创建的按钮可以通过单击主按钮内带有``.btnDeleteProfile''类的标记为的图标从页面上删除。

当我想将单击事件添加到JQuery中的'btnDeleteProfile'时,我可以使用以下方法:

 $('#clientProfiles', page).on('click', '.btnDeleteProfile', function () {});

但是,由于我现在不使用JQuery,所以我遇到了针对'.btnDeleteProfile'的问题。

document.querySelector('。btnDeleteProfile')。addEventListener('click',function(){});

但是MDN表示querySelector只会找到它的第一个实例,并且很可能会创建大量的这些按钮,并附加了不同的配置文件信息。

查询选择器找不到“ btnDeleteProfile”。

我遇到的错误是“无法将点击事件添加为null。

4 个答案:

答案 0 :(得分:1)

您可以使用:

  

Event​.target:事件接口的target属性是对调度事件的对象的引用。

摘要:

let array = new Proxy([], {
  set: (obj, prop, value) => {
    obj[prop] = value;
    if (prop === 'length')
      console.log(`array length changed to ${value}`);
    else
      console.log(`set index ${prop} to ${value}`);
    return true;
  }
});

array[5] = 3;
array.push(1);
array[0] = 10;
console.log(array);
function getClientHtml(device) {

    var html = "";
    html += '<div data-name="' + device.Name + '" data-id="' + device.Id + '"data-app="' + device.AppName + '" style="border-radius: 2px; border: 1px solid rgba(0,0,0,0.158)" class="clientProfile listItem">';
    html += '<img style="float-left; width:3%;" src="../images/devices/xboxone.png"/>';
    html += '<div class="listItemBody">';
    html += '<h3 class="listItemBodyText">' + device.Name + ' - ' + device.AppName + '</h3>';
    html += '</div>';
    html += '<i class="md-icon btnDeleteProfile" data-index="0">close</i>';
    html += '</div>';
    html += '<br />';
    return html;
}

 var clientProfiles = document.querySelector('#clientProfiles');

clientProfiles.innerHTML += getClientHtml({Name: 'Xbox One', id: "mcX7xXZksA1fJooKY2SRS5soNbFgM4lQurFx3bxr2s", AppName: 'Theater'});
clientProfiles.addEventListener('click', function(e) {
    if (e.target.classList.contains('btnDeleteProfile')) {
        e.target.closest('div').remove();
        console.log('Do it');
    }
})

答案 1 :(得分:0)

您可以通过创建自己的委托事件侦听器逻辑来对此进行概括。

  • 将事件监听器绑定到父级
  • 事件发生时,找到与子选择器匹配的所有父项
  • 如果事件源自的元素在该子列表中,请对其应用事件回调。

Element.prototype.addDelegateEventListener = function (eventType, childSelector, callback) {
  var parentElement = this;
  
  parentElement.addEventListener(eventType, function(event){
    var children = [...parentElement.querySelectorAll(childSelector)];
    
    if (children.includes(event.target)) {
      callback.apply(event.target, arguments);
    }
  });
};


document.getElementsByTagName('button')[0].addEventListener('click', function(){
  document.querySelector('#parent').innerHTML += `<div class="clickMe" data-created-on="${Date.now()}">Click Me</div>`;
});

document.getElementById('parent').addDelegateEventListener( 'click', '.clickMe', function(e){
  console.log(this);
  console.log(e.target);
});
<button>Add Element</button>
<div id="parent">
  <div>No Match</div>
  <div>
    <div class="clickMe">Indirect Child</div>
  </div>
</div>

答案 2 :(得分:0)

使用事件委托。使用事件委托,您可以将事件处理程序添加到元素中,该元素将在添加动态内容之前存在。动态添加的元素发生的所有事件都会使DOM冒泡到您已将处理程序附加到的现有元素。然后,您的事件处理程序将需要检查该事件,以了解该事件是否应该执行。

在我的简单示例中,我已将委托处理程序附加到#list。它等待一个.close类的元素被单击,并发出一个click事件,以从列表中删除li

var addItemToList = function addItemToList( listNode, text ) {
  
  var li          = document.createElement( 'li' );
  var spanClose   = document.createElement( 'span' );
  var spanNothing = document.createElement( 'span' );
  
  li.textContent = text;

  spanClose.className = 'close';
  spanClose.innerHTML = '⨯';

  spanNothing.className = 'nothing';
  spanNothing.innerHTML = '★';

  li.appendChild( spanClose )
  li.appendChild( spanNothing );
  listNode.appendChild( li );

};

var getRandomText = function getRandomText() {
  return randomText[ Math.floor(Math.random() * 3) ];
};

var removeListItem = function removeListItem( e ) {

  // e.target = <span>
  if ( e.target.classList.contains( 'close' ) ) {
  
    var li = e.target.parentNode; 
    var ul = li.parentNode;

    ul.removeChild( li );

  }

}

var addToListBtn = document.querySelector( 'button' );
var theList      = document.querySelector( '#list' );
var randomText   = [ 'Hello!', 'Huh?', 'Okay' ];

addToListBtn.addEventListener( 'click', function ( e ) {
  addItemToList( theList, getRandomText() );
} );

theList.addEventListener( 'click', removeListItem );
li {
  line-height: 1.5;
}

li span {
  border: 1px solid #ccc;
  margin-left: 1rem;
  padding: 0.25rem 0.5rem;
  cursor: pointer;
}
<button>Add to List</button>

<ul id="list"></ul>

答案 3 :(得分:-1)

好的,如果您只是想让该代码正常工作,那么gaetanoM的答案很好。

但是,您的问题的核心似乎是如何针对删除按钮的全部来附加功能。因此,您可以使用querySelectorAllforEach之类的MDN来显示,以供将来参考:

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#Accessing_the_matches

// use querySelectorAll to get a node list of the elements, similar to how you would get a jQuery object in jQuery
var deleteButtons = document.querySelectorAll(".btnDeleteProfile");

// iterate over the node list just like you would in jQuery with .each()
deleteButtons.forEach(function(button) {
  // do something with the individual element
  console.log(button);
});