วิธีการส่งผ่านข้อโต้แย้งไปยังฟังก์ชั่นฟัง addEventListener?


304

สถานการณ์ค่อนข้างเหมือน -

var someVar = some_other_function();
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);

ปัญหาคือว่าค่าของsomeVarไม่สามารถมองเห็นได้ภายในฟังฟังก์ชั่นการฟังaddEventListenerซึ่งมันอาจจะถือว่าเป็นตัวแปรใหม่


8
บทความที่ชัดเจนมากเกี่ยวกับเรื่องนี้: toddmotto.com/avoiding-anonymous-javascript-functions
โนบิตะ

ไม่ใช่วิธีที่สะอาดที่สุด แต่ทำงานได้ โปรดทราบว่าหาก someVar สามารถเป็นตัวเลขหรือข้อความเท่านั้น: eval ('someObj.addEventListener ("คลิก", ​​ฟังก์ชัน () {some_function (' + someVar + ');});');
Ignas2526

เพิ่งมีปัญหานี้วันนี้ - วิธีแก้ปัญหาที่ให้ไว้ที่นี่ถูกต้อง (วิธีแก้ไขปัญหาอื่น ๆ มีปัญหาเช่นสำหรับปัญหาลูป ฯลฯ ) - stackoverflow.com/a/54731362/984471
Manohar Reddy Poreddy

คำตอบ:


207

ไม่มีอะไรผิดปกติกับรหัสที่คุณเขียน ทั้งสองsome_functionและsomeVarควรสามารถเข้าถึงได้ในกรณีที่มีอยู่ในบริบทที่ไม่ระบุตัวตน

function() { some_function(someVar); } 

ถูกสร้าง.

ตรวจสอบว่าการแจ้งเตือนให้คุณค่าที่คุณได้รับการค้นหาให้แน่ใจว่าจะสามารถเข้าถึงได้ในขอบเขตของฟังก์ชั่นที่ไม่ระบุชื่อ (เว้นแต่คุณมีรหัสเพิ่มเติมที่ทำงานกับsomeVarตัวแปรเดียวกันถัดจากการโทรไปaddEventListener)

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);

86
วิธีนี้ใช้ไม่ได้กับลูป ฉันมักจะได้รับค่าล่าสุดไม่ใช่สิ่งที่เป็นของการทำซ้ำนั้น ทางออกใด ๆ
iMatoria

6
ใครรู้ว่าทำไมมันไม่ทำงานในวง? สาเหตุของพฤติกรรมนั้นคืออะไร?
Morfidon

3
@Morfidon เพราะฟังก์ชั่นที่มีตัวแปรทั่วโลกทำหน้าที่เป็นปิดใน Javascript ซึ่งหมายความว่าพวกเขาจำสภาพแวดล้อมที่อยู่นอกขอบเขตศัพท์ของพวกเขา หากคุณเพียงแค่สร้างฟังก์ชั่นที่แตกต่างในสภาพแวดล้อมเดียวกันพวกเขาจะอ้างอิงถึงสภาพแวดล้อมเดียวกัน
bugwheels94

16
@Morfidon: ในลูปค่า someVar ไม่ใช่ค่าที่มีเมื่อเพิ่ม listener แต่ค่าที่มีเมื่อมีการเรียกใช้ฟัง เมื่อผู้ฟังถูกเรียกใช้ลูปจะสิ้นสุดลงแล้วดังนั้นค่าของ someVar จะเป็นค่าที่มีเมื่อลูปสิ้นสุดลง
www.admiraalit.nl

4
@iMatoria ฉันเพิ่งค้นพบว่าการสร้างการbound functionใช้.bind()วิธีการนี้จะแก้ปัญหาด้วยลูปdeveloper.mozilla.org/en/docs/Web/JavaScript/Reference/
ลุค T โอไบรอัน

353

ทำไมไม่เพียงแค่รับข้อโต้แย้งจากแอตทริบิวต์เป้าหมายของเหตุการณ์

