Sử dụng nút HTML để gọi hàm JavaScript


229

Tôi đang cố gắng sử dụng nút HTML để gọi hàm JavaScript.

Đây là mã:

<input type="button" value="Capacity Chart" onclick="CapacityChart();">

Nó dường như không hoạt động chính xác mặc dù. Có cách nào tốt hơn để làm điều này?

Đây là liên kết: http://projectpath.ideapeoplesite.com/bendel/toolscalculators.html nhấp vào tab dung lượng ở phần dưới cùng bên trái. Nút sẽ tạo cảnh báo nếu các giá trị không thay đổi và sẽ tạo biểu đồ nếu bạn nhập giá trị.


6
vui lòng xác định "dường như không hoạt động chính xác". bạn gặp phải lỗi gì khi nhấp vào nó?
chỉ là ai đó

Nút này hoạt động trong IE8, nhưng không phải FF 3.5 do lỗi JavaScript (xem câu trả lời của Jeff)
Chris Shouts

1
Vâng, hóa ra document.all là một thứ IE không chuẩn; cập nhật câu trả lời của tôi với một sự thay thế được đề xuất.
Jeff

@ paper1337, @Jeff: Hàm vẫn không đạt được hiệu quả mong muốn trong IE8, do đó, ngay cả việc hoán đổi tài liệu.all cho document.getEuityById sẽ không sửa nó.
Andy E

Câu trả lời:


356

Có một số cách để xử lý các sự kiện với HTML / DOM. Không có cách nào đúng hay sai nhưng cách khác nhau rất hữu ích trong các tình huống khác nhau.

1: Có định nghĩa nó trong HTML:

<input id="clickMe" type="button" value="clickme" onclick="doFunction();" />

2: Có thêm nó vào thuộc tính DOM cho sự kiện trong Javascript:

//- Using a function pointer:
document.getElementById("clickMe").onclick = doFunction;

//- Using an anonymous function:
document.getElementById("clickMe").onclick = function () { alert('hello!'); };

3: Và có đính kèm một chức năng cho trình xử lý sự kiện bằng Javascript:

var el = document.getElementById("clickMe");
if (el.addEventListener)
    el.addEventListener("click", doFunction, false);
else if (el.attachEvent)
    el.attachEvent('onclick', doFunction);

Cả hai phương thức thứ hai và thứ ba đều cho phép các hàm nội tuyến / ẩn danh và cả hai phải được khai báo sau khi phần tử được phân tích cú pháp từ tài liệu. Phương thức đầu tiên không hợp lệ XHTML vì thuộc tính onclick không có trong đặc tả XHTML.

Các phương thức 1 và 2 là loại trừ lẫn nhau, nghĩa là sử dụng một (thứ 2) sẽ ghi đè lên phương thức kia (thứ 1). Phương thức thứ 3 sẽ cho phép bạn đính kèm bao nhiêu chức năng tùy thích vào cùng một trình xử lý sự kiện, ngay cả khi phương thức 1 hoặc 2 cũng đã được sử dụng.

Nhiều khả năng, vấn đề nằm ở đâu đó trong CapacityChart()chức năng của bạn . Sau khi truy cập liên kết của bạn và chạy tập lệnh của bạn, hàm ProfitChart () sẽ chạy và hai cửa sổ bật lên được mở (một được đóng theo kịch bản). Nơi bạn có dòng sau:

CapacityWindow.document.write(s);

Thay vào đó, hãy thử các cách sau:

CapacityWindow.document.open("text/html");
CapacityWindow.document.write(s);
CapacityWindow.document.close();

EDIT
Khi tôi thấy mã của bạn, tôi nghĩ rằng bạn đang viết nó đặc biệt cho IE. Như những người khác đã đề cập, bạn sẽ cần phải thay thế các tài liệu tham khảo document.allvới document.getElementById. Tuy nhiên, bạn vẫn sẽ có nhiệm vụ sửa tập lệnh sau đó, vì vậy tôi khuyên bạn nên làm cho nó hoạt động trong ít nhất IE vì bất kỳ lỗi nào bạn thực hiện khi thay đổi mã để làm việc trên trình duyệt chéo có thể gây ra nhiều nhầm lẫn hơn. Khi nó hoạt động trong IE, sẽ dễ dàng hơn nếu nó hoạt động trong các trình duyệt khác trong khi bạn đang cập nhật mã.


6
Sử dụng jquery, cũng có: $("#clickMe").bind('click', function () { alert('hello!'); };)
La Mã

32

Tôi sẽ nói rằng sẽ tốt hơn nếu thêm javascript theo cách không gây khó chịu ...

