Jest to kod z jQuery 1.7:

<div class="test">
  <div class="bu">
    <a>
      bu here
    </a>
  </div>
</div>
<script src="http://code.jquery.com/jquery-1.7.js"></script>
<script>
$(document).on('click', '.test', function () { alert(0); return false; });
$(document).on('click', '.bu', function () { alert(1); return false; });
$(document).on('click', '.bu', function () { alert(2); return false; });
</script>

Kliknięcie .Text>. Ale alarm "1" i alarm "2", ale nie alerty "0"

Moje pytanie brzmi: jak zrobić to samo bez jQuery (na native dom API)? Wygląda na to, że nie mogę tego zrobić z native dom API bez wdrażania własnej biblioteki ...

2
4esn0k 17 listopad 2011, 10:13

3 odpowiedzi

Najlepsza odpowiedź
<div class="a">
    <div class="b">
      <div class="c" style="border: 1px solid silver; width: 80px; text-align: center;line-height: 80px;">
          click me!
      </div>
    </div>
</div>

<script>

// Element.prototype.matchesSelector
(function (x) {
  var i;
  if (!x.matchesSelector) {
    for (i in x) {
      if (/^\S+MatchesSelector$/.test(i)) {
        x.matchesSelector = x[i];
        break;
      }
    }
  }
}(Element.prototype));

Document.prototype.on =
Element.prototype.on = function (eventType, selector, handler) {
  this.addEventListener(eventType, function listener(event) {
    var t = event.target,
      type = event.type,
      x = [];
    if (event.detail && event.detail.selector === selector && event.detail.handler === handler) {
      return this.removeEventListener(type, listener, true);
    }
    while (t) {
      if (t.matchesSelector && t.matchesSelector(selector)) {
        t.addEventListener(type, handler, false);
        x.push(t);
      }
      t = t.parentNode;
    }
    setTimeout(function () {
      var i = x.length - 1;
      while (i >= 0) {
        x[i].removeEventListener(type, handler, false);
        i -= 1;
      }
    }, 0);
  }, true);
};

Document.prototype.off =
Element.prototype.off = function (eventType, selector, handler) {
  var event = document.createEvent('CustomEvent');
  event.initCustomEvent(eventType, false, false, {selector: selector, handler: handler});
  this.dispatchEvent(event);
};

document.on('click', '.b', function () {
  alert(2);
});
document.on('click', '.a', function () {
  alert(1);
});
document.on('click', '.b', function (event) {
  alert(3);
  event.stopPropagation();
});

</script>
3
4esn0k 14 luty 2012, 06:23

Proszę bardzo:

document.addEventListener( 'click', function ( e ) {
    if ( hasClass( e.target, 'bu' ) ) {            
        // .bu clicked
        // do your thing
    } else if ( hasClass( e.target, 'test' ) ) {
        // .test clicked
        // do your other thing
    }   
}, false );

Gdzie hasClass jest

function hasClass( elem, className ) {
    return elem.className.split( ' ' ).indexOf( className ) > -1;
}

Live Demo: http://jsfiddle.net/nrxp5/30/

14
Šime Vidas 9 grudzień 2014, 14:52

Oto wersja oparta na prototypie

Document.prototype.on = function(event, target = null, callBack){
    this.addEventListener(event, function(event){
        let len = target.length, i = 0;
        while(i < len){
            if(event.target === target[i]){
                callBack.call(target[i], event);
            }
            i ++;
        }
    }, false);
};

Wykorzystanie jest jak jQuery ma:

let btns = document.getElementsByTagName('button');
document.on('click', btns, function(event){
    console.log(this.innerText)
});

A przykład na żywo jest poniżej:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body bgcolor="#000">
<button>hello1</button>
<button>hello2</button>
<script type="text/javascript">
	Document.prototype.on = function(event, target = null, callBack = function(){}){
		this.addEventListener(event, function(event){
			let len = target.length, i = 0;
			while(i < len){
				if(event.target === target[i]){
					callBack.call(target[i], event);
				}
				i ++;
			}
		}, false);
	};


//example of usage
	let btns = document.getElementsByTagName('button');
	document.on('click', btns, function(t){
		alert(this.innerText);
	})

//add elements after delegating an event
	let newBtn = document.createElement('button');
		newBtn.innerText = 'btnNew';
		document.body.appendChild(newBtn);
    
//delay to create
setTimeout(function(){
let newBtn = document.createElement('button');
		newBtn.innerText = 'another btnNew';
		document.body.appendChild(newBtn);
},2000);
</script>
</body>
</html>
0
harry 11 luty 2019, 11:06