ตัวอย่าง:

const someInput = document.querySelector('button');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
  window.alert(evt.currentTarget.myParam);
}
<button class="input">Show parameter</button>

จาวาสคริปต์เป็นภาษาต้นแบบเชิงโปรดจำไว้!


16
นี่คือคำตอบที่ถูกต้องเพราะมันให้เราใช้หลังจากฟังก์ชั่น 'removeEventListener'
user5260143

14
ไม่ควรevt.currentTarget.myParamหรือ หากมีองค์ประกอบอื่นอยู่ภายใน 'someInput' evt.targetอาจจะหมายถึงองค์ประกอบภายใน ( jsfiddle.net/qp5zguay/1 )
Herbertusz

รักษานี้this! การใช้วิธีนี้ใน typescript ต้องใช้องค์ประกอบที่จะเป็นanyหรือทำประเภทย่อยว่า
Badman เก่าเกรย์

1
ตัวแปรของฉันกลับมาอย่างที่ไม่ได้กำหนด ... ความคิดใดเกี่ยวกับวิธีการแก้ไขนั้น?
nomaam

1
ถ้าaddEventListenerเป็นdocument, evt.target.myParamไม่ทำงานสำหรับฉัน ฉันต้องใช้evt.currentTarget.myParamแทน
turrican_34

67

คำถามนี้เก่า แต่ฉันคิดว่าฉันเสนอทางเลือกโดยใช้. ผูก () ของ ES5 - สำหรับลูกหลาน :)

function some_func(otherFunc, ev) {
    // magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);

เพิ่งทราบว่าคุณจำเป็นต้องตั้งค่าฟังก์ชั่นผู้ฟังของคุณด้วย param แรกเป็นอาร์กิวเมนต์ที่คุณส่งผ่านไปยัง bind (ฟังก์ชั่นอื่น ๆ ของคุณ) และ param ที่สองคือเหตุการณ์ (แทนที่จะเป็นอันแรก) .


1
Function.prototype.bind ()เป็นวิธีที่ดีที่สุดในการแก้ไขปัญหานี้ นอกจากนี้ยังทำงานได้อย่างเป็นธรรมชาติภายในลูป - คุณได้รับขอบเขตศัพท์ที่คุณต้องการ ไม่มีฟังก์ชั่นที่ไม่ระบุชื่อIIFEหรือคุณสมบัติพิเศษที่ติดอยู่กับวัตถุ
Clint Pachl

ดูข้อดีและข้อเสียของIIFE VS ผูก ()
Clint Pachl

1
โดยการใช้Function.prototype.bind()คุณจะไม่สามารถลบ listener เหตุการณ์ได้ดีกว่าการใช้ฟังก์ชั่น currying แทน (ดู @ tomcek112 คำตอบ)
21919

หมายเหตุ: เป็นตัวแปรที่คุณสามารถส่งผ่านสิ่งที่ค่าที่คุณต้องการsome_other_func some_func
hitastodestruct

28

คุณสามารถผูกอาร์กิวเมนต์ที่จำเป็นทั้งหมดด้วย 'ผูก':

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));

ด้วยวิธีนี้คุณก็จะได้รับevent, arg1และสิ่งอื่น ๆ myPrettyHandlerส่งผ่านไปยัง

http://passy.svbtle.com/partial-application-in-javascript-using-bind


ขอบคุณ! เคยลองแล้ว.bind()แต่ไม่มีค่า null เป็นพารามิเตอร์แรก ซึ่งไม่ได้ผล
Larphoid

ไม่จำเป็นต้องnullทำงานได้ดี.bind(event, arg1)กับ VueJS เป็นอย่างน้อย
DevonDahon

27

คำถามค่อนข้างเก่า แต่ฉันมีปัญหาเดียวกันในวันนี้ วิธีแก้ปัญหาที่สะอาดที่สุดที่ฉันพบคือใช้แนวคิดของแกง