nếu sử dụng jQuery, bạn có thể làm một cái gì đó như:

<script>
  $(document).ready(function(){
    $('#MyButton').click(function(){
       CapacityChart();
    });
  });
</script>

<input type="button" value="Capacity Chart" id="MyButton" >

4
Đã đồng ý. Trong nhiều trường hợp, jQuery và các khung công tác khác quá mức cần thiết cho một lượng nhỏ javascript và không phải tất cả các mã javascript đều phải là trình duyệt chéo.
Andy E

2
Đủ công bằng .. điểm mà tôi đang cố gắng thực hiện là "một cách tốt hơn để làm điều này" là không phô trương ... Không có jQuery, một cái gì đó như: var btn = document.getEuityById ('MyButton'); btn.onclick = function () {Dung lượngChart ();}
Paul

1
Những người này sử dụng jQuery dường như được thiết lập để sử dụng nó cho mọi thứ trên web. Làm thế nào về việc sử dụng JavaScript phẳng cho một? Trời ơi, jQuery thực sự đang làm tôi lo lắng. CƯỜI LỚN! Ill gọi đó là cách lười biếng của người tạo web, vì tôi đoán đó là tất cả những gì nó thực sự là.
DoctorLouie

@DrLouie: Tôi không có gì chống lại jQuery, đó là một giải pháp tốt cho nhiều vấn đề, nhưng khi OP không được gắn thẻ hoặc yêu cầu, bất kỳ đề cập nào về jQuery cũng nên được hỗ trợ bởi một phương thức không phải là jQuery, nếu không, chúng sẽ gặp rủi ro của a) gây nhầm lẫn cho người hỏi - anh ta có thể không biết jQuery là gì hoặc b) làm phiền người hỏi bằng cách bảo anh ta sử dụng jQuery cho một vài dòng mã javascript. @Paul - Tôi phải nói rằng đó không phải là một bài đọc tuyệt vời ...
Andy E

1
xin lỗi ... liên kết sai được đăng - có nghĩa là để đăng một stackoverflow. stackoverflow.com/questions/1588374/ cấp
Paul

8

HTML của bạn và cách bạn gọi hàm từ nút trông chính xác.

Vấn đề dường như là trong CapacityCountchức năng. Tôi đang gặp lỗi này trong bảng điều khiển của mình trên Firefox 3.5: "document.all không xác định" trên dòng 759 của bentelcorp.js.

Biên tập:

Có vẻ như document.alllà một thứ chỉ dành cho IE và là cách truy cập DOM không chuẩn. Nếu bạn sử dụng document.getElementById(), nó có thể nên làm việc. Ví dụ: document.getElementById("RUnits").valuethay vìdocument.all.Capacity.RUnits.value


Đó không phải là vấn đề cụ thể với chức năng, không gây ra bất kỳ lỗi nào trong IE
Andy E

4

Điều này có vẻ đúng. Tôi đoán bạn đã xác định chức năng của mình bằng một tên khác hoặc trong ngữ cảnh không hiển thị với nút. Vui lòng thêm một số mã


3

Chỉ để bạn biết, dấu chấm phẩy ( ; ) không được phép có trong nút khi bạn gọi hàm.

Vì vậy, nó sẽ trông giống như thế này: onclick="CapacityChart()"

sau đó tất cả sẽ hoạt động :)


2

Một vấn đề lớn mà bạn gặp phải là bạn đang sử dụng trình duyệt đánh hơi mà không có lý do chính đáng:

if(navigator.appName == 'Netscape')
    {
      vesdiameter  = document.forms['Volume'].elements['VesDiameter'].value;
      // more stuff snipped
    }
    else
    {
      vesdiameter  = eval(document.all.Volume.VesDiameter.value);
      // more stuff snipped
    }

Tôi đang sử dụng Chrome, vì vậy navigator.appNamesẽ không có Netscape. Chrome có hỗ trợ document.allkhông? Có thể, nhưng sau đó lại có thể không. Còn những trình duyệt khác thì sao?

Phiên bản mã trên Netscapenhánh sẽ hoạt động trên bất kỳ trình duyệt nào ngay từ khi quay lại Netscape Navigator 2 từ năm 1996, vì vậy bạn có thể chỉ nên sử dụng nó ... ngoại trừ việc nó không hoạt động (hoặc không được bảo đảm để hoạt động ) bởi vì bạn chưa chỉ định một namethuộc tính trên các inputthành phần, vì vậy chúng sẽ không được thêm vào elementsmảng của biểu mẫu dưới dạng các thành phần được đặt tên:

<input type="text" id="VesDiameter" value="0" size="10" onKeyUp="CalcVolume();">