รหัสสำหรับสิ่งนั้น:

someObj.addEventListener('click', some_function(someVar));

var some_function = function(someVar) {
    return function curried_func(e) {
        // do something here
    }
}

โดยการตั้งชื่อฟังก์ชั่น curried จะช่วยให้คุณสามารถเรียก Object.removeEventListener เพื่อยกเลิกการลงทะเบียน eventListener ในเวลาดำเนินการในภายหลัง


4
ดีใจที่ได้พบคำตอบที่กล่าวถึงฟังก์ชั่น curried นี้ คุณจะลบผู้ฟังเหตุการณ์อย่างไร
บ๊อบ

3
ยอดเยี่ยมมากที่เห็นคำศัพท์ที่ดี คุณควรจะสามารถลบ listener เหตุการณ์โดยการตั้งชื่อฟังก์ชั่น curried ฉันจะเสนอการแก้ไข
Matthew Brent

คำตอบนี้จะลงทะเบียนฟังก์ชั่นหลาย ๆ ครั้งตามที่เรียกว่า addEventListener เนื่องจาก some_function (var) จะส่งคืนฟังก์ชันที่สร้างขึ้นใหม่ทุกครั้ง
Yahia

ฉันไม่ชอบความคิดของการตั้งชื่อฟังก์ชั่น curried เพื่อลบ cuz ฟังแล้วคุณจัดการกับ 2 namespaces diff ที่คุณต้องติดตาม
oldboy

19

คุณสามารถเพิ่มและลบ eventlisteners ด้วยข้อโต้แย้งโดยประกาศฟังก์ชั่นเป็นตัวแปร

myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);

newSrc เป็นวิธีการที่มี myaudio เป็นพารามิเตอร์ funcNameเป็นตัวแปรชื่อฟังก์ชั่น

คุณสามารถลบผู้ฟังด้วย myaudio.removeEventListener('ended',func,false);


12

คุณสามารถผ่าน somevar ตามค่า (ไม่ใช่โดยการอ้างอิง) ผ่านคุณสมบัติ javascript ที่รู้จักในชื่อการปิด :

var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',function(someVar){
   return function(){func(someVar)}
}(someVar));
someVar='changed'

หรือคุณสามารถเขียนฟังก์ชัน wrap ทั่วไปเช่นwrapEventCallback:

function wrapEventCallback(callback){
    var args = Array.prototype.slice.call(arguments, 1);
    return function(e){
        callback.apply(this, args)
    }
}
var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',wrapEventCallback(func,someVar))
someVar='changed'

นี่wrapEventCallback(func,var1,var2)คือ:

func.bind(null, var1,var2)

1
ขอบคุณมากสำหรับคำตอบนี้! OP ไม่ได้มองหาสิ่งนี้ แต่ฉันคิดว่าคนที่พิมพ์ "วิธีส่ง args ไปยัง addEventListener" ใน google จะมองหาคำตอบของคุณ มันแค่ต้องการคำอธิบายเพิ่มเติม :) ฉันกำลังแก้ไข
Sindarus

9

someVarค่าควรเข้าถึงได้เฉพาะในsome_function()บริบทไม่ใช่จากผู้ฟัง หากคุณต้องการให้อยู่ภายในผู้ฟังคุณต้องทำสิ่งที่ชอบ:

someObj.addEventListener("click",
                         function(){
                             var newVar = someVar;
                             some_function(someVar);
                         },
                         false);

และใช้newVarแทน

วิธีอื่นคือส่งคืนsomeVarค่าจากsome_function()เพื่อใช้เพิ่มเติมใน listener (เป็น var ภายในเครื่องใหม่):

var someVar = some_function(someVar);

9

นี่เป็นอีกวิธีหนึ่ง (อันนี้ใช้ได้ภายในลูป):

var someVar = some_other_function();
someObj.addEventListener("click", 

function(theVar){
    return function(){some_function(theVar)};
}(someVar),

false);

2
นี่เป็นวิธีที่ดีที่สุด น่าเกลียด แต่มีประสิทธิภาพภายในลูปนับตั้งแต่ส่งอาร์กิวเมนต์ไปยังฟังก์ชันที่ไม่ระบุชื่อจะจับ var
บ๊อบ

9

Function.prototype.bind ()เป็นวิธีการผูกฟังก์ชั่นเป้าหมายกับขอบเขตเฉพาะและเลือกกำหนดthisวัตถุภายในฟังก์ชั่นเป้าหมาย

someObj.addEventListener("click", some_function.bind(this), false);

หรือเพื่อจับภาพขอบเขตศัพท์บางตัวอย่างเช่นในวง:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);

ท้ายที่สุดถ้าthisไม่ต้องการพารามิเตอร์ภายในฟังก์ชันเป้าหมาย:

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);

7

ใช้

   el.addEventListener('click',
    function(){
        // this will give you the id value 
        alert(this.id);    
    },
false);

และถ้าคุณต้องการส่งผ่านค่าที่กำหนดเองใด ๆ ลงในฟังก์ชั่นที่ไม่ระบุชื่อนี้วิธีที่ง่ายที่สุดที่จะทำคือ

 // this will dynamically create property a property
 // you can create anything like el.<your  variable>
 el.myvalue = "hello world";
 el.addEventListener('click',
    function(){
        //this will show you the myvalue 
        alert(el.myvalue);
        // this will give you the id value 
        alert(this.id);    
    },
false);

ทำงานได้อย่างสมบูรณ์แบบในโครงการของฉัน หวังว่าจะช่วยได้


ใช่แน่นอนช่วยเพราะมันยังคงขอบเขตที่คาดไว้ภายในforวง
j4v1

4
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

นี่คือวิธีที่ฉันได้รับเหตุการณ์ผ่านอย่างถูกต้อง


ยอดเยี่ยมนี่คือวิธีที่ฉันเกือบจะสรุป - เพียงแค่ผ่านเหตุการณ์ผิดพลาดเป็นพิเศษเมื่อไม่ได้อยู่ที่นั่น (เหมือนในเชิงมุม) ซึ่งมาในกรณีนี้โดยอัตโนมัติ
Manohar Reddy Poreddy

3

การส่งอาร์กิวเมนต์ไปยังฟังก์ชันการเรียกกลับของ eventListener ต้องสร้างฟังก์ชันแยกและส่งผ่านอาร์กิวเมนต์ไปยังฟังก์ชันที่แยกได้

นี่คือฟังก์ชั่นตัวช่วยเล็ก ๆ ที่คุณสามารถใช้ได้ ตามตัวอย่าง "สวัสดีโลก" ด้านบน)

สิ่งหนึ่งที่จำเป็นต้องมีก็คือการรักษาการอ้างอิงถึงฟังก์ชั่นเพื่อให้เราสามารถลบผู้ฟังได้อย่างหมดจด

// Lambda closure chaos.
//
// Send an anonymous function to the listener, but execute it immediately.
// This will cause the arguments are captured, which is useful when running 
// within loops.
//
// The anonymous function returns a closure, that will be executed when 
// the event triggers. And since the arguments were captured, any vars 
// that were sent in will be unique to the function.

function addListenerWithArgs(elem, evt, func, vars){
    var f = function(ff, vv){
            return (function (){
                ff(vv);
            });
    }(func, vars);

    elem.addEventListener(evt, f);

    return f;
}

// Usage:

function doSomething(withThis){
    console.log("withThis", withThis);
}

// Capture the function so we can remove it later.
var storeFunc = addListenerWithArgs(someElem, "click", doSomething, "foo");

// To remove the listener, use the normal routine:
someElem.removeEventListener("click", storeFunc);