Hoặc đặt tên cho chúng và sử dụng elementsmảng hoặc sử dụng (tốt hơn)

var vesdiameter = document.getElementById("VesDiameter").value;

sẽ hoạt động trên tất cả các trình duyệt hiện đại - không cần phân nhánh. Để đảm bảo an toàn, hãy thay thế việc đánh hơi cho phiên bản trình duyệt lớn hơn hoặc bằng 4 bằng kiểm tra getElementByIdhỗ trợ:

if (document.getElementById) { // NB: no brackets; we're testing for existence of the method, not executing it
    // do stuff...
}

Bạn có thể muốn xác nhận đầu vào của bạn là tốt; cái gì đó như

var vesdiameter = parseFloat(document.getElementById("VesDiameter").value);
if (isNaN(vesdiameter)) {
    alert("Diameter should be numeric");
    return;
}

sẽ giúp.


Xin chào NickFitz, một trong những thách thức của tôi ở đây là kịch bản này ban đầu được viết vào năm 1993 - do đó, các tham chiếu đến Netscape 4. Tôi đã có một số trợ giúp để cập nhật và nó hoạt động cho đến khi tôi đưa nó vào trang chỉ định của nó.
forrest

Tôi nghi ngờ nó đã được viết vào năm 1993, vì Brendan Eich đã không phát minh ra JS cho đến năm 1995 en.wikipedia.org/wiki/Javascript#History ;-) Tôi rất khuyến khích sử dụng document.getElementByIdvà tước bỏ những thứ khác.
NickFitz

Tôi nghĩ rằng ít nhất nên thận trọng để nó hoạt động trong IE trước khi làm việc với khả năng tương thích trình duyệt, nếu không anh ta sẽ không biết liệu các vấn đề tương thích trình duyệt của mình sẽ được khắc phục hay không vì nó vẫn không hoạt động.
Andy E

Tốt hơn là làm cho nó hoạt động bằng các kỹ thuật DOM tiêu chuẩn, sau đó sẽ không có bất kỳ vấn đề tương thích trình duyệt nào được nói đến :-)
NickFitz

2

Mã của bạn không thành công trên dòng này:

var RUnits = Math.abs(document.all.Capacity.RUnits.value);

tôi đã cố gắng bước qua nó với con bọ lửa và nó thất bại ở đó. Điều đó sẽ giúp bạn tìm ra vấn đề.

bạn có tham khảo jquery. bạn cũng có thể sử dụng nó trong tất cả các chức năng này. nó sẽ dọn sạch mã của bạn một cách đáng kể.


Nó không thất bại trong IE trên dòng đó, mặc dù.
Andy E

bởi vì document.all là một thứ IE. anh ta chỉ nên sử dụng ký hiệu jquery $ ('# RUint'). val () anh ta đã bao gồm cả jquery. điều này quan tâm đến bất kỳ sự khác biệt lông mày và làm sạch mã.
Patricia

2

Tôi có một mã nút gọi lại chức năng thông minh:

<br>
<p id="demo"></p><h2>Intelligent Button:</h2><i>Note: Try pressing a key after clicking.</i><br>
<button id="button" shiftKey="getElementById('button').innerHTML=('You're pressing shift, aren't you?')" onscroll="getElementById('button').innerHTML=('Don't Leave me!')" onkeydown="getElementById('button').innerHTML=('Why are you pressing keys?')" onmouseout="getElementById('button').innerHTML=('Whatever, it is gone.. maybe')" onmouseover="getElementById('button').innerHTML=('Something Is Hovering Over Me.. again')" onclick="getElementById('button').innerHTML=('I was clicked, I think')">Ahhhh</button>

1

TRẢ LỜI ĐƠN GIẢN:

   onclick="functionName(ID.value);

Trong đó ID là ID của trường đầu vào.


-2

cách ngu ngốc:

onclick="javascript:CapacityChart();"

Bạn nên đọc về javascript rời rạc và sử dụng phương thức liên kết khung để liên kết các cuộc gọi lại với các sự kiện dom.


@erenon: Thôi nào. Đây không phải là vấn đề của anh ấy, ký hiệu là hoàn toàn tốt, và không có lý do gì để đi vào các ràng buộc và khuôn khổ phức tạp chỉ vì mục đích gán một sự kiện onclick.
Pekka

Cảm ơn bạn đã đến với phòng thủ của tôi. Tôi chỉ muốn một nút đơn giản để hoạt động chính xác.
forrest

3
Các javascript:giao thức không cần thiết trong onclicksự kiện. Sự kiện onclick đã là javascript. Các javascript:giao thức là để thực hiện javascript trong thuộc tính href của một liên kết.
Web_Designer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.