คำตอบนี้มาจาก '15 แต่เป็นสิ่งที่ฉันต้องการเพื่อจัดการกับปัญหานี้ด้วยการใช้ useRef hook หากคุณใช้ตะขออ้างอิงและต้องการผู้ฟังเพื่อให้คุณสามารถล้างข้อมูลในการถอดส่วนประกอบนี่คือมัน หาเรื่องที่ 4 storeFuncควรเป็นตัวแปรอ้างอิงของคุณ นำผู้ฟังของคุณออกไปใช้ประโยชน์ผลเช่นนี้และคุณก็ทำได้ดี:useEffect(() => { return () => { window.removeEventListener('scroll', storeFunc, false); } }, [storeFunc])
Rob B

3

วิธีหนึ่งคือทำสิ่งนี้กับฟังก์ชั่นด้านนอก :

elem.addEventListener('click', (function(numCopy) {
  return function() {
    alert(numCopy)
  };
})(num));

วิธีการห่อฟังก์ชั่นที่ไม่ระบุชื่อในวงเล็บและเรียกมันทันทีเรียกว่าIIFE (นิพจน์ฟังก์ชั่นที่เรียกใช้ทันที)

คุณสามารถตรวจสอบตัวอย่างที่มีสองพารามิเตอร์ในhttp://codepen.io/froucher/pen/BoWwgz

catimg.addEventListener('click', (function(c, i){
  return function() {
    c.meows++;
    i.textContent = c.name + '\'s meows are: ' + c.meows;
  }
})(cat, catmeows));

3

ถ้าฉันไม่เข้าใจผิดว่าใช้การเรียกฟังก์ชันด้วยbindจริง ๆ แล้วสร้างฟังก์ชันใหม่ที่ส่งคืนโดยbindเมธอด สิ่งนี้จะทำให้คุณเกิดปัญหาในภายหลังหรือหากคุณต้องการลบ listener เหตุการณ์เนื่องจากเป็นฟังก์ชันที่ไม่ระบุชื่อ:

// Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', myCallback);
someObject.removeEventListener('event', myCallback);

// Not Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', function() { myCallback });
someObject.removeEventListener('event', /* can't remove anonymous function */);

ดังนั้นจงจำไว้

หากคุณกำลังใช้ ES6 คุณสามารถทำเช่นเดียวกับที่แนะนำ แต่สะอาดกว่า:

someObject.addEventListener('event', () => myCallback(params));

3

ทางเลือกที่ดีหนึ่งบรรทัด

element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {

 //some action...

}

2

ลองใช้สิ่งเหล่านี้ (IE8 + Chrome ฉันไม่รู้ FF):

function addEvent(obj, type, fn) {
    eval('obj.on'+type+'=fn');
}

function removeEvent(obj, type) {
    eval('obj.on'+type+'=null');
}

// Use :

function someFunction (someArg) {alert(someArg);}

var object=document.getElementById('somObject_id') ;
var someArg="Hi there !";
var func=function(){someFunction (someArg)};

// mouseover is inactive
addEvent (object, 'mouseover', func);
// mouseover is now active
addEvent (object, 'mouseover');
// mouseover is inactive

หวังว่าจะไม่มีการพิมพ์ผิด :-)


มันจะยากแค่ไหนที่จะตอบคำถามทั้งหมด? ฉันควรทดสอบสิ่งนี้กับ FF หรือไม่? ดีฉันจะไม่รำคาญ ...
StefanNch

2

ฉันติดอยู่กับสิ่งนี้เพราะฉันใช้มันเป็นวงวนเพื่อค้นหาองค์ประกอบและเพิ่มผู้ฟังเข้าไป หากคุณใช้มันในการวนซ้ำสิ่งนี้จะทำงานได้อย่างสมบูรณ์แบบ

for (var i = 0; i < states_array.length; i++) {
     var link = document.getElementById('apply_'+states_array[i].state_id);
     link.my_id = i;
     link.addEventListener('click', function(e) {   
        alert(e.target.my_id);        
        some_function(states_array[e.target.my_id].css_url);
     });
}

2

ในปี 2019 มีการเปลี่ยนแปลง API จำนวนมากคำตอบที่ดีที่สุดใช้ไม่ได้อีกต่อไปโดยไม่มีการแก้ไขข้อบกพร่อง

แบ่งปันรหัสการทำงานบางอย่าง

แรงบันดาลใจจากคำตอบข้างต้นทั้งหมด

 button_element = document.getElementById('your-button')

 button_element.setAttribute('your-parameter-name',your-parameter-value);

 button_element.addEventListener('click', your_function);


 function your_function(event)
   {
      //when click print the parameter value 
      console.log(event.currentTarget.attributes.your-parameter-name.value;)
   }

1

มีตัวแปรพิเศษภายในการทำงานทั้งหมดคือข้อโต้แย้ง คุณสามารถส่งพารามิเตอร์ของคุณเป็นพารามิเตอร์ที่ไม่ระบุชื่อและเข้าถึงพวกเขา (ตามลำดับ) ผ่านตัวแปรอาร์กิวเมนต์

ตัวอย่าง:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);

อืม ... อะไรคือเหตุผลของการโหวต? หากไม่ใช่สิ่งที่คุณมองหาโปรดอธิบายให้ชัดเจนยิ่งขึ้นว่าคุณหมายถึงอะไร (ฉันรู้ว่าคำถามได้รับคำตอบแล้ว) แต่รหัสของฉันไม่ตอบสิ่งที่คุณถามใช่ไหม "อาร์กิวเมนต์" ตัวแปรพิเศษให้คุณเข้าถึงพารามิเตอร์ทั้งหมดภายในฟังก์ชั่น
StanE

1
    var EV = {
        ev: '',
        fn: '',
        elem: '',
        add: function () {
            this.elem.addEventListener(this.ev, this.fn, false);
        }
    };

    function cons() {
        console.log('some what');
    }

    EV.ev = 'click';
    EV.fn = cons;
    EV.elem = document.getElementById('body');
    EV.add();

//If you want to add one more listener for load event then simply add this two lines of code:

    EV.ev = 'load';
    EV.add();

1

วิธีการต่อไปนี้ใช้ได้ดีสำหรับฉัน ดัดแปลงมาจากที่นี่

function callback(theVar) {
  return function() {
    theVar();
  }
}

function some_other_function() {
  document.body.innerHTML += "made it.";
}

var someVar = some_other_function;
document.getElementById('button').addEventListener('click', callback(someVar));
<!DOCTYPE html>
<html>
  <body>
    <button type="button" id="button">Click Me!</button>
  </body>
</html>


0

คำตอบต่อไปนี้ถูกต้อง แต่รหัสด้านล่างไม่ทำงานใน IE8 ถ้าสมมติว่าคุณบีบอัดไฟล์ js โดยใช้ yuicompressor (ที่จริงแล้วคนส่วนใหญ่ในสหรัฐอเมริกายังใช้ IE8 อยู่)

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click",
                         function(){
                          some_function(someVar);
                         },
                         false);

ดังนั้นเราสามารถแก้ไขปัญหาข้างต้นได้ดังนี้และทำงานได้ดีในเบราว์เซอร์ทั้งหมด

var someVar, eventListnerFunc;
someVar = some_other_function();
eventListnerFunc = some_function(someVar);
someObj.addEventListener("click", eventListnerFunc, false);

หวังว่ามันจะมีประโยชน์สำหรับคนที่กำลังบีบอัดไฟล์ js ในสภาพแวดล้อมการผลิต

โชคดี!!


0

รหัสต่อไปนี้ทำงานได้ดีสำหรับฉัน (firefox):

for (var i=0; i<3; i++) {
   element = new ...   // create your element
   element.counter = i;
   element.addEventListener('click', function(e){
        console.log(this.counter);
        ...            // another code with this element
   }, false);
}

เอาท์พุท:

0
1
2

อะไรในโลกนี้
NiCk Newman


0

อาจไม่ดีที่สุด แต่ก็ง่ายพอสำหรับผู้ที่ไม่เข้าใจ super js ใส่ฟังก์ชั่นที่เรียกใช้ addEventListener ในฟังก์ชั่นของตัวเอง ด้วยวิธีการใด ๆ ค่าฟังก์ชั่นที่ส่งผ่านเข้าไปจะรักษาขอบเขตของตัวเองและคุณสามารถทำซ้ำมากกว่าฟังก์ชั่นที่คุณต้องการ

ตัวอย่างฉันทำงานกับการอ่านไฟล์ตามที่ฉันต้องการในการจับภาพและแสดงตัวอย่างของภาพและชื่อไฟล์ ฉันใช้เวลาสักครู่เพื่อหลีกเลี่ยงปัญหาแบบอะซิงโครนัสเมื่อใช้งานการอัปโหลดไฟล์หลายประเภท ฉันบังเอิญเห็นชื่อ 'เหมือนกัน' บนตัวเรนเดอร์ทั้งหมดแม้จะอัพโหลดไฟล์ต่างกัน

แต่เดิมฟังก์ชั่น readFile () ทั้งหมดอยู่ในฟังก์ชั่น readFiles () สิ่งนี้ทำให้เกิดปัญหาการกำหนดขอบเขตแบบอะซิงโครนัส

    function readFiles(input) {
      if (input.files) {
        for(i=0;i<input.files.length;i++) {

          var filename = input.files[i].name;

          if ( /\.(jpe?g|jpg|png|gif|svg|bmp)$/i.test(filename) ) {
            readFile(input.files[i],filename);
          }
       }
      }
    } //end readFiles



    function readFile(file,filename) {
            var reader = new FileReader();

            reader.addEventListener("load", function() { alert(filename);}, false);

            reader.readAsDataURL(file);

    } //end readFile

0

แค่อยากจะเพิ่ม หากมีใครกำลังเพิ่มฟังก์ชั่นที่อัปเดตช่องทำเครื่องหมายให้กับผู้ฟังเหตุการณ์คุณจะต้องใช้event.targetแทนthisการปรับปรุงช่องทำเครื่องหมาย


0

ฉันมีวิธีการที่ง่ายมาก สิ่งนี้อาจใช้ได้กับคนอื่นในขณะที่มันช่วยฉัน มันคือ ... เมื่อคุณมีหลายองค์ประกอบ / ตัวแปรที่กำหนดฟังก์ชั่นเดียวกันและคุณต้องการที่จะผ่านการอ้างอิงทางออกที่ง่ายที่สุดคือ ...

function Name()
{

this.methodName = "Value"

}

แค่นั้นแหละ. มันใช้งานได้สำหรับฉัน ง่ายมาก


-1

ทางเลือกอื่น ๆ อาจไม่สวยงามเท่าการใช้งานการผูก แต่ใช้ได้กับเหตุการณ์ในลูป

for (var key in catalog){
    document.getElementById(key).my_id = key
    document.getElementById(key).addEventListener('click', function(e) {
        editorContent.loadCatalogEntry(e.srcElement.my_id)
    }, false);
}

ได้รับการทดสอบสำหรับส่วนขยายของ Google Chrome และอาจต้องเปลี่ยน e.srcElement โดย e.source ในเบราว์เซอร์อื่น

ฉันพบโซลูชันนี้โดยใช้ความคิดเห็นที่โพสต์โดยImatoriaแต่ฉันไม่สามารถทำเครื่องหมายว่ามีประโยชน์เพราะฉันมีชื่อเสียงไม่เพียงพอ: D


-1

วิธีนี้อาจดูดี

var some_other_function = someVar => function() {
}

someObj.addEventListener('click', some_other_function(someVar));

หรือผูกของมีค่าก็จะดีเช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.